|
4 | 4 | */
|
5 | 5 | class PhaseMetrics extends HTMLElement {
|
6 | 6 | 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> |
25 | 44 | </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> |
35 | 50 | </div>
|
36 | 51 | </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> |
120 | 52 | </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('')} |
121 | 60 | </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> |
122 | 69 | </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')} |
141 | 74 | </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> |
160 | 77 | </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('')} |
166 | 80 | </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> |
176 | 96 | </div>
|
177 |
| - </div>`; |
| 97 | + `; |
| 98 | + |
| 99 | + $(this).find('.menu .item').tab(); |
178 | 100 | }
|
179 | 101 | }
|
180 | 102 |
|
@@ -364,37 +286,45 @@ const calculateCO2 = (phase, total_CO2_in_ug) => {
|
364 | 286 | const updateKeyMetric = (phase, metric_name, clean_name, detail_name, value, std_dev_text, unit, raw_value, raw_unit, explanation, source) => {
|
365 | 287 |
|
366 | 288 | 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'; |
378 | 292 | } 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'; |
384 | 296 | } 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 | + } |
386 | 313 | }
|
387 | 314 |
|
| 315 | + if(selector === null) return; // could not match key metric |
388 | 316 |
|
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; |
390 | 319 |
|
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}]`); |
392 | 323 |
|
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; |
396 | 326 |
|
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'); |
399 | 329 |
|
400 | 330 | }
|
0 commit comments