xref: /openbmc/openbmc/poky/scripts/lib/build_perf/html/measurement_chart.html (revision edff49234e31f23dc79f823473c9e286a21596c1)
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