diff --git a/script.js b/script.js index 2da1326..69377a5 100644 --- a/script.js +++ b/script.js @@ -15,137 +15,125 @@ function renderBuildCounts(container, data) { var y = function(d, i) { return yScale(i); }; var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; }; var x = d3.scale.linear().domain([0, d3.max(data, barValue)]).range([0, maxBarWidth]); + // svg container element - var chart = d3.select().html('').append("svg") var chart = d3.select(container).html('').append("svg") - .attr('width', maxBarWidth + barLabelWidth + valueLabelWidth) - .attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight); + .attr('width', maxBarWidth + barLabelWidth + valueLabelWidth) + .attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight); + // grid line labels var gridContainer = chart.append('g') - .attr('transform', 'translate(' + barLabelWidth + ',' + gridLabelHeight + ')'); + .attr('transform', 'translate(' + barLabelWidth + ',' + gridLabelHeight + ')'); gridContainer.selectAll("text").data(x.ticks(10)).enter().append("text") - .attr("x", x) - .attr("dy", -3) - .attr("text-anchor", "middle") - .text(String); + .attr("x", x) + .attr("dy", -3) + .attr("text-anchor", "middle") + .text(String); + // vertical grid lines gridContainer.selectAll("line").data(x.ticks(10)).enter().append("line") - .attr("x1", x) - .attr("x2", x) - .attr("y1", 0) - .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) - .style("stroke", "#ccc"); + .attr("x1", x) + .attr("x2", x) + .attr("y1", 0) + .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) + .style("stroke", "#ccc"); + // bar labels var labelsContainer = chart.append('g') - .attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')'); - labelsContainer.selectAll('text').data(data).enter().append('text') - .attr('y', yText) - .attr("dy", ".35em") // vertical-align: middle - .attr('text-anchor', 'end') - .text(function(d) { return d.key; }); + .attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')'); + labelsContainer.selectAll('text').data(data).enter().append('text') + .attr('y', yText) + .attr("dy", ".35em") // vertical-align: middle + .attr('text-anchor', 'end') + .text(function(d) { return d.key; }); // bars var barsContainer = chart.append('g') - .attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')'); + .attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')'); barsContainer.selectAll("rect").data(data).enter().append("rect") - .attr('y', y) - .attr('height', yScale.rangeBand()) - .attr('width', function(d) { return x(barValue(d)); }) - .attr('stroke', 'white') - .attr('fill', 'steelblue'); + .attr('y', y) + .attr('height', yScale.rangeBand()) + .attr('width', function(d) { return x(barValue(d)); }) + .attr('stroke', 'white') + .attr('fill', 'steelblue'); + // bar value labels barsContainer.selectAll("text").data(data).enter().append("text") - .attr("x", function(d) { return x(barValue(d)); }) - .attr("y", yText) - .attr("dx", 3) // padding-left - .attr("dy", ".35em") // vertical-align: middle - .attr("text-anchor", "start") // text-align: right - .attr("fill", "black") - .attr("stroke", "none") - .text(function(d) { return d3.round(barValue(d), 2); }); + .attr("x", function(d) { return x(barValue(d)); }) + .attr("y", yText) + .attr("dx", 3) // padding-left + .attr("dy", ".35em") // vertical-align: middle + .attr("text-anchor", "start") // text-align: right + .attr("fill", "black") + .attr("stroke", "none") + .text(function(d) { return d3.round(barValue(d), 2); }); + // start line barsContainer.append("line") - .attr("y1", -gridChartOffset) - .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) - .style("stroke", "#000"); + .attr("y1", -gridChartOffset) + .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) + .style("stroke", "#000"); } function renderBuildTimes(container, data, baseUrl) { - var valueLabelWidth = 40; // space reserved for value labels (right) - var barHeight = 20; // height of one bar - var barLabelWidth = 50; // space reserved for bar labels - var barLabelPadding = 5; // padding between bar and bar labels (left) + var paddingLeft = 5; // space to the left of the bars + var paddingRight = 10; // space to the right of the bars + var barHeight = 5; // height of one bar + var barPaddingV = 1; // vertical padding between bars var gridLabelHeight = 18; // space reserved for gridline labels var gridChartOffset = 3; // space between start of grid and first bar - var maxBarWidth = 420; // width of the bar with the max value + var maxBarWidth = 450; // width of the bar with the max value // accessor functions var barValue = function(d) { return d.duration/60; }; // scales - var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]); - var y = function(d, i) { return yScale(i); }; + var yScale = d3.scale.ordinal() + .domain(d3.range(0, data.length)) + .rangeBands([0, data.length * (barHeight+barPaddingV)]); + var y = function(d, i) { return yScale(i) + barPaddingV*i; }; var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; }; - var x = d3.scale.linear().domain([0, d3.max(data, barValue)]).range([0, maxBarWidth]); + var x = d3.scale.linear() + .domain([0, d3.max(data, barValue)]) + .range([0, maxBarWidth]); + // svg container element - var chart = d3.select().html('').append("svg") var chart = d3.select(container).html('').append("svg") - .attr('width', maxBarWidth + barLabelWidth + valueLabelWidth) - .attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight); + .attr('width', maxBarWidth + paddingLeft + paddingRight) + .attr('height', gridLabelHeight + gridChartOffset + data.length * (barHeight+barPaddingV*2)); + // grid line labels var gridContainer = chart.append('g') - .attr('transform', 'translate(' + barLabelWidth + ',' + gridLabelHeight + ')'); + .attr('transform', 'translate(' + paddingLeft + ',' + gridLabelHeight + ')'); gridContainer.selectAll("text").data(x.ticks(10)).enter().append("text") - .attr("x", x) - .attr("dy", -3) - .attr("text-anchor", "middle") - .text(String); + .attr("x", x) + .attr("dy", -3) + .attr("text-anchor", "middle") + .text(String); + // vertical grid lines gridContainer.selectAll("line").data(x.ticks(10)).enter().append("line") - .attr("x1", x) - .attr("x2", x) - .attr("y1", 0) - .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) - .style("stroke", "#ccc"); - // bar labels - var labelsContainer = chart.append('g') - .attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')'); - labelsContainer.selectAll('text').data(data).enter().append('text') - .attr('class', 'build-nr') - .attr('y', yText) - .attr("dy", ".35em") // vertical-align: middle - .attr('text-anchor', 'end') - .text(function(d) { return d.number; }) - .on('click', function(d) { - window.open(baseUrl + d.id); - }); + .attr("x1", x) + .attr("x2", x) + .attr("y1", 0) + .attr("y2", yScale.rangeExtent()[1] + gridChartOffset + barPaddingV*data.length) + .style("stroke", "#ccc"); // bars var barsContainer = chart.append('g') - .attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')'); + .attr('transform', 'translate(' + paddingLeft + ',' + (gridLabelHeight + gridChartOffset) + ')'); barsContainer.selectAll("rect").data(data).enter().append("rect") - .attr('y', y) - .attr('height', yScale.rangeBand()) - .attr('width', function(d) { return x(barValue(d)); }) - .attr('stroke', 'white') - .attr('fill', function(d) { - return d.result === 0 ? '#038035' : '#CC0000'; - }); - // bar value labels - barsContainer.selectAll("text").data(data).enter().append("text") - .attr("x", function(d) { return x(barValue(d)); }) - .attr("y", yText) - .attr("dx", 3) // padding-left - .attr("dy", ".35em") // vertical-align: middle - .attr("text-anchor", "start") // text-align: right - .attr("fill", "black") - .attr("stroke", "none") - .text(function(d) { return d3.round(barValue(d), 2); }); - // start line - barsContainer.append("line") - .attr("y1", -gridChartOffset) - .attr("y2", yScale.rangeExtent()[1] + gridChartOffset) - .style("stroke", "#000"); + .attr('y', y) + .attr('height', yScale.rangeBand()) + .attr('width', function(d) { return x(barValue(d)); }) + .attr('stroke', 'white') + .attr('class', 'build-time-bar') + .attr('fill', function(d) { + return d.result === 0 ? '#038035' : '#CC0000'; + }) + .on('click', function(d) { + window.open(baseUrl + d.id); + }); } function getBuildDate(build) { @@ -162,7 +150,7 @@ function updateChart() { var builds = []; var oldestBuild = Infinity; - var i=0, n=15; + var i=0, n=20; var buildCounts = {}; diff --git a/style.css b/style.css index db1de4b..4b11322 100644 --- a/style.css +++ b/style.css @@ -38,14 +38,11 @@ form { .column { width: 49%; + min-width: 590px; float: left; } -.build-nr { - fill: blue; -} - -.build-nr:hover { +.build-time-bar:hover { cursor: pointer; - text-decoration: underline; + stroke: gray; }