summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNinette Adhikari <ninette.adhikari@gmail.com>2025-01-27 14:20:08 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-02-09 22:23:30 +0000
commit9f3127060027a24995c3c361cbda964d2c59d039 (patch)
treec39492feaecddedf2e777b381bf3b205d44e3c5c
parente0a7a6eb096d94010d159456d8a6e86b36ec7a6a (diff)
downloadpoky-9f3127060027a24995c3c361cbda964d2c59d039.tar.gz
scripts/buildperf: Add chart tabs for commit count/time
We triggered a test of an older revision to narrow down when performance changed. The issue is that git's timestamps are granular to 1s. We'll usually merge a set of commits at the same time so they will all have the same timestamp for a block of them. This means that even if we use the commit date, all the points can't be distinguished on the graph. The author date doesn't work either as the commits are not merged in author date order. To solve this this patch adds the commit_count chart as a separate tab next to the start_time chart (From OE-Core rev: b263edd33f6c895238d81ef148c0445fcd0aa268) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--scripts/lib/build_perf/html/measurement_chart.html108
-rw-r--r--scripts/lib/build_perf/html/report.html71
2 files changed, 156 insertions, 23 deletions
diff --git a/scripts/lib/build_perf/html/measurement_chart.html b/scripts/lib/build_perf/html/measurement_chart.html
index 05bd84e6ce..3cd713a2ee 100644
--- a/scripts/lib/build_perf/html/measurement_chart.html
+++ b/scripts/lib/build_perf/html/measurement_chart.html
@@ -26,26 +26,36 @@
26 ] 26 ]
27 }); 27 });
28 28
29 const commitCountList = rawData.map(([commit, value, time]) => {
30 return commit
31 });
32
33 const commitCountData = rawData.map(([commit, value, time]) => {
34 return updateValue(value)
35 });
36
29 // Set chart options 37 // Set chart options
30 const option = { 38 const option_start_time = {
31 tooltip: { 39 tooltip: {
32 trigger: 'axis', 40 trigger: 'axis',
33 enterable: true, 41 enterable: true,
34 position: function (point, params, dom, rect, size) { 42 position: function (point, params, dom, rect, size) {
35 return [point[0]-150, '10%']; 43 return [point[0]+20, '10%'];
36 }, 44 },
37 formatter: function (param) { 45 formatter: function (param) {
38 const value = param[0].value[1] 46 const value = param[0].value[1]
39 const sample = rawData.filter(([commit, dataValue]) => updateValue(dataValue) === value) 47 const sample = rawData.filter(([commit, dataValue]) => updateValue(dataValue) === value)
48 const formattedDate = new Date(sample[0][2] * 1000).toString().replace(/GMT[+-]\d{4}/, '').replace(/\(.*\)/, '(CEST)');
49
40 // Add commit hash to the tooltip as a link 50 // Add commit hash to the tooltip as a link
41 const commitLink = `https://git.yoctoproject.org/poky/commit/?id=${sample[0][3]}` 51 const commitLink = `https://git.yoctoproject.org/poky/commit/?id=${sample[0][3]}`
42 if ('{{ measurement.value_type.quantity }}' == 'time') { 52 if ('{{ measurement.value_type.quantity }}' == 'time') {
43 const hours = Math.floor(value/60) 53 const hours = Math.floor(value/60)
44 const minutes = Math.floor(value % 60) 54 const minutes = Math.floor(value % 60)
45 const seconds = Math.floor((value * 60) % 60) 55 const seconds = Math.floor((value * 60) % 60)
46 return `<strong>Duration:</strong> ${hours}:${minutes}:${seconds}, <br/> <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>` 56 return `<strong>Duration:</strong> ${hours}:${minutes}:${seconds}, <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>, <br/> <strong>Start time:</strong> ${formattedDate}`
47 } 57 }
48 return `<strong>Size:</strong> ${value.toFixed(2)} MB, <br/> <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>` 58 return `<strong>Size:</strong> ${value.toFixed(2)} MB, <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>, <br/> <strong>Start time:</strong> ${formattedDate}`
49 ;} 59 ;}
50 }, 60 },
51 xAxis: { 61 xAxis: {
@@ -79,22 +89,82 @@
79 ] 89 ]
80 }; 90 };
81 91
92 const option_commit_count = {
93 tooltip: {
94 trigger: 'axis',
95 enterable: true,
96 position: function (point, params, dom, rect, size) {
97 return [point[0]+20, '10%'];
98 },
99 formatter: function (param) {
100 const value = param[0].value
101 const sample = rawData.filter(([commit, dataValue]) => updateValue(dataValue) === value)
102 const formattedDate = new Date(sample[0][2] * 1000).toString().replace(/GMT[+-]\d{4}/, '').replace(/\(.*\)/, '(CEST)');
103 // Add commit hash to the tooltip as a link
104 const commitLink = `https://git.yoctoproject.org/poky/commit/?id=${sample[0][3]}`
105 if ('{{ measurement.value_type.quantity }}' == 'time') {
106 const hours = Math.floor(value/60)
107 const minutes = Math.floor(value % 60)
108 const seconds = Math.floor((value * 60) % 60)
109 return `<strong>Duration:</strong> ${hours}:${minutes}:${seconds}, <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>, <br/> <strong>Start time:</strong> ${formattedDate}`
110 }
111 return `<strong>Size:</strong> ${value.toFixed(2)} MB, <strong>Commit number:</strong> <a href="${commitLink}" target="_blank" rel="noreferrer noopener">${sample[0][0]}</a>, <br/> <strong>Start time:</strong> ${formattedDate}`
112 ;}
113 },
114 xAxis: {
115 name: 'Commit count',
116 type: 'category',
117 data: commitCountList
118 },
119 yAxis: {
120 name: '{{ measurement.value_type.quantity }}' == 'time' ? 'Duration in minutes' : 'Disk size in MB',
121 type: 'value',
122 min: function(value) {
123 return Math.round(value.min - 0.5);
124 },
125 max: function(value) {
126 return Math.round(value.max + 0.5);
127 }
128 },
129 dataZoom: [
130 {
131 type: 'slider',
132 xAxisIndex: 0,
133 filterMode: 'none'
134 },
135 ],
136 series: [
137 {
138 name: '{{ measurement.value_type.quantity }}',
139 type: 'line',
140 step: 'start',
141 symbol: 'none',
142 data: commitCountData
143 }
144 ]
145 };
146
82 // Draw chart 147 // Draw chart
83 const chart_div = document.getElementById('{{ chart_elem_id }}'); 148 const draw_chart = (chart_id, option) => {
84 // Set dark mode 149 let chart_name
85 let measurement_chart 150 const chart_div = document.getElementById(chart_id);
86 if (window.matchMedia('(prefers-color-scheme: dark)').matches) { 151 // Set dark mode
87 measurement_chart= echarts.init(chart_div, 'dark', { 152 if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
88 height: 320 153 chart_name= echarts.init(chart_div, 'dark', {
89 }); 154 height: 320
90 } else { 155 });
91 measurement_chart= echarts.init(chart_div, null, { 156 } else {
92 height: 320 157 chart_name= echarts.init(chart_div, null, {
158 height: 320
159 });
160 }
161 // Change chart size with browser resize
162 window.addEventListener('resize', function() {
163 chart_name.resize();
93 }); 164 });
165 return chart_name.setOption(option);
94 } 166 }
95 // Change chart size with browser resize 167
96 window.addEventListener('resize', function() { 168 draw_chart('{{ chart_elem_start_time_id }}', option_start_time)
97 measurement_chart.resize(); 169 draw_chart('{{ chart_elem_commit_count_id }}', option_commit_count)
98 });
99 measurement_chart.setOption(option);
100</script> 170</script>
diff --git a/scripts/lib/build_perf/html/report.html b/scripts/lib/build_perf/html/report.html
index 537ed3ee52..28cd80e738 100644
--- a/scripts/lib/build_perf/html/report.html
+++ b/scripts/lib/build_perf/html/report.html
@@ -9,7 +9,8 @@
9{% for test in test_data %} 9{% for test in test_data %}
10 {% if test.status == 'SUCCESS' %} 10 {% if test.status == 'SUCCESS' %}
11 {% for measurement in test.measurements %} 11 {% for measurement in test.measurements %}
12 {% set chart_elem_id = test.name + '_' + measurement.name + '_chart' %} 12 {% set chart_elem_start_time_id = test.name + '_' + measurement.name + '_chart_start_time' %}
13 {% set chart_elem_commit_count_id = test.name + '_' + measurement.name + '_chart_commit_count' %}
13 {% include 'measurement_chart.html' %} 14 {% include 'measurement_chart.html' %}
14 {% endfor %} 15 {% endfor %}
15 {% endif %} 16 {% endif %}
@@ -116,6 +117,22 @@ a {
116a:hover { 117a:hover {
117 color: #8080ff; 118 color: #8080ff;
118} 119}
120button {
121 background-color: #F3F4F6;
122 border: none;
123 outline: none;
124 cursor: pointer;
125 padding: 10px 12px;
126 transition: 0.3s;
127 border-radius: 8px;
128 color: #3A4353;
129}
130button:hover {
131 background-color: #d6d9e0;
132}
133.tab button.active {
134 background-color: #d6d9e0;
135}
119@media (prefers-color-scheme: dark) { 136@media (prefers-color-scheme: dark) {
120 :root { 137 :root {
121 --text: #e9e8fa; 138 --text: #e9e8fa;
@@ -126,6 +143,16 @@ a:hover {
126 --trborder: #212936; 143 --trborder: #212936;
127 --chartborder: #b1b0bf; 144 --chartborder: #b1b0bf;
128 } 145 }
146 button {
147 background-color: #28303E;
148 color: #fff;
149 }
150 button:hover {
151 background-color: #545a69;
152 }
153 .tab button.active {
154 background-color: #545a69;
155 }
129} 156}
130</style> 157</style>
131 158
@@ -233,7 +260,18 @@ a:hover {
233 <tr> 260 <tr>
234 <td style="width: 75%"> 261 <td style="width: 75%">
235 {# Linechart #} 262 {# Linechart #}
236 <div id="{{ test.name }}_{{ measurement.name }}_chart"></div> 263 <div class="tab {{ test.name }}_{{ measurement.name }}_tablinks">
264 <button class="tablinks active" onclick="openChart(event, '{{ test.name }}_{{ measurement.name }}_start_time', '{{ test.name }}_{{ measurement.name }}')">Chart with start time</button>
265 <button class="tablinks" onclick="openChart(event, '{{ test.name }}_{{ measurement.name }}_commit_count', '{{ test.name }}_{{ measurement.name }}')">Chart with commit count</button>
266 </div>
267 <div class="{{ test.name }}_{{ measurement.name }}_tabcontent">
268 <div id="{{ test.name }}_{{ measurement.name }}_start_time" class="tabcontent" style="display: block;">
269 <div id="{{ test.name }}_{{ measurement.name }}_chart_start_time"></div>
270 </div>
271 <div id="{{ test.name }}_{{ measurement.name }}_commit_count" class="tabcontent" style="display: none;">
272 <div id="{{ test.name }}_{{ measurement.name }}_chart_commit_count"></div>
273 </div>
274 </div>
237 </td> 275 </td>
238 <td> 276 <td>
239 {# Measurement statistics #} 277 {# Measurement statistics #}
@@ -340,6 +378,31 @@ a:hover {
340 <div class="preformatted">{{ test.message }}</div> 378 <div class="preformatted">{{ test.message }}</div>
341 {% endif %} 379 {% endif %}
342 {% endfor %} 380 {% endfor %}
343</div></body> 381</div>
344</html>
345 382
383<script>
384function openChart(event, chartType, chartName) {
385 let i, tabcontents, tablinks
386 tabcontents = document.querySelectorAll(`.${chartName}_tabcontent > .tabcontent`);
387 tabcontents.forEach((tabcontent) => {
388 tabcontent.style.display = "none";
389 });
390
391 tablinks = document.querySelectorAll(`.${chartName}_tablinks > .tablinks`);
392 tablinks.forEach((tabLink) => {
393 tabLink.classList.remove('active');
394 });
395
396 const targetTab = document.getElementById(chartType)
397 targetTab.style.display = "block";
398
399 // Call resize on the ECharts instance to redraw the chart
400 const chartContainer = targetTab.querySelector('div')
401 echarts.init(chartContainer).resize();
402
403 event.currentTarget.classList.add('active');
404}
405</script>
406
407</body>
408</html>