|
4 | 4 | <meta charset="utf-8"> |
5 | 5 | <title>PyLCM Benchmarks</title> |
6 | 6 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
7 | | - <script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script> |
| 7 | + <script src="https://cdn.jsdelivr.net/npm/plotly.js-basic-dist-min@2"></script> |
8 | 8 | <style> |
9 | 9 | body { font-family: system-ui, sans-serif; margin: 2rem; } |
10 | 10 | h1 { margin-bottom: 0.5rem; } |
11 | | - .chart-box { margin: 1.5rem 0; max-width: 900px; } |
12 | | - canvas { max-height: 350px; } |
| 11 | + .chart-box { margin: 1rem 0; max-width: 900px; } |
13 | 12 | details { margin: 0.5rem 0; } |
14 | 13 | summary { cursor: pointer; font-weight: 600; } |
15 | 14 | p.meta { color: #666; font-size: 0.9rem; } |
@@ -71,90 +70,76 @@ <h1>PyLCM Benchmarks</h1> |
71 | 70 | sub.textContent = DESCRIPTIONS[group]; |
72 | 71 | det.appendChild(sub); |
73 | 72 | } |
74 | | - var div = document.createElement('div'); |
75 | | - div.className = 'chart-box'; |
76 | | - var cv = document.createElement('canvas'); |
77 | | - div.appendChild(cv); |
78 | | - det.appendChild(div); |
| 73 | + var plotDiv = document.createElement('div'); |
| 74 | + plotDiv.className = 'chart-box'; |
| 75 | + det.appendChild(plotDiv); |
79 | 76 | box.appendChild(det); |
80 | 77 | var commitIds = entries.map(function(e) { |
81 | 78 | return e.commit.id || ''; |
82 | 79 | }); |
83 | | - var labels = commitIds.map(function(id) { |
| 80 | + var shortShas = commitIds.map(function(id) { |
84 | 81 | return id ? id.slice(0, 8) : '?'; |
85 | 82 | }); |
86 | | - var ds = gNames.map(function(name, i) { |
87 | | - var hue = (i * 360 / gNames.length) % 360; |
88 | | - return { |
89 | | - label: name, |
90 | | - data: entries.map(function(e) { |
91 | | - var b = e.benches.find( |
92 | | - function(x) { return x.name === name; } |
| 83 | + var traces = gNames.map(function(name) { |
| 84 | + var yVals = []; |
| 85 | + var hoverTexts = []; |
| 86 | + entries.forEach(function(e, i) { |
| 87 | + var b = e.benches.find(function(x) { return x.name === name; }); |
| 88 | + yVals.push(b ? b.value * 1000 : null); |
| 89 | + if (b) { |
| 90 | + hoverTexts.push( |
| 91 | + '<b>' + name + '</b><br>' + |
| 92 | + (b.value * 1000).toFixed(2) + ' ms ' + b.range + '<br>' + |
| 93 | + b.extra + '<br>' + |
| 94 | + '<i>' + shortShas[i] + '</i>' |
93 | 95 | ); |
94 | | - return b ? b.value * 1000 : null; |
95 | | - }), |
96 | | - borderColor: 'hsl('+hue+',70%,50%)', |
97 | | - tension: 0.2, |
98 | | - spanGaps: true |
| 96 | + } else { |
| 97 | + hoverTexts.push(''); |
| 98 | + } |
| 99 | + }); |
| 100 | + return { |
| 101 | + x: shortShas, |
| 102 | + y: yVals, |
| 103 | + name: name, |
| 104 | + mode: 'lines+markers', |
| 105 | + connectgaps: true, |
| 106 | + hoverinfo: 'text', |
| 107 | + hovertext: hoverTexts, |
| 108 | + marker: { size: 6 } |
99 | 109 | }; |
100 | 110 | }); |
101 | | - new Chart(cv, { |
102 | | - type: 'line', |
103 | | - data: { labels: labels, datasets: ds }, |
104 | | - options: { |
105 | | - responsive: true, |
106 | | - onClick: function(evt, elems, chart) { |
107 | | - var rect = cv.getBoundingClientRect(); |
108 | | - var x = evt.native.clientX - rect.left; |
109 | | - var y = evt.native.clientY - rect.top; |
110 | | - var xScale = chart.scales.x; |
111 | | - var idx; |
112 | | - if (y >= xScale.top) { |
113 | | - idx = xScale.getValueForPixel(x); |
114 | | - } else { |
115 | | - var pts = chart.getElementsAtEventForMode( |
116 | | - evt, 'index', { intersect: false }, false |
117 | | - ); |
118 | | - if (pts.length > 0) idx = pts[0].index; |
119 | | - } |
120 | | - if (idx != null && idx >= 0 && idx < commitIds.length) { |
121 | | - var sha = commitIds[idx]; |
122 | | - if (sha) window.open(GH + sha, '_blank'); |
123 | | - } |
124 | | - }, |
125 | | - plugins: { |
126 | | - legend: { |
127 | | - position: 'bottom', |
128 | | - labels: { boxWidth: 12, font: { size: 11 } } |
129 | | - } |
130 | | - }, |
131 | | - scales: { |
132 | | - y: { |
133 | | - title: { display: true, text: 'Time (ms)' }, |
134 | | - beginAtZero: false |
135 | | - }, |
136 | | - x: { |
137 | | - title: { display: true, text: 'Commit' }, |
138 | | - ticks: { |
139 | | - color: '#0969da', |
140 | | - font: { size: 11 } |
141 | | - } |
142 | | - } |
143 | | - }, |
144 | | - onHover: function(evt, elems, chart) { |
145 | | - var rect = cv.getBoundingClientRect(); |
146 | | - var y = evt.native.clientY - rect.top; |
147 | | - var xScale = chart.scales.x; |
148 | | - if (y >= xScale.top) { |
149 | | - cv.style.cursor = 'pointer'; |
150 | | - return; |
151 | | - } |
152 | | - var pts = chart.getElementsAtEventForMode( |
153 | | - evt, 'index', { intersect: false }, false |
154 | | - ); |
155 | | - cv.style.cursor = pts.length ? 'pointer' : ''; |
156 | | - } |
157 | | - } |
| 111 | + var layout = { |
| 112 | + template: 'plotly_white', |
| 113 | + height: 350, |
| 114 | + margin: { l: 60, r: 20, t: 10, b: 60 }, |
| 115 | + xaxis: { |
| 116 | + title: 'Commit', |
| 117 | + tickfont: { size: 11, color: '#0969da' }, |
| 118 | + type: 'category' |
| 119 | + }, |
| 120 | + yaxis: { |
| 121 | + title: 'Time (ms)' |
| 122 | + }, |
| 123 | + legend: { |
| 124 | + orientation: 'h', |
| 125 | + yanchor: 'top', |
| 126 | + y: -0.25, |
| 127 | + xanchor: 'center', |
| 128 | + x: 0.5 |
| 129 | + }, |
| 130 | + hovermode: 'closest' |
| 131 | + }; |
| 132 | + var config = { |
| 133 | + responsive: true, |
| 134 | + displayModeBar: true, |
| 135 | + modeBarButtonsToRemove: ['lasso2d', 'select2d'], |
| 136 | + displaylogo: false |
| 137 | + }; |
| 138 | + Plotly.newPlot(plotDiv, traces, layout, config); |
| 139 | + plotDiv.on('plotly_click', function(clickData) { |
| 140 | + var idx = clickData.points[0].pointIndex; |
| 141 | + var sha = commitIds[idx]; |
| 142 | + if (sha) window.open(GH + sha, '_blank'); |
158 | 143 | }); |
159 | 144 | }); |
160 | 145 | }); |
|
0 commit comments