From b263d12e8521a5062296ffed61b834571e41c709 Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 08:40:59 +0100 Subject: [PATCH 01/10] Add icons to the chart tooltips --- .../carbon-estimation.component.ts | 20 ++++++++++++++++++- .../carbon-estimation.constants.ts | 13 ++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/app/carbon-estimation/carbon-estimation.component.ts b/src/app/carbon-estimation/carbon-estimation.component.ts index 77af83c8..65629cd8 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.ts @@ -123,7 +123,7 @@ export class CarbonEstimationComponent implements OnInit { Object.entries(emissions) // eslint-disable-next-line @typescript-eslint/no-unused-vars .filter(([_key, value]) => value !== 0) - .map(([key, value]) => ({ x: labelFunction(key), y: value })) + .map(([key, value]) => ({ x: labelFunction(key), y: value, meta: { svg: this.getSvg(key) } })) ); } @@ -191,4 +191,22 @@ export class CarbonEstimationComponent implements OnInit { const extraHeight = Number(extraHeightString) || 0; return innerHeight - this.estimatorBaseHeight - extraHeight - expansionPanelHeight; } + + private getSvg(key: string): string { + switch (key) { + case 'software': + return 'M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z'; + case 'user': + case 'endUser': + return 'M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z'; + case 'network': + return 'M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z'; + case 'server': + return 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z'; + case 'cloud': + return 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z'; + default: + return ''; + } + } } diff --git a/src/app/carbon-estimation/carbon-estimation.constants.ts b/src/app/carbon-estimation/carbon-estimation.constants.ts index 510b5436..c717911c 100644 --- a/src/app/carbon-estimation/carbon-estimation.constants.ts +++ b/src/app/carbon-estimation/carbon-estimation.constants.ts @@ -21,10 +21,15 @@ const customTooltip = ({ // eslint-disable-next-line @typescript-eslint/no-explicit-any w: any; }) => { - return `
-
${w.globals.initialSeries[seriesIndex].name.split(' -')[0]}:
-
${w.globals.initialSeries[seriesIndex].data[dataPointIndex].x} - - ${tooltipFormatter(series[seriesIndex][dataPointIndex])}
`; + const initialSeries = w.globals.initialSeries[seriesIndex]; + const data = initialSeries.data[dataPointIndex]; + + return `
+
+
+
${initialSeries.name.split(' -')[0]}:
+
${data.x} - + ${tooltipFormatter(series[seriesIndex][dataPointIndex])}
`; }; export const chartOptions: ChartOptions = { From 33445f0f4344cac3275ea5894bcaa440cb4a1ff1 Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 09:46:37 +0100 Subject: [PATCH 02/10] Remove tooltip border from apex chart component --- src/app/carbon-estimation/carbon-estimation.component.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/carbon-estimation/carbon-estimation.component.css b/src/app/carbon-estimation/carbon-estimation.component.css index b66ef6b3..49cc6ecd 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.css +++ b/src/app/carbon-estimation/carbon-estimation.component.css @@ -10,3 +10,7 @@ ::ng-deep .apexcharts-legend-series:hover { background-color: rgb(226 232 240); } + +::ng-deep .apexcharts-tooltip.apexcharts-theme-light { + border: none !important; +} From 2b61dab31a27b1bf1e27787eb1e7eecbbdddbced Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 09:47:17 +0100 Subject: [PATCH 03/10] Added mobile view styling for tooltip --- .../carbon-estimation/carbon-estimation.constants.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/carbon-estimation/carbon-estimation.constants.ts b/src/app/carbon-estimation/carbon-estimation.constants.ts index c717911c..456af145 100644 --- a/src/app/carbon-estimation/carbon-estimation.constants.ts +++ b/src/app/carbon-estimation/carbon-estimation.constants.ts @@ -24,11 +24,11 @@ const customTooltip = ({ const initialSeries = w.globals.initialSeries[seriesIndex]; const data = initialSeries.data[dataPointIndex]; - return `
-
-
-
${initialSeries.name.split(' -')[0]}:
-
${data.x} - + return `
+
+
+
${initialSeries.name.split(' -')[0]}:
+
${data.x} - ${tooltipFormatter(series[seriesIndex][dataPointIndex])}
`; }; From d5df3204300710dc32437ddb8115a590b22c144a Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 10:43:01 +0100 Subject: [PATCH 04/10] Fix estimator unit tests --- .../carbon-estimation.component.spec.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/app/carbon-estimation/carbon-estimation.component.spec.ts b/src/app/carbon-estimation/carbon-estimation.component.spec.ts index 6d50c656..5d6fb577 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.spec.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.spec.ts @@ -41,6 +41,10 @@ describe('CarbonEstimationComponent', () => { network: 12, }, }; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + spyOn(component as any, 'getSvg').and.callFake((key: string) => key); + fixture.componentRef.setInput('carbonEstimation', carbonEstimation); fixture.detectChanges(); @@ -114,18 +118,22 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 7, + meta: { svg: 'software' }, }, { x: 'User Hardware', y: 6, + meta: { svg: 'user' }, }, { x: 'Networking and Infrastructure Hardware', y: 6, + meta: { svg: 'network' }, }, { x: 'Servers and Storage Hardware', y: 6, + meta: { svg: 'server' }, }, ], }, @@ -136,14 +144,17 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 9, + meta: { svg: 'user' }, }, { x: 'Networking and Infrastructure', y: 8, + meta: { svg: 'network' }, }, { x: 'Servers and Storage', y: 8, + meta: { svg: 'server' }, }, ], }, @@ -154,14 +165,17 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 9, + meta: { svg: 'cloud' }, }, { x: 'SaaS', y: 8, + meta: { svg: 'saas' }, }, { x: 'Managed Services', y: 8, + meta: { svg: 'managed' }, }, ], }, @@ -172,10 +186,12 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 13, + meta: { svg: 'endUser' }, }, { x: 'Network Data Transfer', y: 12, + meta: { svg: 'network' }, }, ], }, @@ -255,6 +271,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 25, + meta: { svg: 'software' }, }, ], }, @@ -265,6 +282,7 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 25, + meta: { svg: 'user' }, }, ], }, @@ -275,6 +293,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 25, + meta: { svg: 'cloud' }, }, ], }, @@ -285,6 +304,7 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 25, + meta: { svg: 'endUser' }, }, ], }, @@ -329,6 +349,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 50, + meta: { svg: 'software' }, }, ], }, @@ -339,6 +360,7 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 50, + meta: { svg: 'user' }, }, ], }, From 00e42cd035a7c088188b3b27874b81eaaf91c13a Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 10:43:30 +0100 Subject: [PATCH 05/10] Add icons for all sub categories --- src/app/carbon-estimation/carbon-estimation.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/carbon-estimation/carbon-estimation.component.ts b/src/app/carbon-estimation/carbon-estimation.component.ts index 65629cd8..43f4617c 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.ts @@ -195,6 +195,7 @@ export class CarbonEstimationComponent implements OnInit { private getSvg(key: string): string { switch (key) { case 'software': + case 'saas': return 'M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z'; case 'user': case 'endUser': @@ -202,6 +203,7 @@ export class CarbonEstimationComponent implements OnInit { case 'network': return 'M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z'; case 'server': + case 'managed': return 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z'; case 'cloud': return 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z'; From de9b56aa3c534babe827eae3d0815d97e311158e Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 10:49:27 +0100 Subject: [PATCH 06/10] Change downstream network to networkTransfer --- .../carbon-estimation.component.spec.ts | 10 +++++----- .../carbon-estimation/carbon-estimation.component.ts | 4 +++- .../estimation/estimate-downstream-emissions.spec.ts | 12 ++++++------ src/app/estimation/estimate-downstream-emissions.ts | 4 ++-- .../tech-carbon-estimator.component.spec.ts | 2 +- src/app/types/carbon-estimator.ts | 2 +- 6 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/app/carbon-estimation/carbon-estimation.component.spec.ts b/src/app/carbon-estimation/carbon-estimation.component.spec.ts index 5d6fb577..b38ac3bb 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.spec.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.spec.ts @@ -38,7 +38,7 @@ describe('CarbonEstimationComponent', () => { }, downstreamEmissions: { endUser: 13, - network: 12, + networkTransfer: 12, }, }; @@ -191,7 +191,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Network Data Transfer', y: 12, - meta: { svg: 'network' }, + meta: { svg: 'networkTransfer' }, }, ], }, @@ -225,7 +225,7 @@ describe('CarbonEstimationComponent', () => { }, downstreamEmissions: { endUser: 13, - network: 12, + networkTransfer: 12, }, }; fixture.componentRef.setInput('carbonEstimation', carbonEstimation); @@ -256,7 +256,7 @@ describe('CarbonEstimationComponent', () => { }, downstreamEmissions: { endUser: 25, - network: 0, + networkTransfer: 0, }, }; fixture.componentRef.setInput('carbonEstimation', carbonEstimation); @@ -334,7 +334,7 @@ describe('CarbonEstimationComponent', () => { }, downstreamEmissions: { endUser: 0, - network: 0, + networkTransfer: 0, }, }; fixture.componentRef.setInput('carbonEstimation', carbonEstimation); diff --git a/src/app/carbon-estimation/carbon-estimation.component.ts b/src/app/carbon-estimation/carbon-estimation.component.ts index 43f4617c..b4037bdf 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.ts @@ -172,7 +172,7 @@ export class CarbonEstimationComponent implements OnInit { switch (key) { case 'endUser': return 'End-User Devices'; - case 'network': + case 'networkTransfer': return 'Network Data Transfer'; default: return startCase(key); @@ -207,6 +207,8 @@ export class CarbonEstimationComponent implements OnInit { return 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z'; case 'cloud': return 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z'; + case 'networkTransfer': + return 'M196-276q-57-60-86.5-133T80-560q0-78 29.5-151T196-844l48 48q-48 48-72 110.5T148-560q0 63 24 125.5T244-324l-48 48Zm96-96q-39-39-59.5-88T212-560q0-51 20.5-100t59.5-88l48 48q-30 27-45 64t-15 76q0 36 15 73t45 67l-48 48ZM280-80l135-405q-16-14-25.5-33t-9.5-42q0-42 29-71t71-29q42 0 71 29t29 71q0 23-9.5 42T545-485L680-80h-80l-26-80H387l-27 80h-80Zm133-160h134l-67-200-67 200Zm255-132-48-48q30-27 45-64t15-76q0-36-15-73t-45-67l48-48q39 39 58 88t22 100q0 51-20.5 100T668-372Zm96 96-48-48q48-48 72-110.5T812-560q0-63-24-125.5T716-796l48-48q57 60 86.5 133T880-560q0 78-28 151t-88 133Z'; default: return ''; } diff --git a/src/app/estimation/estimate-downstream-emissions.spec.ts b/src/app/estimation/estimate-downstream-emissions.spec.ts index 2af556e0..32e8a39b 100644 --- a/src/app/estimation/estimate-downstream-emissions.spec.ts +++ b/src/app/estimation/estimate-downstream-emissions.spec.ts @@ -12,7 +12,7 @@ describe('estimateDownstreamEmissions', () => { }; expect(estimateDownstreamEmissions(input)).toEqual({ endUser: 0, - network: 0, + networkTransfer: 0, }); }); @@ -28,31 +28,31 @@ describe('estimateDownstreamEmissions', () => { it('should return emissions for information site', () => { const result = estimateDownstreamEmissions(createInput('information')); expect(result.endUser).toBeCloseTo(0.50222); - expect(result.network).toBeCloseTo(0.0525016); + expect(result.networkTransfer).toBeCloseTo(0.0525016); }); it('should return emissions for e-commerce site', () => { const result = estimateDownstreamEmissions(createInput('eCommerce')); expect(result.endUser).toBeCloseTo(3.13888); - expect(result.network).toBeCloseTo(1.11322); + expect(result.networkTransfer).toBeCloseTo(1.11322); }); it('should return emissions for social media site', () => { const result = estimateDownstreamEmissions(createInput('socialMedia')); expect(result.endUser).toBeCloseTo(511.637); - expect(result.network).toBeCloseTo(298.761); + expect(result.networkTransfer).toBeCloseTo(298.761); }); it('should return emissions for streaming site', () => { const result = estimateDownstreamEmissions(createInput('streaming')); expect(result.endUser).toBeCloseTo(695.038); - expect(result.network).toBeCloseTo(698.533); + expect(result.networkTransfer).toBeCloseTo(698.533); }); it('should return emissions based on average values', () => { const result = estimateDownstreamEmissions(createInput('average')); expect(result.endUser).toBeCloseTo(302.579); - expect(result.network).toBeCloseTo(249.615); + expect(result.networkTransfer).toBeCloseTo(249.615); }); it('should create average equivalent to average of all other purposes', () => { diff --git a/src/app/estimation/estimate-downstream-emissions.ts b/src/app/estimation/estimate-downstream-emissions.ts index bf324200..2bd1f015 100644 --- a/src/app/estimation/estimate-downstream-emissions.ts +++ b/src/app/estimation/estimate-downstream-emissions.ts @@ -56,7 +56,7 @@ export const siteTypeInfo: Record = addAverage({ export function estimateDownstreamEmissions(downstream: Downstream): DownstreamEstimation { if (downstream.monthlyActiveUsers === 0) { - return { endUser: 0, network: 0 }; + return { endUser: 0, networkTransfer: 0 }; } const downstreamDataTransfer = estimateDownstreamDataTransfer( @@ -65,7 +65,7 @@ export function estimateDownstreamEmissions(downstream: Downstream): DownstreamE ); const endUserEmissions = estimateEndUserEmissions(downstream, downstreamDataTransfer); const networkEmissions = estimateNetworkEmissions(downstream, downstreamDataTransfer); - return { endUser: endUserEmissions, network: networkEmissions }; + return { endUser: endUserEmissions, networkTransfer: networkEmissions }; } function estimateDownstreamDataTransfer(monthlyActiveUsers: number, purposeOfSite: PurposeOfSite): Gb { diff --git a/src/app/tech-carbon-estimator/tech-carbon-estimator.component.spec.ts b/src/app/tech-carbon-estimator/tech-carbon-estimator.component.spec.ts index 409c5e43..bfd5d0f4 100644 --- a/src/app/tech-carbon-estimator/tech-carbon-estimator.component.spec.ts +++ b/src/app/tech-carbon-estimator/tech-carbon-estimator.component.spec.ts @@ -31,7 +31,7 @@ describe('TechCarbonEstimatorComponent', () => { }, downstreamEmissions: { endUser: 15, - network: 10, + networkTransfer: 10, }, }), }; diff --git a/src/app/types/carbon-estimator.ts b/src/app/types/carbon-estimator.ts index df4add3d..996da1e9 100644 --- a/src/app/types/carbon-estimator.ts +++ b/src/app/types/carbon-estimator.ts @@ -27,7 +27,7 @@ export type DirectEstimation = { }; export type DownstreamEstimation = { endUser: number; - network: number; + networkTransfer: number; }; export type EstimatorValues = { From 9e8e7fca0572cf57052689058eec4ed22f245cfc Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 14:56:02 +0100 Subject: [PATCH 07/10] Refactor how generate data items fro harts --- .../carbon-estimation.component.spec.ts | 23 +-- .../carbon-estimation.component.ts | 168 +++++++++--------- .../carbon-estimation.constants.ts | 16 ++ 3 files changed, 105 insertions(+), 102 deletions(-) diff --git a/src/app/carbon-estimation/carbon-estimation.component.spec.ts b/src/app/carbon-estimation/carbon-estimation.component.spec.ts index b38ac3bb..d128106d 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.spec.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.spec.ts @@ -43,7 +43,10 @@ describe('CarbonEstimationComponent', () => { }; // eslint-disable-next-line @typescript-eslint/no-explicit-any - spyOn(component as any, 'getSvg').and.callFake((key: string) => key); + spyOn(component as any, 'getDataItemObject').and.callFake((x: string, y: number) => ({ + x, + y, + })); fixture.componentRef.setInput('carbonEstimation', carbonEstimation); @@ -118,22 +121,18 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 7, - meta: { svg: 'software' }, }, { x: 'User Hardware', y: 6, - meta: { svg: 'user' }, }, { x: 'Networking and Infrastructure Hardware', y: 6, - meta: { svg: 'network' }, }, { x: 'Servers and Storage Hardware', y: 6, - meta: { svg: 'server' }, }, ], }, @@ -144,17 +143,14 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 9, - meta: { svg: 'user' }, }, { x: 'Networking and Infrastructure', y: 8, - meta: { svg: 'network' }, }, { x: 'Servers and Storage', y: 8, - meta: { svg: 'server' }, }, ], }, @@ -165,17 +161,14 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 9, - meta: { svg: 'cloud' }, }, { x: 'SaaS', y: 8, - meta: { svg: 'saas' }, }, { x: 'Managed Services', y: 8, - meta: { svg: 'managed' }, }, ], }, @@ -186,12 +179,10 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 13, - meta: { svg: 'endUser' }, }, { x: 'Network Data Transfer', y: 12, - meta: { svg: 'networkTransfer' }, }, ], }, @@ -271,7 +262,6 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 25, - meta: { svg: 'software' }, }, ], }, @@ -282,7 +272,6 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 25, - meta: { svg: 'user' }, }, ], }, @@ -293,7 +282,6 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 25, - meta: { svg: 'cloud' }, }, ], }, @@ -304,7 +292,6 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 25, - meta: { svg: 'endUser' }, }, ], }, @@ -349,7 +336,6 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 50, - meta: { svg: 'software' }, }, ], }, @@ -360,7 +346,6 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 50, - meta: { svg: 'user' }, }, ], }, diff --git a/src/app/carbon-estimation/carbon-estimation.component.ts b/src/app/carbon-estimation/carbon-estimation.component.ts index b4037bdf..8928f005 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.ts @@ -13,10 +13,23 @@ import { NumberObject, sumValues } from '../utils/number-object'; import { ApexAxisChartSeries, ChartComponent, NgApexchartsModule } from 'ng-apexcharts'; import { startCase } from 'lodash-es'; -import { EmissionsColours, chartOptions, estimatorHeights, tooltipFormatter } from './carbon-estimation.constants'; +import { + EmissionsColours, + EmissionsLabels, + SVG, + chartOptions, + estimatorHeights, + tooltipFormatter, +} from './carbon-estimation.constants'; import { ExpansionPanelComponent } from '../expansion-panel/expansion-panel.component'; -type ApexChartDataItem = { x: string; y: number }; +type ApexChartDataItem = { x: string; y: number; meta: { svg: string; parent: string } }; + +type ApexChartSeries = { + name: string; + color: string; + data: ApexChartDataItem[]; +}; @Component({ selector: 'carbon-estimation', @@ -42,7 +55,7 @@ export class CarbonEstimationComponent implements OnInit { constructor(private changeDetectorRef: ChangeDetectorRef) { effect(() => { this.emissions = this.getOverallEmissionPercentages(this.carbonEstimation()); - this.emissionAriaLabel = this.getAriaLabel(this.carbonEstimation()); + this.emissionAriaLabel = this.getAriaLabel(this.emissions); }); } @@ -69,41 +82,35 @@ export class CarbonEstimationComponent implements OnInit { private getOverallEmissionPercentages(carbonEstimation: CarbonEstimation): ApexAxisChartSeries { return [ { - name: `Upstream Emissions - ${this.getOverallPercentageLabel(carbonEstimation.upstreamEmissions)}`, + name: `${EmissionsLabels.Upstream} - ${this.getOverallPercentageLabel(carbonEstimation.upstreamEmissions)}`, color: EmissionsColours.Upstream, - data: this.getEmissionPercentages(carbonEstimation.upstreamEmissions, this.getUpstreamLabel), + data: this.getEmissionPercentages(carbonEstimation.upstreamEmissions, EmissionsLabels.Upstream), }, { - name: `Direct Emissions - ${this.getOverallPercentageLabel(carbonEstimation.directEmissions)}`, + name: `${EmissionsLabels.Direct} - ${this.getOverallPercentageLabel(carbonEstimation.directEmissions)}`, color: EmissionsColours.Direct, - data: this.getEmissionPercentages(carbonEstimation.directEmissions, this.getDirectLabel), + data: this.getEmissionPercentages(carbonEstimation.directEmissions, EmissionsLabels.Direct), }, { - name: `Indirect Emissions - ${this.getOverallPercentageLabel(carbonEstimation.indirectEmissions)}`, + name: `${EmissionsLabels.Indirect} - ${this.getOverallPercentageLabel(carbonEstimation.indirectEmissions)}`, color: EmissionsColours.Indirect, - data: this.getEmissionPercentages(carbonEstimation.indirectEmissions, this.getIndirectLabel), + data: this.getEmissionPercentages(carbonEstimation.indirectEmissions, EmissionsLabels.Indirect), }, { - name: `Downstream Emissions - ${this.getOverallPercentageLabel(carbonEstimation.downstreamEmissions)}`, + name: `${EmissionsLabels.Downstream} - ${this.getOverallPercentageLabel(carbonEstimation.downstreamEmissions)}`, color: EmissionsColours.Downstream, - data: this.getEmissionPercentages(carbonEstimation.downstreamEmissions, this.getDownstreamLabel), + data: this.getEmissionPercentages(carbonEstimation.downstreamEmissions, EmissionsLabels.Downstream), }, ].filter(entry => entry.data.length !== 0); } - private getAriaLabel(carbonEstimation: CarbonEstimation): string { - return `Estimation of emissions. ${this.getAriaLabelForCategory('Upstream', carbonEstimation.upstreamEmissions, this.getUpstreamLabel)} - ${this.getAriaLabelForCategory('Direct', carbonEstimation.directEmissions, this.getDirectLabel)} - ${this.getAriaLabelForCategory('Indirect', carbonEstimation.indirectEmissions, this.getIndirectLabel)} - ${this.getAriaLabelForCategory('Downstream', carbonEstimation.downstreamEmissions, this.getDownstreamLabel)}`; + private getAriaLabel(emission: ApexAxisChartSeries): string { + return `Estimation of emissions. ${emission.map(entry => this.getAriaLabelForCategory(entry as ApexChartSeries)).join(' ')}`; } - private getAriaLabelForCategory( - category: string, - emissions: NumberObject, - labelFunction: (key: string) => string - ): string { - return `${category} emissions are ${this.getOverallPercentageLabel(emissions)}${this.getEmissionMadeUp(this.getEmissionPercentages(emissions, labelFunction))}`; + private getAriaLabelForCategory(series: ApexChartSeries): string { + const category = series.name.replace('-', 'emissions are'); + return `${category}${this.getEmissionMadeUp(series.data)}`; } private getEmissionMadeUp(emission: ApexChartDataItem[]): string { @@ -118,99 +125,94 @@ export class CarbonEstimationComponent implements OnInit { return percentage < 1 ? '<1%' : Math.round(percentage) + '%'; }; - private getEmissionPercentages(emissions: NumberObject, labelFunction: (key: string) => string): ApexChartDataItem[] { + private getEmissionPercentages(emissions: NumberObject, parent: string): ApexChartDataItem[] { return ( Object.entries(emissions) // eslint-disable-next-line @typescript-eslint/no-unused-vars .filter(([_key, value]) => value !== 0) - .map(([key, value]) => ({ x: labelFunction(key), y: value, meta: { svg: this.getSvg(key) } })) + .map(([_key, value]) => this.getDataItem(_key, value, parent)) ); } - private getUpstreamLabel(key: string): string { - switch (key) { - case 'software': - return 'Software - Off the Shelf'; - case 'user': - return 'User Hardware'; - case 'network': - return 'Networking and Infrastructure Hardware'; - case 'server': - return 'Servers and Storage Hardware'; - default: - return startCase(key); + private getChartHeight(innerHeight: number, innerWidth: number): number { + const expansionPanelHeight = this.detailsPanel.nativeElement.clientHeight; + + // medium tailwind responsive design breakpoint https://tailwindcss.com/docs/responsive-design + if (innerWidth < 768) { + return innerHeight - this.estimatorBaseHeight - expansionPanelHeight + estimatorHeights.title; } + + const extraHeightString = this.extraHeight(); + const extraHeight = Number(extraHeightString) || 0; + return innerHeight - this.estimatorBaseHeight - extraHeight - expansionPanelHeight; } - private getDirectLabel(key: string): string { + private getDataItem(key: string, value: number, parent: string): ApexChartDataItem { switch (key) { + case 'software': + return this.getDataItemObject('Software - Off the Shelf', value, SVG.WEB, parent); + case 'saas': + return this.getDataItemObject('SaaS', value, SVG.WEB, parent); case 'user': - return 'User Devices'; + return this.getDataItemObject(this.getUserLabel(parent), value, SVG.DEVICES, parent); + case 'endUser': + return this.getDataItemObject('End-User Devices', value, SVG.DEVICES, parent); case 'network': - return 'Networking and Infrastructure'; + return this.getDataItemObject(this.getNetworkLabel(parent), value, SVG.ROUTER, parent); case 'server': - return 'Servers and Storage'; + return this.getDataItemObject(this.getServerLabel(parent), value, SVG.STORAGE, parent); + case 'managed': + return this.getDataItemObject('Managed Services', value, SVG.STORAGE, parent); + case 'cloud': + return this.getDataItemObject('Cloud Services', value, SVG.CLOUD, parent); + case 'networkTransfer': + return this.getDataItemObject('Network Data Transfer', value, SVG.CELL_TOWER, parent); default: - return startCase(key); + return this.getDataItemObject(startCase(key), value, '', parent); } } - private getIndirectLabel(key: string): string { + private getDataItemObject(x: string, y: number, svg: string, parent: string): ApexChartDataItem { + return { + x, + y, + meta: { + svg, + parent, + }, + }; + } + + private getUserLabel(key: string): string { switch (key) { - case 'cloud': - return 'Cloud Services'; - case 'saas': - return 'SaaS'; - case 'managed': - return 'Managed Services'; + case 'Upstream Emissions': + return 'User Hardware'; + case 'Direct Emissions': + return 'User Devices'; default: return startCase(key); } } - private getDownstreamLabel(key: string): string { + private getNetworkLabel(key: string): string { switch (key) { - case 'endUser': - return 'End-User Devices'; - case 'networkTransfer': - return 'Network Data Transfer'; + case 'Upstream Emissions': + return 'Networking and Infrastructure Hardware'; + case 'Direct Emissions': + return 'Networking and Infrastructure'; default: return startCase(key); } } - private getChartHeight(innerHeight: number, innerWidth: number): number { - const expansionPanelHeight = this.detailsPanel.nativeElement.clientHeight; - - // medium tailwind responsive design breakpoint https://tailwindcss.com/docs/responsive-design - if (innerWidth < 768) { - return innerHeight - this.estimatorBaseHeight - expansionPanelHeight + estimatorHeights.title; - } - - const extraHeightString = this.extraHeight(); - const extraHeight = Number(extraHeightString) || 0; - return innerHeight - this.estimatorBaseHeight - extraHeight - expansionPanelHeight; - } - - private getSvg(key: string): string { + private getServerLabel(key: string): string { switch (key) { - case 'software': - case 'saas': - return 'M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z'; - case 'user': - case 'endUser': - return 'M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z'; - case 'network': - return 'M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z'; - case 'server': - case 'managed': - return 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z'; - case 'cloud': - return 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z'; - case 'networkTransfer': - return 'M196-276q-57-60-86.5-133T80-560q0-78 29.5-151T196-844l48 48q-48 48-72 110.5T148-560q0 63 24 125.5T244-324l-48 48Zm96-96q-39-39-59.5-88T212-560q0-51 20.5-100t59.5-88l48 48q-30 27-45 64t-15 76q0 36 15 73t45 67l-48 48ZM280-80l135-405q-16-14-25.5-33t-9.5-42q0-42 29-71t71-29q42 0 71 29t29 71q0 23-9.5 42T545-485L680-80h-80l-26-80H387l-27 80h-80Zm133-160h134l-67-200-67 200Zm255-132-48-48q30-27 45-64t15-76q0-36-15-73t-45-67l48-48q39 39 58 88t22 100q0 51-20.5 100T668-372Zm96 96-48-48q48-48 72-110.5T812-560q0-63-24-125.5T716-796l48-48q57 60 86.5 133T880-560q0 78-28 151t-88 133Z'; + case 'Upstream Emissions': + return 'Servers and Storage Hardware'; + case 'Direct Emissions': + return 'Servers and Storage'; default: - return ''; + return startCase(key); } } } diff --git a/src/app/carbon-estimation/carbon-estimation.constants.ts b/src/app/carbon-estimation/carbon-estimation.constants.ts index 456af145..98ceefd9 100644 --- a/src/app/carbon-estimation/carbon-estimation.constants.ts +++ b/src/app/carbon-estimation/carbon-estimation.constants.ts @@ -89,3 +89,19 @@ export const estimatorHeights = { button: 40, chartExtra: 15, }; + +export enum SVG { + WEB = 'M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z', + DEVICES = 'M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z', + ROUTER = 'M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z', + STORAGE = 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z', + CLOUD = 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z', + CELL_TOWER = 'M196-276q-57-60-86.5-133T80-560q0-78 29.5-151T196-844l48 48q-48 48-72 110.5T148-560q0 63 24 125.5T244-324l-48 48Zm96-96q-39-39-59.5-88T212-560q0-51 20.5-100t59.5-88l48 48q-30 27-45 64t-15 76q0 36 15 73t45 67l-48 48ZM280-80l135-405q-16-14-25.5-33t-9.5-42q0-42 29-71t71-29q42 0 71 29t29 71q0 23-9.5 42T545-485L680-80h-80l-26-80H387l-27 80h-80Zm133-160h134l-67-200-67 200Zm255-132-48-48q30-27 45-64t15-76q0-36-15-73t-45-67l48-48q39 39 58 88t22 100q0 51-20.5 100T668-372Zm96 96-48-48q48-48 72-110.5T812-560q0-63-24-125.5T716-796l48-48q57 60 86.5 133T880-560q0 78-28 151t-88 133Z', +} + +export enum EmissionsLabels { + Upstream = 'Upstream Emissions', + Direct = 'Direct Emissions', + Indirect = 'Indirect Emissions', + Downstream = 'Downstream Emissions', +} From 61f79133633a26801de1fddfd34befc7ab6a3c31 Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 15:33:53 +0100 Subject: [PATCH 08/10] Refactor how icon are served --- .../carbon-estimation.component.css | 24 +++++++++++++++++++ .../carbon-estimation.component.spec.ts | 24 ++++++++++++++----- .../carbon-estimation.constants.ts | 16 ++++++------- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/app/carbon-estimation/carbon-estimation.component.css b/src/app/carbon-estimation/carbon-estimation.component.css index 49cc6ecd..489c1490 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.css +++ b/src/app/carbon-estimation/carbon-estimation.component.css @@ -14,3 +14,27 @@ ::ng-deep .apexcharts-tooltip.apexcharts-theme-light { border: none !important; } + +::ng-deep .web-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z'/%3E%3C/svg%3E"); +} + +::ng-deep .devices-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z'/%3E%3C/svg%3E"); +} + +::ng-deep .router-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z'/%3E%3C/svg%3E"); +} + +::ng-deep .storage-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z'/%3E%3C/svg%3E"); +} + +::ng-deep .cloud-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z'/%3E%3C/svg%3E"); +} + +::ng-deep .cell-tower-logo { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath style='fill:white' d='M196-276q-57-60-86.5-133T80-560q0-78 29.5-151T196-844l48 48q-48 48-72 110.5T148-560q0 63 24 125.5T244-324l-48 48Zm96-96q-39-39-59.5-88T212-560q0-51 20.5-100t59.5-88l48 48q-30 27-45 64t-15 76q0 36 15 73t45 67l-48 48ZM280-80l135-405q-16-14-25.5-33t-9.5-42q0-42 29-71t71-29q42 0 71 29t29 71q0 23-9.5 42T545-485L680-80h-80l-26-80H387l-27 80h-80Zm133-160h134l-67-200-67 200Zm255-132-48-48q30-27 45-64t15-76q0-36-15-73t-45-67l48-48q39 39 58 88t22 100q0 51-20.5 100T668-372Zm96 96-48-48q48-48 72-110.5T812-560q0-63-24-125.5T716-796l48-48q57 60 86.5 133T880-560q0 78-28 151t-88 133Z'/%3E%3C/svg%3E"); +} diff --git a/src/app/carbon-estimation/carbon-estimation.component.spec.ts b/src/app/carbon-estimation/carbon-estimation.component.spec.ts index d128106d..e0aa2ab5 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.spec.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.spec.ts @@ -42,12 +42,6 @@ describe('CarbonEstimationComponent', () => { }, }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - spyOn(component as any, 'getDataItemObject').and.callFake((x: string, y: number) => ({ - x, - y, - })); - fixture.componentRef.setInput('carbonEstimation', carbonEstimation); fixture.detectChanges(); @@ -121,18 +115,22 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 7, + meta: { svg: 'web-logo', parent: 'Upstream Emissions' }, }, { x: 'User Hardware', y: 6, + meta: { svg: 'devices-logo', parent: 'Upstream Emissions' }, }, { x: 'Networking and Infrastructure Hardware', y: 6, + meta: { svg: 'router-logo', parent: 'Upstream Emissions' }, }, { x: 'Servers and Storage Hardware', y: 6, + meta: { svg: 'storage-logo', parent: 'Upstream Emissions' }, }, ], }, @@ -143,14 +141,17 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 9, + meta: { svg: 'devices-logo', parent: 'Direct Emissions' }, }, { x: 'Networking and Infrastructure', y: 8, + meta: { svg: 'router-logo', parent: 'Direct Emissions' }, }, { x: 'Servers and Storage', y: 8, + meta: { svg: 'storage-logo', parent: 'Direct Emissions' }, }, ], }, @@ -161,14 +162,17 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 9, + meta: { svg: 'cloud-logo', parent: 'Indirect Emissions' }, }, { x: 'SaaS', y: 8, + meta: { svg: 'web-logo', parent: 'Indirect Emissions' }, }, { x: 'Managed Services', y: 8, + meta: { svg: 'storage-logo', parent: 'Indirect Emissions' }, }, ], }, @@ -179,10 +183,12 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 13, + meta: { svg: 'devices-logo', parent: 'Downstream Emissions' }, }, { x: 'Network Data Transfer', y: 12, + meta: { svg: 'cell-tower-logo', parent: 'Downstream Emissions' }, }, ], }, @@ -262,6 +268,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 25, + meta: { svg: 'web-logo', parent: 'Upstream Emissions' }, }, ], }, @@ -272,6 +279,7 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 25, + meta: { svg: 'devices-logo', parent: 'Direct Emissions' }, }, ], }, @@ -282,6 +290,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Cloud Services', y: 25, + meta: { svg: 'cloud-logo', parent: 'Indirect Emissions' }, }, ], }, @@ -292,6 +301,7 @@ describe('CarbonEstimationComponent', () => { { x: 'End-User Devices', y: 25, + meta: { svg: 'devices-logo', parent: 'Downstream Emissions' }, }, ], }, @@ -336,6 +346,7 @@ describe('CarbonEstimationComponent', () => { { x: 'Software - Off the Shelf', y: 50, + meta: { svg: 'web-logo', parent: 'Upstream Emissions' }, }, ], }, @@ -346,6 +357,7 @@ describe('CarbonEstimationComponent', () => { { x: 'User Devices', y: 50, + meta: { svg: 'devices-logo', parent: 'Direct Emissions' }, }, ], }, diff --git a/src/app/carbon-estimation/carbon-estimation.constants.ts b/src/app/carbon-estimation/carbon-estimation.constants.ts index 98ceefd9..8780bcfc 100644 --- a/src/app/carbon-estimation/carbon-estimation.constants.ts +++ b/src/app/carbon-estimation/carbon-estimation.constants.ts @@ -25,9 +25,9 @@ const customTooltip = ({ const data = initialSeries.data[dataPointIndex]; return `
-
+
-
${initialSeries.name.split(' -')[0]}:
+
${data.meta.parent}:
${data.x} - ${tooltipFormatter(series[seriesIndex][dataPointIndex])}
`; }; @@ -91,12 +91,12 @@ export const estimatorHeights = { }; export enum SVG { - WEB = 'M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm0-80h420v-140H160v140Zm500 0h140v-360H660v360ZM160-460h420v-140H160v140Z', - DEVICES = 'M80-160v-120h80v-440q0-33 23.5-56.5T240-800h600v80H240v440h240v120H80Zm520 0q-17 0-28.5-11.5T560-200v-400q0-17 11.5-28.5T600-640h240q17 0 28.5 11.5T880-600v400q0 17-11.5 28.5T840-160H600Zm40-120h160v-280H640v280Zm0 0h160-160Z', - ROUTER = 'M200-120q-33 0-56.5-23.5T120-200v-160q0-33 23.5-56.5T200-440h400v-160h80v160h80q33 0 56.5 23.5T840-360v160q0 33-23.5 56.5T760-120H200Zm0-80h560v-160H200v160Zm80-40q17 0 28.5-11.5T320-280q0-17-11.5-28.5T280-320q-17 0-28.5 11.5T240-280q0 17 11.5 28.5T280-240Zm140 0q17 0 28.5-11.5T460-280q0-17-11.5-28.5T420-320q-17 0-28.5 11.5T380-280q0 17 11.5 28.5T420-240Zm140 0q17 0 28.5-11.5T600-280q0-17-11.5-28.5T560-320q-17 0-28.5 11.5T520-280q0 17 11.5 28.5T560-240Zm10-390-58-58q26-24 58-38t70-14q38 0 70 14t58 38l-58 58q-14-14-31.5-22t-38.5-8q-21 0-38.5 8T570-630ZM470-730l-56-56q44-44 102-69t124-25q66 0 124 25t102 69l-56 56q-33-33-76.5-51.5T640-800q-50 0-93.5 18.5T470-730ZM200-200v-160 160Z', - STORAGE = 'M120-160v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80-440v-160h720v160H120Zm80-40h80v-80h-80v80Zm-80 280v-160h720v160H120Zm80-40h80v-80h-80v80Z', - CLOUD = 'M260-160q-91 0-155.5-63T40-377q0-78 47-139t123-78q25-92 100-149t170-57q117 0 198.5 81.5T760-520q69 8 114.5 59.5T920-340q0 75-52.5 127.5T740-160H260Zm0-80h480q42 0 71-29t29-71q0-42-29-71t-71-29h-60v-80q0-83-58.5-141.5T480-720q-83 0-141.5 58.5T280-520h-20q-58 0-99 41t-41 99q0 58 41 99t99 41Zm220-240Z', - CELL_TOWER = 'M196-276q-57-60-86.5-133T80-560q0-78 29.5-151T196-844l48 48q-48 48-72 110.5T148-560q0 63 24 125.5T244-324l-48 48Zm96-96q-39-39-59.5-88T212-560q0-51 20.5-100t59.5-88l48 48q-30 27-45 64t-15 76q0 36 15 73t45 67l-48 48ZM280-80l135-405q-16-14-25.5-33t-9.5-42q0-42 29-71t71-29q42 0 71 29t29 71q0 23-9.5 42T545-485L680-80h-80l-26-80H387l-27 80h-80Zm133-160h134l-67-200-67 200Zm255-132-48-48q30-27 45-64t15-76q0-36-15-73t-45-67l48-48q39 39 58 88t22 100q0 51-20.5 100T668-372Zm96 96-48-48q48-48 72-110.5T812-560q0-63-24-125.5T716-796l48-48q57 60 86.5 133T880-560q0 78-28 151t-88 133Z', + WEB = 'web-logo', + DEVICES = 'devices-logo', + ROUTER = 'router-logo', + STORAGE = 'storage-logo', + CLOUD = 'cloud-logo', + CELL_TOWER = 'cell-tower-logo', } export enum EmissionsLabels { From 8c5a94346cab588f1c3f30f270af7645b67869bc Mon Sep 17 00:00:00 2001 From: Jareth Main Date: Thu, 25 Apr 2024 15:39:59 +0100 Subject: [PATCH 09/10] Update doc with networkTransfer --- docs/types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/types.md b/docs/types.md index b0024bb9..25a27bc6 100644 --- a/docs/types.md +++ b/docs/types.md @@ -138,7 +138,7 @@ classDiagram } class DownstreamEstimation { endUser: number; - network: number; + networkTransfer: number; } ``` @@ -202,4 +202,4 @@ multiplyValues(input: T, factor: number): T Multiplies every number in the object by the given factor, returning the same type as the input. -These are used at the end of the estimation process to calculate totals and scale the estimations from Kg CO2e to percentages. \ No newline at end of file +These are used at the end of the estimation process to calculate totals and scale the estimations from Kg CO2e to percentages. From bd9f4fe2e531534d1e1574dd90126598f7172588 Mon Sep 17 00:00:00 2001 From: jmain-scottlogic <131965549+jmain-scottlogic@users.noreply.github.com> Date: Thu, 25 Apr 2024 17:16:04 +0100 Subject: [PATCH 10/10] Update src/app/carbon-estimation/carbon-estimation.component.ts to remove duplicate emissions Co-authored-by: Matthew Griffin <117279304+mgriffin-scottlogic@users.noreply.github.com> --- src/app/carbon-estimation/carbon-estimation.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/carbon-estimation/carbon-estimation.component.ts b/src/app/carbon-estimation/carbon-estimation.component.ts index 8928f005..5a1aeac7 100644 --- a/src/app/carbon-estimation/carbon-estimation.component.ts +++ b/src/app/carbon-estimation/carbon-estimation.component.ts @@ -109,7 +109,7 @@ export class CarbonEstimationComponent implements OnInit { } private getAriaLabelForCategory(series: ApexChartSeries): string { - const category = series.name.replace('-', 'emissions are'); + const category = series.name.replace('-', 'are'); return `${category}${this.getEmissionMadeUp(series.data)}`; }