Skip to content

Commit 327bf39

Browse files
committed
Generate metric cards dynamically
1 parent c4faf40 commit 327bf39

File tree

1 file changed

+115
-185
lines changed

1 file changed

+115
-185
lines changed

frontend/js/helpers/metric-boxes.js

Lines changed: 115 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -4,177 +4,99 @@
44
*/
55
class PhaseMetrics extends HTMLElement {
66
connectedCallback() {
7-
this.innerHTML = `
8-
<h3 class="ui dividing header print-page-break">Key metrics</h3>
9-
<div class="ui four cards stackable">
10-
<div class="ui card phase-duration">
11-
<div class="ui content">
12-
<div class="ui top attached purple label overflow-ellipsis">Phase Duration <span class="si-unit"></span></div>
13-
<div class="description">
14-
<div class="ui fluid mini statistic">
15-
<div class="value">
16-
<i class="clock icon"></i> <span>N/A</span>
17-
</div>
18-
</div>
19-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="Duration of the phase.">
20-
<i class="question circle icon"></i>
21-
</div>
22-
<div class="ui bottom left attached label">
23-
<span class="metric-type"></span>
24-
</div>
7+
const tabCards = {
8+
power: [
9+
{ key: 'cpu', name: 'CPU', icon: 'microchip' },
10+
{ key: 'dram', name: 'DRAM', icon: 'memory' },
11+
{ key: 'gpu', name: 'GPU', icon: 'camera retro' },
12+
{ key: 'disk', name: 'Disk', icon: 'hdd' },
13+
{ key: 'machine', name: 'Machine', icon: 'power off' },
14+
],
15+
energy: [
16+
{ key: 'cpu', name: 'CPU', icon: 'microchip' },
17+
{ key: 'dram', name: 'DRAM', icon: 'memory' },
18+
{ key: 'gpu', name: 'GPU', icon: 'camera retro' },
19+
{ key: 'disk', name: 'Disk', icon: 'hdd' },
20+
{ key: 'machine', name: 'Machine', icon: 'battery three quarters' },
21+
],
22+
co2: [
23+
{ key: 'cpu', name: 'CPU', icon: 'microchip' },
24+
{ key: 'dram', name: 'DRAM', icon: 'memory' },
25+
{ key: 'gpu', name: 'GPU', icon: 'camera retro' },
26+
{ key: 'disk', name: 'Disk', icon: 'hdd' },
27+
{ key: 'machine', name: 'Machine', icon: 'burn' },
28+
],
29+
};
30+
31+
const extraCards = [
32+
{ key: 'runtime', name: 'Runtime', icon: 'clock' },
33+
{ key: 'sci', name: 'SCI', icon: 'leaf' },
34+
{ key: 'network', name: 'Network', icon: 'wifi' },
35+
];
36+
37+
const createCard = ({ key, name, icon }, suffix = '') => {
38+
const cardClass = suffix ? `${key}-${suffix}` : key;
39+
return `
40+
<div class="ui card ${cardClass}">
41+
<div class="content">
42+
<i class="${icon} icon"></i><b>${name}</b>
43+
<div class="right floated meta si-unit"></div>
2544
</div>
26-
</div>
27-
</div>
28-
<div class="ui card machine-power">
29-
<div class="ui content">
30-
<div class="ui top attached orange label overflow-ellipsis">Machine Power <span class="si-unit"></span></div>
31-
<div class="description">
32-
<div class="ui fluid mini statistic">
33-
<div class="value">
34-
<i class="power off icon"></i> <span>N/A</span>
45+
<div class="extra content">
46+
<div class="description">
47+
<span class="value">N/A</span>
48+
<div class="right floated meta help" data-tooltip="No data available" data-position="bottom right" data-inverted>
49+
<i class="question circle outline icon"></i>
3550
</div>
3651
</div>
37-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="Power of all hardware components during current usage phase.">
38-
<span class="source"></span>
39-
<i class="question circle icon"></i>
40-
</div>
41-
<div class="ui bottom left attached label">
42-
<span class="metric-type"></span>
43-
</div>
44-
</div>
45-
</div>
46-
</div>
47-
<div class="ui card machine-energy">
48-
<div class="ui content">
49-
<div class="ui top attached blue label overflow-ellipsis">Machine Energy <span class="si-unit"></span></div>
50-
<div class="description">
51-
<div class="ui fluid mini statistic">
52-
<div class="value">
53-
<i class="battery three quarters icon"></i> <span>N/A</span>
54-
</div>
55-
</div>
56-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="Energy of all hardware components during current usage phase.">
57-
<span class="source"></span>
58-
<i class="question circle icon"></i>
59-
</div>
60-
<div class="ui bottom left attached label">
61-
<span class="metric-type"></span>
62-
</div>
63-
</div>
64-
</div>
65-
</div>
66-
<div class="ui card network-energy">
67-
<div class="ui content">
68-
<div class="ui top blue attached label overflow-ellipsis">Network Transmission Energy<span class="si-unit"></span></div>
69-
<div class="description">
70-
<div class="ui fluid mini statistic">
71-
<div class="value">
72-
<i class="battery three quarters icon"></i> <span>N/A</span>
73-
</div>
74-
</div>
75-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="Estimated external energy cost for network infrastructure. See details under formula.">
76-
<u><a href="https://www.green-coding.io/co2-formulas/">via Formula</a></u>
77-
<i class="question circle icon"></i>
78-
</div>
79-
<div class="ui bottom left attached label">
80-
<span class="metric-type"></span>
81-
</div>
82-
</div>
83-
</div>
84-
</div>
85-
<div class="ui card machine-co2">
86-
<div class="ui content">
87-
<div class="ui top black attached label overflow-ellipsis">Machine CO<sub>2</sub> (usage) <span class="si-unit"></span></div>
88-
<div class="description">
89-
<div class="ui fluid mini statistic">
90-
<div class="value">
91-
<i class="burn icon"></i> <span>N/A</span>
92-
</div>
93-
</div>
94-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="CO2 cost of usage phase">
95-
<u><a href="https://www.green-coding.io/co2-formulas/">via Formula</a></u>
96-
<i class="question circle icon"></i>
97-
</div>
98-
<div class="ui bottom left attached label">
99-
<span class="metric-type"></span>
100-
</div>
101-
</div>
102-
</div>
103-
</div>
104-
<div class="ui card network-co2">
105-
<div class="ui content">
106-
<div class="ui top black attached label overflow-ellipsis">Network Transmission CO2 <span class="si-unit"></span></div>
107-
<div class="description">
108-
<div class="ui fluid mini statistic">
109-
<div class="value">
110-
<i class="burn icon"></i> <span>N/A</span>
111-
</div>
112-
</div>
113-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="Estimated external CO2 cost for network infrastructure. See details under formula.">
114-
<u><a href="https://www.green-coding.io/co2-formulas/">via Formula</a></u>
115-
<i class="question circle icon"></i>
116-
</div>
117-
<div class="ui bottom left attached label">
118-
<span class="metric-type"></span>
119-
</div>
12052
</div>
53+
</div>`;
54+
};
55+
56+
const buildTab = (tab, active = false) => `
57+
<div class="ui tab ${active ? 'active' : ''}" data-tab="${tab}">
58+
<div class="ui five cards stackable">
59+
${tabCards[tab].map(card => createCard(card, tab)).join('')}
12160
</div>
61+
</div>`;
62+
63+
this.innerHTML = `
64+
<h3 class="ui dividing header print-page-break">Metrics Overview</h3>
65+
<div class="ui top attached tabular menu">
66+
<a class="item active" data-tab="power">Power</a>
67+
<a class="item" data-tab="energy">Energy</a>
68+
<a class="item" data-tab="co2">CO<sub>2</sub></a>
12269
</div>
123-
<div class="ui card embodied-carbon">
124-
<div class="ui content">
125-
<div class="ui top black attached label overflow-ellipsis">Machine CO<sub>2</sub> (manufacturing) <span class="si-unit"></span></div>
126-
<div class="description">
127-
<div class="ui fluid mini statistic">
128-
<div class="value">
129-
<i class="burn icon"></i> <span>N/A</span>
130-
</div>
131-
</div>
132-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="CO2 (manufacturing) attr. to lifetime share of phase duration.">
133-
<u><a href="https://www.green-coding.io/co2-formulas/">via Formula</a></u>
134-
<i class="question circle icon"></i>
135-
</div>
136-
<div class="ui bottom left attached label">
137-
<span class="metric-type"></span>
138-
</div>
139-
</div>
140-
</div>
70+
<div class="ui bottom attached segment">
71+
${buildTab('power', true)}
72+
${buildTab('energy')}
73+
${buildTab('co2')}
14174
</div>
142-
<div class="ui card software-carbon-intensity">
143-
<div class="ui content">
144-
<div class="ui top black attached label overflow-ellipsis">SCI</sub> <span class="si-unit"></span></div>
145-
<div class="description">
146-
<div class="ui fluid mini statistic">
147-
<div class="value">
148-
<i class="burn icon"></i> <span>N/A</span>
149-
</div>
150-
</div>
151-
<div class="ui bottom right attached label icon" data-position="bottom right" data-inverted="" data-tooltip="SCI by the Green Software Foundation">
152-
<u><a href="https://docs.green-coding.io/docs/measuring/sci/">see Details</a></u>
153-
<i class="question circle icon"></i>
154-
</div>
155-
<div class="ui bottom left attached label">
156-
<span class="metric-type"></span>
157-
</div>
158-
</div>
159-
</div>
75+
<div class="ui warning message hidden">
76+
<ul></ul>
16077
</div>
161-
</div><!-- end ui three cards stackable -->
162-
<br>
163-
<div class="ui accordion">
164-
<div class="title ui header">
165-
<i class="dropdown icon"></i> <a><u>Click here for detailed metrics ...</u></a>
78+
<div class="ui three cards stackable">
79+
${extraCards.map(card => createCard(card)).join('')}
16680
</div>
167-
<div class="content">
168-
<h3 class="ui dividing header">Detailed metrics</h3>
169-
<table class="ui celled table compare-metrics-table sortable">
170-
<thead></thead>
171-
<tbody></tbody>
172-
</table>
173-
<co2-tangible></co2-tangible>
174-
<h3 class="ui dividing header hide-for-single-stats">Detailed Charts</h3>
175-
<div class="compare-chart-container"></div>
81+
<br>
82+
<div class="ui accordion">
83+
<div class="title ui header">
84+
<i class="dropdown icon"></i> <a><u>Click here for detailed metrics ...</u></a>
85+
</div>
86+
<div class="content">
87+
<h3 class="ui dividing header">Detailed metrics</h3>
88+
<table class="ui celled table compare-metrics-table sortable">
89+
<thead></thead>
90+
<tbody></tbody>
91+
</table>
92+
<co2-tangible></co2-tangible>
93+
<h3 class="ui dividing header hide-for-single-stats">Detailed Charts</h3>
94+
<div class="compare-chart-container"></div>
95+
</div>
17696
</div>
177-
</div>`;
97+
`;
98+
99+
$(this).find('.menu .item').tab();
178100
}
179101
}
180102

