Skip to content

Commit d77fbfa

Browse files
mattipclaude
andcommitted
refactor home page to use chart.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d60173c commit d77fbfa

1 file changed

Lines changed: 81 additions & 116 deletions

File tree

speed_pypy/templates/home.html

Lines changed: 81 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ <h2>Comparison</h2>
2929
{% if show_historical %}
3030
<div id="historical">
3131
<h3>How fast is {{ default_exe.project }}?</h3>
32-
<div id="baseline-comparison-plot"></div>
32+
<div id="baseline-comparison-plot" style="position:relative;height:400px;"></div>
3333
<p class="plot-caption">Plot 1: The above plot represents {{ default_exe.project }} ({{ default_exe }}) benchmark times normalized to {{ baseline }}. Smaller is better.</p>
3434
<p>It depends greatly on the type of task being performed. The geometric average of all benchmarks is <span id="geomean"></span> or <strong id="geofaster"></strong> times <em>faster</em> than {{ baseline }}</p>
3535

3636
<h3>How has PyPy performance evolved over time?</h3>
37-
<div id="historical-plot"></div>
37+
<div id="historical-plot" style="position:relative;height:350px;"></div>
3838
<p class="plot-caption">Plot 2: Speedup compared to {{ baseline }}, using the inverse of the geometric average of normalized times, out of <span id="num_of_benchs"></span> benchmarks (see <a href="http://dl.acm.org/citation.cfm?id=5673" title="How not to lie with statistics: the correct way to summarize benchmark results">paper</a> on why the geometric mean is better for normalized results).</p>
3939
</div>
4040
{% endif %}
@@ -44,172 +44,137 @@ <h3>How has PyPy performance evolved over time?</h3>
4444
{% block extra_script %}
4545
{{ block.super }}
4646
{% if show_historical %}
47-
<link rel="stylesheet" type="text/css" href="{% static 'js/jqplot/jquery.jqplot.min.css' %}" />
48-
<script type="text/javascript" src="{% static 'js/jqplot/jquery.jqplot.min.js' %}"></script>
49-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.barRenderer.min.js' %}"></script>
50-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasAxisTickRenderer.min.js' %}"></script>
51-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.categoryAxisRenderer.min.js' %}"></script>
52-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasAxisLabelRenderer.min.js' %}"></script>
53-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.pointLabels.min.js' %}"></script>
54-
<script type="text/javascript" src="{% static 'js/jqplot/jqplot.canvasTextRenderer.min.js' %}"></script>
47+
<script type="text/javascript" src="{% static 'js/chart.umd.min.js' %}"></script>
5548
{% endif %}
5649

5750
<script type="text/javascript">
5851
function updateReportTables() {
59-
//Add permalink events to table rows
6052
$("div#reports table tbody tr").each(function() {
6153
$(this).click(function () {
6254
window.location = $(this).find("td:eq(0) label").text();
6355
});
6456
});
65-
//Add hover effect to rows
6657
$("div#reports table tbody tr td").hover(function() {
6758
$(this).parents('tr').addClass('highlight');
6859
}, function() {
6960
$(this).parents('tr').removeClass('highlight');
7061
});
7162
}
7263

73-
function numOrd(a, b){ return (a-b); }
64+
{% if show_historical %}
65+
Chart.Tooltip.positioners.cursor = function(_items, eventPosition) {
66+
return {x: eventPosition.x, y: eventPosition.y};
67+
};
7468

