@@ -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+
2125const 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+
6169const chartRows: ComputedRef <Array <[string , CompilationSections ]>> = computed (
6270 () => [
6371 [" Before" , props .before ],
6472 [" After" , props .after ],
6573 ]
6674);
6775const 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 : 600 px ;
202+ width : 500 px ;
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