Skip to content

Commit cf26f96

Browse files
committed
Turn fraction chart legend into a table
1 parent 03e4bd1 commit cf26f96

File tree

1 file changed

+108
-66
lines changed

1 file changed

+108
-66
lines changed

site/frontend/src/pages/compare/compile/table/sections-chart.vue

Lines changed: 108 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ const afterTotalWidth = computed(() => {
1818
return calculateTotalSectionsDuration(props.after);
1919
});
2020
21+
const maxTotalWidth = computed(() => {
22+
return Math.max(beforeTotalWidth.value, afterTotalWidth.value);
23+
});
24+
2125
const SECTIONS_PALETTE = [
2226
"#7768AE",
2327
"#FFCf96",
@@ -58,23 +62,38 @@ function formatPercent(
5862
return `${percent.toFixed(2)}%`;
5963
}
6064
65+
function getRowWidth(): number {
66+
return maxTotalWidth.value;
67+
}
68+
6169
const chartRows: ComputedRef<Array<[string, CompilationSections]>> = computed(
6270
() => [
6371
["Before", props.before],
6472
["After", props.after],
6573
]
6674
);
6775
const legendItems: ComputedRef<
68-
Array<{section: CompilationSection; label: string; color: string}>
76+
Array<{
77+
section: CompilationSection;
78+
color: string;
79+
beforePercent: string;
80+
beforeAbsolute: string;
81+
afterPercent: string;
82+
afterAbsolute: string;
83+
}>
6984
> = computed(() => {
7085
const items = [];
7186
for (const section of props.before.sections) {
7287
items.push({
7388
section,
74-
label: `${section.name} (${formatPercent(
75-
props.before,
76-
section.name
77-
)} -> ${formatPercent(props.after, section.name)})`,
89+
beforePercent: formatPercent(props.before, section.name),
90+
beforeAbsolute:
91+
getSectionByName(props.before, section.name)?.value?.toLocaleString() ??
92+
"??",
93+
afterPercent: formatPercent(props.after, section.name),
94+
afterAbsolute:
95+
getSectionByName(props.after, section.name)?.value?.toLocaleString() ??
96+
"??",
7897
color: getSectionColor(items.length),
7998
});
8099
}
@@ -92,63 +111,81 @@ function deactivate() {
92111
</script>
93112

94113
<template>
95-
<div class="wrapper">
96-
<div class="chart-wrapper">
97-
<div class="chart" v-for="([label, sections], rowIndex) in chartRows">
98-
<span class="label">{{ label }}</span>
99-
<div class="section-wrapper">
100-
<div
101-
v-for="(section, index) in sections.sections"
102-
:class="{section: true, active: activeSection === section.name}"
103-
@mouseenter="activate(section.name)"
104-
@mouseleave="deactivate"
105-
:style="{
106-
width: calculate_width(
107-
section.value,
108-
rowIndex == 0 ? beforeTotalWidth : afterTotalWidth
109-
),
110-
backgroundColor: getSectionColor(index),
111-
}"
112-
>
114+
<div>
115+
<div class="wrapper">
116+
<div class="chart-wrapper">
117+
<div class="chart" v-for="([label, sections], rowIndex) in chartRows">
118+
<span class="label">{{ label }}</span>
119+
<div class="section-wrapper">
113120
<div
114-
class="description"
115-
v-if="rowIndex == 1 && activeSection === section.name"
121+
v-for="(section, index) in sections.sections"
122+
:class="{section: true, active: activeSection === section.name}"
123+
@mouseenter="activate(section.name)"
124+
@mouseleave="deactivate"
125+
:style="{
126+
width: calculate_width(section.value, getRowWidth()),
127+
backgroundColor: getSectionColor(index),
128+
}"
116129
>
117-
<div>
118-
<b>{{ section.name }}</b>
119-
</div>
120-
<div>
130+
<div
131+
class="description"
132+
v-if="rowIndex == 1 && activeSection === section.name"
133+
>
121134
<div>
122-
{{ formatPercent(props.before, section.name) }} ->
123-
{{ formatPercent(props.after, section.name) }}
135+
<b>{{ section.name }}</b>
124136
</div>
125137
<div>
126-
{{
127-
getSectionByName(props.before, section.name)?.value ?? "??"
128-
}}
129-
->
130-
{{
131-
getSectionByName(props.after, section.name)?.value ?? "??"
132-
}}
138+
<div>
139+
{{ formatPercent(props.before, section.name) }} ->
140+
{{ formatPercent(props.after, section.name) }}
141+
</div>
142+
<div>
143+
{{
144+
getSectionByName(
145+
props.before,
146+
section.name
147+
)?.value?.toLocaleString() ?? "??"
148+
}}
149+
->
150+
{{
151+
getSectionByName(
152+
props.after,
153+
section.name
154+
)?.value.toLocaleString() ?? "??"
155+
}}
156+
</div>
133157
</div>
134158
</div>
135159
</div>
136160
</div>
137161
</div>
138162
</div>
139-
</div>
140-
<div class="legend">
141-
<div
142-
class="item"
143-
v-for="item in legendItems"
144-
@mouseenter="activate(item.section.name)"
145-
@mouseleave="deactivate"
146-
>
147-
<div
148-
:class="{color: true, active: activeSection === item.section.name}"
149-
:style="{backgroundColor: item.color}"
150-
></div>
151-
<div class="name">{{ item.label }}</div>
163+
<div class="legend">
164+
<table>
165+
<thead>
166+
<tr>
167+
<th></th>
168+
<th>Section</th>
169+
<th>Relative change</th>
170+
<th>Absolute change</th>
171+
</tr>
172+
</thead>
173+
<tbody>
174+
<tr
175+
v-for="item in legendItems"
176+
@mouseenter="activate(item.section.name)"
177+
@mouseleave="deactivate"
178+
:class="{active: activeSection === item.section.name}"
179+
>
180+
<td>
181+
<div class="color" :style="{backgroundColor: item.color}"></div>
182+
</td>
183+
<td class="name">{{ item.section.name }}</td>
184+
<td>{{ item.beforePercent }} -> {{ item.afterPercent }}</td>
185+
<td>{{ item.beforeAbsolute }} -> {{ item.afterAbsolute }}</td>
186+
</tr>
187+
</tbody>
188+
</table>
152189
</div>
153190
</div>
154191
</div>
@@ -162,7 +199,7 @@ function deactivate() {
162199
.chart {
163200
display: flex;
164201
justify-content: flex-end;
165-
width: 600px;
202+
width: 500px;
166203
167204
&:first-child {
168205
margin-bottom: 10px;
@@ -196,10 +233,6 @@ function deactivate() {
196233
}
197234
}
198235
199-
.active {
200-
box-shadow: inset 0 0 1px 2px #000;
201-
}
202-
203236
.section:first-child {
204237
border-radius: 5px 0 0 5px;
205238
}
@@ -210,17 +243,26 @@ function deactivate() {
210243
.legend {
211244
margin-left: 40px;
212245
213-
.item {
214-
display: flex;
215-
margin-bottom: 5px;
216-
217-
.color {
218-
width: 15px;
219-
height: 15px;
220-
}
221-
.name {
222-
margin-left: 5px;
246+
table {
247+
td,
248+
th {
249+
padding: 5px;
223250
}
224251
}
252+
.color {
253+
width: 15px;
254+
height: 15px;
255+
}
256+
.active {
257+
font-weight: bold;
258+
}
259+
.name {
260+
margin-left: 5px;
261+
}
262+
}
263+
264+
.active .color,
265+
.active.section {
266+
box-shadow: inset 0 0 1px 2px #000;
225267
}
226268
</style>

0 commit comments

Comments
 (0)