7569
function renderplot(data) {
76-
var plotoptions = {};
77-
var plotdata = [new Array(), new Array()];
78-
var labels = new Array();
79-
var benchmarks = new Array();
8070
if (data === null || data.length === 0) {
8171
$("#baseline-comparison-plot").html(getLoadText('Error retrieving data', 0));
82-
return 1;
72+
return;
8373
}
8474
if (typeof data === 'string' || data instanceof String) {
8575
$("#baseline-comparison-plot").html(getLoadText('Error retrieving data ' + data, 0));
86-
return 1;
76+
return;
8777
}
78+
79+
var benchmarks = [], latestValues = [], baselineValues = [];
8880
var trunk_geomean = 1;
89-
var tagged_data = new Array();
90-
for (i in data['tagged_revs']) {
91-
tagged_data[i] = new Array();
92-
}
81+
var tagged_data = [];
82+
for (var i in data['tagged_revs']) { tagged_data[i] = []; }
83+
9384
for (var bench in data['benchmarks']) {
94-
var relative_value = 0;
95-
benchname = data['benchmarks'][bench];
85+
var benchname = data['benchmarks'][bench];
9686
var add_to_tagged_data = true;
9787
for (var i in data['tagged_revs']) {
9888
var rev = data['tagged_revs'][i];
99-
if (data['results'][benchname][rev] === 0) {
100-
add_to_tagged_data = false;
101-
}
102-
if (add_to_tagged_data === false) { break; }
103-
relative_value = data['results'][benchname][rev]/data['results'][benchname][data['baseline']];
104-
tagged_data[i].push(relative_value)
89+
if (data['results'][benchname][rev] === 0) { add_to_tagged_data = false; break; }
90+
tagged_data[i].push(data['results'][benchname][rev] / data['results'][benchname][data['baseline']]);
10591
}
106-
// Only add benchmark if there are no 0 values
107-
if (add_to_tagged_data === false) { continue; }
108-
// First add benchmark
92+
if (!add_to_tagged_data) { continue; }
10993
benchmarks.push(benchname);
110-
// Add latest results and baseline
111-
relative_value = data['results'][benchname]['latest']/data['results'][benchname][data['baseline']];
112-
plotdata[0].push(relative_value);
113-
plotdata[1].push(1.0);
114-
labels.push(relative_value.toFixed(2));
115-
if (relative_value > 0 && !isNaN(relative_value)) {
116-
trunk_geomean *= relative_value;
117-
}
94+
var rel = data['results'][benchname]['latest'] / data['results'][benchname][data['baseline']];
95+
latestValues.push(rel);
96+
baselineValues.push(1.0);
97+
if (rel > 0 && !isNaN(rel)) { trunk_geomean *= rel; }
11898
}
119-
trunk_geomean = Math.pow(trunk_geomean, 1/plotdata[0].length);
120-
var geofaster = 1/trunk_geomean;
99+
100+
trunk_geomean = Math.pow(trunk_geomean, 1 / latestValues.length);
121101
$('#geomean').html(trunk_geomean.toFixed(2));
122-
$('#geofaster').html(geofaster.toFixed(1));
123-
// Render first plot
124-
plotoptions1 = {
125-
legend:{show:true},
126-
seriesDefaults: {
127-
showMarker: false,
128-
rendererOptions:{barPadding: 2, barMargin:5}
129-
},
130-
axesDefaults: {
131-
tickRenderer: $.jqplot.CanvasAxisTickRenderer
102+
$('#geofaster').html((1 / trunk_geomean).toFixed(1));
103+
104+
// Plot 1: per-benchmark normalized comparison
105+
var wrap1 = document.getElementById('baseline-comparison-plot');
106+
var canvas1 = document.createElement('canvas');
107+
wrap1.appendChild(canvas1);
108+
new Chart(canvas1, {
109+
type: 'bar',
110+
data: {
111+
labels: benchmarks,
112+
datasets: [
113+
{label: 'latest {{ default_exe }}', data: latestValues, backgroundColor: '#4e79a7'},
114+
{label: data['baseline'], data: baselineValues, backgroundColor: '#f28e2b'}
115+
]
132116
},
133-
series:[
134-
{
135-
label: 'latest',
136-
renderer:$.jqplot.BarRenderer,
137-
pointLabels:{labels: labels}
138-
},
139-
{
140-
label: data['baseline'],
141-
pointLabels:{show: false}
142-
}
143-
],
144-
axes: {
145-
xaxis: {
146-
renderer: $.jqplot.CategoryAxisRenderer,
147-
ticks: benchmarks,
148-
tickOptions: {angle: -70}
117+
options: {
118+
animation: false,
119+
responsive: true,
120+
maintainAspectRatio: false,
121+
plugins: {
122+
tooltip: {position: 'cursor'}
149123
},
150-
yaxis:{
151-
ticks: [0, 0.5, 1, 1.5],
152-
tickOptions:{formatString: '%.2f'}
124+
scales: {
125+
x: {ticks: {maxRotation: 70, minRotation: 70, autoSkip: false, font: {size: 11}}},
126+
y: {min: 0, ticks: {callback: function(v) { return v.toFixed(2); }}}
153127
}
154128
}
155-
};
156-
plot1 = $.jqplot("baseline-comparison-plot", plotdata, plotoptions1);
129+
});
157130

158-
// Prepare and render second plot
131+
// Plot 2: geomean speedup over tagged revisions
159132
var geomeans = [1.0];
160133
var num_of_benchs = 0;
161134
for (var i in data['tagged_revs']) {
162135
num_of_benchs = tagged_data[i].length;
163136
var tempgeo = 1;
164137
for (var j in tagged_data[i]) {
165-
value = tagged_data[i][j];
166-
if (value > 0 && !isNaN(value)) {
167-
tempgeo *= value;
168-
}
138+
var val = tagged_data[i][j];
139+
if (val > 0 && !isNaN(val)) { tempgeo *= val; }
169140
}
170-
tempgeo = Math.pow(tempgeo, 1/tagged_data[i].length);
171-
tempgeo = 1/tempgeo;
172-
geomeans.push(tempgeo);
173-
}
174-
geomeans.push(1/trunk_geomean);
175-
var ticks = [data['baseline']];
176-
for (var i in data['tagged_revs']) {
177-
ticks.push(data['tagged_revs'][i]);
178-
}
179-
ticks.push('latest {{ default_exe.project }}');
180-
var geolabels = new Array();
181-
for (var i in geomeans) {
182-
geolabels.push(geomeans[i].toFixed(2) + "x");
141+
geomeans.push(1 / Math.pow(tempgeo, 1 / tagged_data[i].length));
183142
}
184-
$('#num_of_benchs').html(num_of_benchs)
143+
geomeans.push(1 / trunk_geomean);
144+
$('#num_of_benchs').html(num_of_benchs);
185145

186-
plotoptions2 = {
187-
seriesDefaults: {
188-
renderer:$.jqplot.BarRenderer,
189-
showMarker: false
190-
},
191-
axesDefaults: {
192-
tickRenderer: $.jqplot.CanvasAxisTickRenderer
146+
var ticks2 = [data['baseline']];
147+
for (var i in data['tagged_revs']) { ticks2.push(data['tagged_revs'][i]); }
148+
ticks2.push('latest {{ default_exe.project }}');
149+
150+
var wrap2 = document.getElementById('historical-plot');
151+
var canvas2 = document.createElement('canvas');
152+
wrap2.appendChild(canvas2);
153+
new Chart(canvas2, {
154+
type: 'bar',
155+
data: {
156+
labels: ticks2,
157+
datasets: [{
158+
label: 'Speedup vs {{ baseline }}',
159+
data: geomeans,
160+
backgroundColor: '#4e79a7'
161+
}]
193162
},
194-
series:[
195-
{
196-
pointLabels:{labels:geolabels}
197-
}
198-
],
199-
axes: {
200-
xaxis: {
201-
renderer: $.jqplot.CategoryAxisRenderer,
202-
ticks: ticks,
203-
tickOptions: {angle: -40}
163+
options: {
164+
animation: false,
165+
responsive: true,
166+
maintainAspectRatio: false,
167+
plugins: {
168+
tooltip: {position: 'cursor'}
204169
},
205-
yaxis:{
206-
min: 0,
207-
tickOptions:{formatString:'%.1f'}
170+
scales: {
171+
x: {ticks: {maxRotation: 40, minRotation: 40}},
172+
y: {min: 0, ticks: {callback: function(v) { return v.toFixed(1) + 'x'; }}}
208173
}
209174
}
210-
};
211-
plot2 = $.jqplot("historical-plot", [geomeans], plotoptions2);
175+
});
212176
}
177+
{% endif %}
213178

214179
$(function() {
215180
{% if show_reports %}

0 commit comments

Comments
 (0)