@@ -364,37 +286,45 @@ const calculateCO2 = (phase, total_CO2_in_ug) => {
364286
const updateKeyMetric = (phase, metric_name, clean_name, detail_name, value, std_dev_text, unit, raw_value, raw_unit, explanation, source) => {
365287

366288
let selector = null;
367-
// key metrics are already there, cause we want a fixed order, so we just replace
368-
if(machine_energy_metric_condition(metric_name)) {
369-
selector = '.machine-energy';
370-
} else if(network_energy_metric_condition(metric_name)) {
371-
selector = '.network-energy';
372-
} else if(phase_time_metric_condition(metric_name)) {
373-
selector = '.phase-duration';
374-
} else if(network_carbon_metric_condition(metric_name)) {
375-
selector = '.network-co2';
376-
} else if(embodied_carbon_share_metric_condition(metric_name)) {
377-
selector = '.embodied-carbon';
289+
290+
if(phase_time_metric_condition(metric_name)) {
291+
selector = '.runtime';
378292
} else if(sci_metric_condition(metric_name)) {
379-
selector = '.software-carbon-intensity';
380-
} else if(machine_power_metric_condition(metric_name)) {
381-
selector = '.machine-power';
382-
} else if(psu_machine_carbon_metric_condition(metric_name)) {
383-
selector = '.machine-co2';
293+
selector = '.sci';
294+
} else if(network_energy_metric_condition(metric_name)) {
295+
selector = '.network';
384296
} else {
385-
return; // could not match key metric
297+
const isPower = metric_name.indexOf('_power_') !== -1;
298+
const isEnergy = metric_name.indexOf('_energy_') !== -1;
299+
const isCO2 = metric_name.indexOf('_carbon_') !== -1;
300+
301+
let component = null;
302+
if(metric_name.indexOf('cpu') !== -1) component = 'cpu';
303+
else if(metric_name.indexOf('memory') !== -1) component = 'dram';
304+
else if(metric_name.indexOf('gpu') !== -1) component = 'gpu';
305+
else if(metric_name.indexOf('disk') !== -1) component = 'disk';
306+
else if(metric_name.indexOf('psu') !== -1 || metric_name.indexOf('machine') !== -1) component = 'machine';
307+
308+
if(component !== null) {
309+
if(isPower) selector = `.${component}-power`;
310+
else if(isEnergy) selector = `.${component}-energy`;
311+
else if(isCO2) selector = `.${component}-co2`;
312+
}
386313
}
387314

315+
if(selector === null) return; // could not match key metric
388316

389-
document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .value span`).innerText = `${value} ${std_dev_text}`
317+
const card = document.querySelector(`div.tab[data-tab='${phase}'] ${selector}`);
318+
if(!card) return;
390319

391-
document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .value`).setAttribute('title', `${raw_value} [${raw_unit}]`)
320+
const valueNode = card.querySelector('.value');
321+
valueNode.innerText = `${value} ${std_dev_text}`;
322+
valueNode.setAttribute('title', `${raw_value} [${raw_unit}]`);
392323

393-
document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .si-unit`).innerText = `[${unit}]`
394-
if(std_dev_text != '') document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .metric-type`).innerText = `(AVG + STD.DEV)`;
395-
else if(String(value).indexOf('%') !== -1) document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .metric-type`).innerText = `(Diff. in %)`;
324+
const unitNode = card.querySelector('.si-unit');
325+
if(unitNode) unitNode.innerText = unit;
396326

397-
node = document.querySelector(`div.tab[data-tab='${phase}'] ${selector} .source`)
398-
if (node !== null) node.innerText = source // not every key metric shall have a custom detail_name
327+
const helpNode = card.querySelector('.help');
328+
if(helpNode) helpNode.setAttribute('data-tooltip', explanation || 'No data available');
399329

400330
}

0 commit comments

Comments
 (0)