1<script type="module"> 2 // Get raw data 3 const rawData = [ 4 {% for sample in measurement.samples %} 5 [{{ sample.commit_num }}, {{ sample.mean.gv_value() }}, {{ sample.start_time }}, '{{sample.commit}}'], 6 {% endfor %} 7 ]; 8 9 const convertToMinute = (time) => { 10 return time[0]*60 + time[1] + time[2]/60 + time[3]/3600; 11 } 12 13 // Update value format to either minutes or leave as size value 14 const updateValue = (value) => { 15 // Assuming the array values are duration in the format [hours, minutes, seconds, milliseconds] 16 return Array.isArray(value) ? convertToMinute(value) : value 17 } 18 19 // Convert raw data to the format: [time, value] 20 const data = rawData.map(([commit, value, time]) => { 21 return [ 22 // The Date object takes values in milliseconds rather than seconds. So to use a Unix timestamp we have to multiply it by 1000. 23 new Date(time * 1000).getTime(), 24 // Assuming the array values are duration in the format [hours, minutes, seconds, milliseconds] 25 updateValue(value) 26 ] 27 }); 28 29 // Set chart options 30 const option = { 31 tooltip: { 32 trigger: 'axis', 33 enterable: true, 34 position: function (point, params, dom, rect, size) { 35 return [point[0]-150, '10%']; 36 }, 37 formatter: function (param) { 38 const value = param[0].value[1] 39 const sample = rawData.filter(([commit, dataValue]) => updateValue(dataValue) === value) 40 // Add commit hash to the tooltip as a link 41 const commitLink = `https://git.yoctoproject.org/poky/commit/?id=${sample[0][3]}` 42 if ('{{ measurement.value_type.quantity }}' == 'time') { 43 const hours = Math.floor(value/60) 44 const minutes = Math.floor(value % 60) 45 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>` 47 } 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>` 49 ;} 50 }, 51 xAxis: { 52 type: 'time', 53 }, 54 yAxis: { 55 name: '{{ measurement.value_type.quantity }}' == 'time' ? 'Duration in minutes' : 'Disk size in MB', 56 type: 'value', 57 min: function(value) { 58 return Math.round(value.min - 0.5); 59 }, 60 max: function(value) { 61 return Math.round(value.max + 0.5); 62 } 63 }, 64 dataZoom: [ 65 { 66 type: 'slider', 67 xAxisIndex: 0, 68 filterMode: 'none' 69 }, 70 ], 71 series: [ 72 { 73 name: '{{ measurement.value_type.quantity }}', 74 type: 'line', 75 step: 'start', 76 symbol: 'none', 77 data: data 78 } 79 ] 80 }; 81 82 // Draw chart 83 const chart_div = document.getElementById('{{ chart_elem_id }}'); 84 // Set dark mode 85 let measurement_chart 86 if (window.matchMedia('(prefers-color-scheme: dark)').matches) { 87 measurement_chart= echarts.init(chart_div, 'dark', { 88 height: 320 89 }); 90 } else { 91 measurement_chart= echarts.init(chart_div, null, { 92 height: 320 93 }); 94 } 95 // Change chart size with browser resize 96 window.addEventListener('resize', function() { 97 measurement_chart.resize(); 98 }); 99 measurement_chart.setOption(option); 100</script> 101