Skip to content

Commit af72a5f

Browse files
mattipclaude
andcommitted
Draw version boundary lines on timeline when suite_version changes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e22558f commit af72a5f

1 file changed

Lines changed: 47 additions & 6 deletions

File tree

codespeed/static/js/timeline.js

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,14 @@ function buildGraphData(branches, median, equidistant) {
8484
var mid = pt[1];
8585
var low, high, commit, tag;
8686

87+
var suite_version;
8788
if (median) {
88-
// pt: [date, median, max, q3, q1, min, commit, tag, branch]
89+
// pt: [date, median, max, q3, q1, min, commit, tag, branch, suite_version]
8990
var q1 = (pt[4] !== "") ? pt[4] : mid;
9091
var q3 = (pt[3] !== "") ? pt[3] : mid;
9192
var min = (pt[5] !== "") ? pt[5] : mid;
9293
var max = (pt[2] !== "") ? pt[2] : mid;
93-
commit = pt[6]; tag = pt[7];
94+
commit = pt[6]; tag = pt[7]; suite_version = pt[9] || '';
9495
if (shouldPlotExtrema()) {
9596
low = min; high = max;
9697
} else if (shouldPlotQuartiles()) {
@@ -99,16 +100,17 @@ function buildGraphData(branches, median, equidistant) {
99100
low = mid; high = mid;
100101
}
101102
} else {
102-
// pt: [date, value, std_dev, commit, tag, branch]
103+
// pt: [date, value, std_dev, commit, tag, branch, suite_version]
103104
var std = (pt[2] !== "" && pt[2] !== null) ? pt[2] : 0;
104105
low = Math.max(0, mid - std);
105106
high = mid + std;
106-
commit = pt[3]; tag = pt[4];
107+
commit = pt[3]; tag = pt[4]; suite_version = pt[6] || '';
107108
}
108109

109110
dateIndex[dateKey] = new Date(dateKey.trim());
110111
seriesRaw[exe_id][dateKey] = {low: low, mid: mid, high: high,
111112
commit: commit, tag: tag,
113+
suite_version: suite_version,
112114
dateKey: dateKey};
113115
}
114116
}
@@ -136,7 +138,8 @@ function buildGraphData(branches, median, equidistant) {
136138
if (seriesRaw[id][dk]) {
137139
var pt = seriesRaw[id][dk];
138140
commitMap[dk][id] = {commit: pt.commit, tag: pt.tag,
139-
low: pt.low, high: pt.high};
141+
low: pt.low, high: pt.high,
142+
suite_version: pt.suite_version};
140143
}
141144
});
142145
});
@@ -153,7 +156,7 @@ function buildGraphData(branches, median, equidistant) {
153156

154157
return {labels: labels, colors: colors, data: graphData,
155158
commitMap: commitMap, sortedDateKeys: sortedDateKeys,
156-
seriesIds: seriesIds, tsMap: tsMap};
159+
seriesIds: seriesIds, tsMap: tsMap, dateIndex: dateIndex};
157160
}
158161

159162
function renderPlot(data) {
@@ -192,8 +195,26 @@ function renderPlot(data) {
192195
var sortedDateKeys = built.sortedDateKeys;
193196
var seriesIds = built.seriesIds;
194197
var tsMap = built.tsMap;
198+
var dateIndex = built.dateIndex;
195199
var env = $("input[name='environments']:checked").val();
196200

201+
// Find x-positions where suite_version changes between adjacent points
202+
var seen = {};
203+
var versionBoundaries = [];
204+
sortedDateKeys.forEach(function(dk, idx) {
205+
if (idx === 0) { return; }
206+
var prevDk = sortedDateKeys[idx - 1];
207+
seriesIds.forEach(function(id) {
208+
var curr = commitMap[dk] && commitMap[dk][id];
209+
var prev = commitMap[prevDk] && commitMap[prevDk][id];
210+
if (curr && prev && curr.suite_version && prev.suite_version &&
211+
curr.suite_version !== prev.suite_version && !seen[dk]) {
212+
seen[dk] = true;
213+
versionBoundaries.push({dk: dk, idx: idx, label: curr.suite_version});
214+
}
215+
});
216+
});
217+
197218
// Map label -> color and label -> exeId for tooltip
198219
var colorMap = {};
199220
var labelToExeId = {};
@@ -236,6 +257,7 @@ function renderPlot(data) {
236257
html += '<br><span style="font-size:0.85em;font-weight:normal;color:#666">' +
237258
'commit: ' + info.commit;
238259
if (info.tag) { html += '&nbsp;&nbsp;tag: ' + info.tag; }
260+
if (versionBoundaries.length > 0 && info.suite_version) { html += '&nbsp;&nbsp;suite: ' + info.suite_version; }
239261
html += '</span>';
240262
}
241263
html += '</div>';
@@ -285,6 +307,25 @@ function renderPlot(data) {
285307
y: { valueRange: [0, null] }
286308
},
287309
connectSeparatedPoints: true,
310+
underlayCallback: function(canvas, area, g) {
311+
versionBoundaries.forEach(function(b) {
312+
var xval = equidistant ? b.idx : dateIndex[b.dk];
313+
var cx = g.toDomXCoord(xval);
314+
canvas.save();
315+
canvas.beginPath();
316+
canvas.moveTo(cx, area.y);
317+
canvas.lineTo(cx, area.y + area.h);
318+
canvas.strokeStyle = 'rgba(120, 120, 120, 0.6)';
319+
canvas.lineWidth = 1.5;
320+
canvas.setLineDash([4, 3]);
321+
canvas.stroke();
322+
canvas.setLineDash([]);
323+
canvas.fillStyle = 'rgba(80, 80, 80, 0.75)';
324+
canvas.font = '10px sans-serif';
325+
canvas.fillText(b.label, cx + 3, area.y + 12);
326+
canvas.restore();
327+
});
328+
},
288329
highlightSeriesOpts: { strokeWidth: 3 },
289330
highlightCircleSize: 5,
290331
highlightCallback: function(e, x, points) {

0 commit comments

Comments
 (0)