Skip to content

Commit 3ba1b59

Browse files
authored
Merge pull request #1612 from rust-lang/compare-page-ui
Update compare page UI
2 parents a1794bb + ea002c7 commit 3ba1b59

File tree

16 files changed

+347
-71
lines changed

16 files changed

+347
-71
lines changed

site/frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.0.0",
44
"description": "",
55
"scripts": {
6-
"watch": "parcel watch",
6+
"watch": "parcel watch --no-hmr",
77
"build": "parcel build",
88
"fmt": "prettier --write src",
99
"check": "tsc -p tsconfig.json --noEmit && prettier --check src"

site/frontend/src/pages/compare/benchmarks/test-cases-table.vue

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -117,29 +117,41 @@ function prettifyRawNumber(number: number): string {
117117
</td>
118118
<td>{{ testCase.scenario }}</td>
119119
<td>
120-
<a
121-
v-bind:href="
122-
detailedQueryPercentLink(commitB, commitA, testCase)
123-
"
124-
>
125-
<span v-bind:class="percentClass(testCase.percent)">
126-
{{ testCase.percent.toFixed(2) }}%
127-
</span>
128-
</a>
120+
<div class="numeric-aligned">
121+
<div>
122+
<a
123+
v-bind:href="
124+
detailedQueryPercentLink(commitB, commitA, testCase)
125+
"
126+
>
127+
<span v-bind:class="percentClass(testCase.percent)">
128+
{{ testCase.percent.toFixed(2) }}%
129+
</span>
130+
</a>
131+
</div>
132+
</div>
129133
</td>
130134
<td>
131-
{{
132-
testCase.significanceThreshold
133-
? testCase.significanceThreshold.toFixed(2) + "%"
134-
: "-"
135-
}}
135+
<div class="numeric-aligned">
136+
<div>
137+
{{
138+
testCase.significanceThreshold
139+
? testCase.significanceThreshold.toFixed(2) + "%"
140+
: "-"
141+
}}
142+
</div>
143+
</div>
136144
</td>
137145
<td>
138-
{{
139-
testCase.significanceFactor
140-
? testCase.significanceFactor.toFixed(2) + "x"
141-
: "-"
142-
}}
146+
<div class="numeric-aligned">
147+
<div>
148+
{{
149+
testCase.significanceFactor
150+
? testCase.significanceFactor.toFixed(2) + "x"
151+
: "-"
152+
}}
153+
</div>
154+
</div>
143155
</td>
144156
<td v-if="showRawData" class="numeric">
145157
<a v-bind:href="detailedQueryRawDataLink(commitA, testCase)">
@@ -189,17 +201,27 @@ function prettifyRawNumber(number: number): string {
189201
190202
.benches th {
191203
text-align: center;
192-
width: 25%;
193204
min-width: 50px;
194205
}
195206
196207
.benches td {
197208
text-align: center;
198209
width: 25%;
199-
}
200210
201-
.benches td.numeric {
202-
text-align: right;
211+
& > .numeric-aligned {
212+
display: flex;
213+
flex-direction: column;
214+
align-items: center;
215+
text-align: right;
216+
217+
& > div {
218+
width: 70px;
219+
}
220+
}
221+
222+
&.numeric {
223+
text-align: right;
224+
}
203225
}
204226
205227
.bench-table {

site/frontend/src/pages/compare/bootstrap-table.vue

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import {CompareResponse} from "./types";
3-
import {percentClass} from "./shared";
3+
import {diffClass, percentClass} from "./shared";
44
55
const props = defineProps<{data: CompareResponse}>();
66
@@ -44,16 +44,6 @@ const bootstraps = Object.entries(props.data.a.bootstrap)
4444
return a.name.localeCompare(b.name);
4545
}
4646
});
47-
48-
function diffClass(diff: number): string {
49-
let klass = "";
50-
if (diff > 1) {
51-
klass = "positive";
52-
} else if (diff < -1) {
53-
klass = "negative";
54-
}
55-
return klass;
56-
}
5747
</script>
5848

5949
<template>

site/frontend/src/pages/compare/header/filters.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ watch(
3333

3434
<template>
3535
<fieldset class="collapsible-section">
36-
<Toggle :defaultOpened="true">
36+
<Toggle :defaultOpened="false">
3737
<template #label>Filters</template>
3838
<template #content>
3939
<div>

site/frontend/src/pages/compare/header/header.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const after = computed(() =>
6161
</script>
6262

6363
<template>
64-
<h2>
64+
<h2 style="text-align: center">
6565
Comparing <span id="stat-header">{{ selector.stat }}</span> between
6666
<span id="before">{{ before }}</span> and
6767
<span id="after">{{ after }}</span>

site/frontend/src/pages/compare/header/quick-links.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const metrics = [
3939

4040
<template>
4141
<div class="quick-links">
42-
<div>Quick links:</div>
42+
<div class="label">Quick links:</div>
4343
<div
4444
v-for="metric in metrics"
4545
:class="{active: props.stat === metric.stat}"
@@ -64,4 +64,12 @@ const metrics = [
6464
.quick-links .active {
6565
font-weight: bold;
6666
}
67+
68+
.quick-links .label {
69+
display: none;
70+
71+
@media (min-width: 600px) {
72+
display: block;
73+
}
74+
}
6775
</style>

site/frontend/src/pages/compare/page.vue

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import {loadBenchmarkInfo} from "../../api";
33
import AsOf from "../../components/as-of.vue";
44
import {
5-
createUrlFromParams,
5+
changeUrl,
66
createUrlWithAppendedParams,
77
getUrlParams,
88
navigateToUrlParams,
@@ -11,7 +11,7 @@ import {computed, Ref, ref} from "vue";
1111
import {withLoading} from "../../utils/loading";
1212
import {postMsgpack} from "../../utils/requests";
1313
import {COMPARE_DATA_URL} from "../../urls";
14-
import {CompareResponse, CompareSelector, DataFilter} from "./types";
14+
import {CompareResponse, CompareSelector, DataFilter, Tab} from "./types";
1515
import BootstrapTable from "./bootstrap-table.vue";
1616
import Header from "./header/header.vue";
1717
import DataSelector, {SelectionParams} from "./header/data-selector.vue";
@@ -23,10 +23,12 @@ import {
2323
computeSummary,
2424
computeTestCasesWithNonRelevant,
2525
filterNonRelevant,
26+
SummaryGroup,
2627
} from "./data";
2728
import OverallTable from "./summary/overall-table.vue";
2829
import Aggregations from "./summary/aggregations.vue";
2930
import Benchmarks from "./benchmarks/benchmarks.vue";
31+
import Tabs from "./tabs.vue";
3032
3133
function loadSelectorFromUrl(urlParams: Dict<string>): CompareSelector {
3234
const start = urlParams["start"] ?? "";
@@ -39,6 +41,21 @@ function loadSelectorFromUrl(urlParams: Dict<string>): CompareSelector {
3941
};
4042
}
4143
44+
function loadTabFromUrl(urlParams: Dict<string>): Tab | null {
45+
const tab = urlParams["tab"] ?? "";
46+
if (tab == Tab.CompileTime) {
47+
return Tab.CompileTime;
48+
} else if (tab == Tab.Bootstrap) {
49+
return Tab.Bootstrap;
50+
}
51+
return null;
52+
}
53+
54+
function storeTabToUrl(urlParams: Dict<string>, tab: Tab) {
55+
urlParams["tab"] = tab as string;
56+
changeUrl(urlParams);
57+
}
58+
4259
function loadFilterFromUrl(
4360
urlParams: Dict<string>,
4461
defaultFilter: DataFilter
@@ -139,10 +156,7 @@ function storeFilterToUrl(
139156
defaultFilter.category.secondary
140157
);
141158
142-
// Change URL without creating a history entry
143-
if (history.replaceState) {
144-
history.replaceState({}, null, createUrlFromParams(urlParams).toString());
145-
}
159+
changeUrl(urlParams);
146160
}
147161
148162
async function loadCompareData(
@@ -158,6 +172,16 @@ async function loadCompareData(
158172
return await postMsgpack<CompareResponse>(COMPARE_DATA_URL, params);
159173
});
160174
data.value = response;
175+
totalSummary.value = computeSummary(
176+
filterNonRelevant(
177+
defaultFilter,
178+
computeTestCasesWithNonRelevant(
179+
defaultFilter,
180+
data.value,
181+
benchmarkMap.value
182+
)
183+
)
184+
);
161185
}
162186
163187
function updateSelection(params: SelectionParams) {
@@ -222,13 +246,26 @@ const testCases = computed(() =>
222246
);
223247
const filteredSummary = computed(() => computeSummary(testCases.value));
224248
249+
// Include all relevant changes in the compile-time tab summary
250+
// We do not wrap it in computed, because it should be loaded only once, after
251+
// the data is downloaded.
252+
const totalSummary: Ref<SummaryGroup | null> = ref(null);
253+
225254
const loading = ref(false);
226255
227256
const quickLinksKey = ref(0);
228257
const info = await loadBenchmarkInfo();
229258
const selector = loadSelectorFromUrl(urlParams);
230259
const filter = ref(loadFilterFromUrl(urlParams, defaultFilter));
231260
261+
const initialTab: Tab = loadTabFromUrl(urlParams) ?? Tab.CompileTime;
262+
const tab: Ref<Tab> = ref(initialTab);
263+
264+
function changeTab(newTab: Tab) {
265+
tab.value = newTab;
266+
storeTabToUrl(getUrlParams(), newTab);
267+
}
268+
232269
const data: Ref<CompareResponse | null> = ref(null);
233270
loadCompareData(selector, loading);
234271
</script>
@@ -247,23 +284,31 @@ loadCompareData(selector, loading);
247284
<p>Loading ...</p>
248285
</div>
249286
<div v-if="data !== null">
250-
<QuickLinks :stat="selector.stat" :key="quickLinksKey" />
251-
<Filters
252-
:defaultFilter="defaultFilter"
253-
:initialFilter="filter"
254-
@change="updateFilter"
255-
@export="exportData"
256-
/>
257-
<OverallTable :summary="filteredSummary" />
258-
<Aggregations :cases="testCases" />
259-
<Benchmarks
287+
<Tabs
288+
@change-tab="changeTab"
260289
:data="data"
261-
:test-cases="testCases"
262-
:all-test-cases="allTestCases"
263-
:filter="filter"
264-
:stat="selector.stat"
265-
></Benchmarks>
266-
<BootstrapTable :data="data" />
290+
:initial-tab="initialTab"
291+
:compile-time-summary="totalSummary"
292+
/>
293+
<template v-if="tab === Tab.CompileTime">
294+
<QuickLinks :stat="selector.stat" :key="quickLinksKey" />
295+
<Filters
296+
:defaultFilter="defaultFilter"
297+
:initialFilter="filter"
298+
@change="updateFilter"
299+
@export="exportData"
300+
/>
301+
<OverallTable :summary="filteredSummary" />
302+
<Aggregations :cases="testCases" />
303+
<Benchmarks
304+
:data="data"
305+
:test-cases="testCases"
306+
:all-test-cases="allTestCases"
307+
:filter="filter"
308+
:stat="selector.stat"
309+
></Benchmarks>
310+
</template>
311+
<BootstrapTable v-if="tab === Tab.Bootstrap" :data="data" />
267312
</div>
268313
</div>
269314
<br />

site/frontend/src/pages/compare/shared.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,10 @@ export function percentClass(pct: number): string {
2727
}
2828
return klass;
2929
}
30+
31+
export function diffClass(diff: number): string {
32+
if (diff >= 0) {
33+
return "positive";
34+
}
35+
return "negative";
36+
}

site/frontend/src/pages/compare/summary/percent-value.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import {computed} from "vue";
3-
import {signIfPositive} from "../shared";
3+
import {percentClass, signIfPositive} from "../shared";
44
55
const props = withDefaults(
66
defineProps<{
@@ -23,5 +23,7 @@ const padSpaces = computed((): string => {
2323
</script>
2424

2525
<template>
26-
<span><span v-html="padSpaces" />{{ formattedValue }}%</span>
26+
<span :class="percentClass(props.value)"
27+
><span v-html="padSpaces" />{{ formattedValue }}%</span
28+
>
2729
</template>

site/frontend/src/pages/compare/summary/summary-table.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const summary = computed(() => props.summary);
3939
</tr>
4040
</thead>
4141
<tbody>
42-
<tr class="positive">
42+
<tr>
4343
<td title="Regressions" v-if="withLegend">❌</td>
4444
<template v-if="summary.regressions.count !== 0">
4545
<td>
@@ -48,7 +48,7 @@ const summary = computed(() => props.summary);
4848
<td>
4949
<SummaryPercentValue :value="summary.regressions.average" />
5050
</td>
51-
<td>
51+
<td class="positive">
5252
<SummaryCount
5353
:cases="summary.regressions.count"
5454
:benchmarks="summary.regressions.benchmarks"
@@ -59,7 +59,7 @@ const summary = computed(() => props.summary);
5959
<td colspan="3" style="text-align: center">No regressions</td>
6060
</template>
6161
</tr>
62-
<tr class="negative">
62+
<tr>
6363
<td title="Improvements" v-if="withLegend">✅</td>
6464
<template v-if="summary.improvements.count !== 0">
6565
<td>
@@ -68,7 +68,7 @@ const summary = computed(() => props.summary);
6868
<td>
6969
<SummaryPercentValue :value="summary.improvements.average" />
7070
</td>
71-
<td>
71+
<td class="negative">
7272
<SummaryCount
7373
:cases="summary.improvements.count"
7474
:benchmarks="summary.improvements.benchmarks"

0 commit comments

Comments
 (0)