add builds per day
This commit is contained in:
parent
859230bd07
commit
ddb4593b50
|
@ -12,8 +12,15 @@
|
||||||
<input id="repo-name" type="text" value="wp-cli/wp-cli" />
|
<input id="repo-name" type="text" value="wp-cli/wp-cli" />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
<h2>Build durations over time</h2>
|
<h2>Build durations over time</h2>
|
||||||
<div id="build-times"></div>
|
<div id="build-times"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
|
<h2>Builds per day</h2>
|
||||||
|
<div id="build-counts"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="http://d3js.org/d3.v2.min.js"></script>
|
<script src="http://d3js.org/d3.v2.min.js"></script>
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
|
|
97
script.js
97
script.js
|
@ -1,4 +1,76 @@
|
||||||
function renderBuildTimes(selector, data, baseUrl) {
|
function renderBuildCounts(container, data) {
|
||||||
|
var valueLabelWidth = 40; // space reserved for value labels (right)
|
||||||
|
var barHeight = 20; // height of one bar
|
||||||
|
var barLabelWidth = 130; // space reserved for bar labels
|
||||||
|
var barLabelPadding = 5; // padding between bar and bar labels (left)
|
||||||
|
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
|
||||||
|
|
||||||
|
// accessor functions
|
||||||
|
var barValue = function(d) { return d.value; };
|
||||||
|
|
||||||
|
// 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 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);
|
||||||
|
// grid line labels
|
||||||
|
var gridContainer = chart.append('g')
|
||||||
|
.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);
|
||||||
|
// 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('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) + ')');
|
||||||
|
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');
|
||||||
|
// 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBuildTimes(container, data, baseUrl) {
|
||||||
var valueLabelWidth = 40; // space reserved for value labels (right)
|
var valueLabelWidth = 40; // space reserved for value labels (right)
|
||||||
var barHeight = 20; // height of one bar
|
var barHeight = 20; // height of one bar
|
||||||
var barLabelWidth = 50; // space reserved for bar labels
|
var barLabelWidth = 50; // space reserved for bar labels
|
||||||
|
@ -17,7 +89,7 @@ function renderBuildTimes(selector, data, baseUrl) {
|
||||||
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
|
// svg container element
|
||||||
var chart = d3.select().html('').append("svg")
|
var chart = d3.select().html('').append("svg")
|
||||||
var chart = d3.select(selector).html('').append("svg")
|
var chart = d3.select(container).html('').append("svg")
|
||||||
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
|
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
|
||||||
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
|
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
|
||||||
// grid line labels
|
// grid line labels
|
||||||
|
@ -76,6 +148,11 @@ function renderBuildTimes(selector, data, baseUrl) {
|
||||||
.style("stroke", "#000");
|
.style("stroke", "#000");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBuildDate(build) {
|
||||||
|
var dt = new Date(Date.parse(build.started_at));
|
||||||
|
return dt.toDateString();
|
||||||
|
}
|
||||||
|
|
||||||
function updateChart() {
|
function updateChart() {
|
||||||
var repoName = document.getElementById('repo-name').value;
|
var repoName = document.getElementById('repo-name').value;
|
||||||
var baseUrl = 'https://travis-ci.org/' + repoName + '/builds/';
|
var baseUrl = 'https://travis-ci.org/' + repoName + '/builds/';
|
||||||
|
@ -87,6 +164,18 @@ function updateChart() {
|
||||||
var oldestBuild = Infinity;
|
var oldestBuild = Infinity;
|
||||||
var i=0, n=15;
|
var i=0, n=15;
|
||||||
|
|
||||||
|
var buildCounts = {};
|
||||||
|
|
||||||
|
function updateCount(build) {
|
||||||
|
var buildDate = getBuildDate(build);
|
||||||
|
|
||||||
|
if (!buildCounts[buildDate]) {
|
||||||
|
buildCounts[buildDate] = 1;
|
||||||
|
} else {
|
||||||
|
buildCounts[buildDate] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function filterBuilds(rawBuilds) {
|
function filterBuilds(rawBuilds) {
|
||||||
var curOldestBuild = oldestBuild;
|
var curOldestBuild = oldestBuild;
|
||||||
|
|
||||||
|
@ -100,12 +189,12 @@ function updateChart() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
build.started_at = Date.parse(build.started_at);
|
updateCount(build);
|
||||||
|
|
||||||
builds.push(build);
|
builds.push(build);
|
||||||
});
|
});
|
||||||
|
|
||||||
renderBuildTimes('#build-times', builds, baseUrl);
|
renderBuildTimes('#build-times', builds, baseUrl);
|
||||||
|
renderBuildCounts('#build-counts', d3.entries(buildCounts), baseUrl);
|
||||||
|
|
||||||
if (++i < n && curOldestBuild < oldestBuild) {
|
if (++i < n && curOldestBuild < oldestBuild) {
|
||||||
oldestBuild = curOldestBuild;
|
oldestBuild = curOldestBuild;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user