Skip to content

Commit

Permalink
Merge pull request #104 from ScottLogic/SFD-113-diagram-placeholder
Browse files Browse the repository at this point in the history
SFD-113: Display a placeholder for the diagram before it is shown
  • Loading branch information
sdun-scottlogic authored Jul 17, 2024
2 parents a1f5af8 + 0ed4427 commit 01a0881
Show file tree
Hide file tree
Showing 16 changed files with 238 additions and 180 deletions.
20 changes: 12 additions & 8 deletions src/app/carbon-estimation/carbon-estimation.component.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
::ng-deep .apexcharts-legend-series {
::ng-deep .apexcharts-legend-series {
cursor: default !important;
min-width: 250px;
margin-left: 0 !important;
}
::ng-deep .apexcharts-legend {
::ng-deep .apexcharts-legend {
padding: 0 !important;
}

Expand All @@ -16,25 +16,29 @@
}

::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");
background-image: url('../../assets/web.svg');
}

::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");
background-image: url('../../assets/devices.svg');
}

::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");
background-image: url('../../assets/router.svg');
}

::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");
background-image: url('../../assets/storage.svg');
}

::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");
background-image: url('../../assets/cloud.svg');
}

::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");
background-image: url('../../assets/cell-tower.svg');
}

::ng-deep .question-mark-logo {
background-image: url('../../assets/question-mark.svg');
}
16 changes: 8 additions & 8 deletions src/app/carbon-estimation/carbon-estimation.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ <h2 class="tce-text-2xl">Estimations</h2>
</p>
</div>
</expansion-panel>
<div [attr.aria-label]="emissionAriaLabel" role="presentation" tabindex="0">
<div [attr.aria-label]="emissionAriaLabel()" role="presentation" tabindex="0">
<apx-chart
#chart
aria-hidden="true"
[series]="emissions"
[chart]="chartOptions.chart"
[plotOptions]="chartOptions.plotOptions"
[legend]="chartOptions.legend"
[states]="chartOptions.states"
[dataLabels]="chartOptions.dataLabels"
[tooltip]="chartOptions.tooltip"></apx-chart>
[series]="chartData()"
[chart]="chartOptions().chart"
[plotOptions]="chartOptions().plotOptions"
[legend]="chartOptions().legend"
[states]="chartOptions().states"
[dataLabels]="chartOptions().dataLabels"
[tooltip]="chartOptions().tooltip"></apx-chart>
</div>
</div>
25 changes: 10 additions & 15 deletions src/app/carbon-estimation/carbon-estimation.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,11 @@ describe('CarbonEstimationComponent', () => {
fixture.detectChanges();
});

it('should set the chart height when the component is initialised', () => {
spyOnProperty(window, 'innerHeight').and.returnValue(1000);
spyOnProperty(window, 'innerWidth').and.returnValue(1000);
spyOnProperty(window.screen, 'height').and.returnValue(1080);
spyOnProperty(component.detailsPanel.nativeElement, 'clientHeight').and.returnValue(200);

component.ngOnInit();
fixture.detectChanges();

expect(component.chartOptions.chart.height).toBe(1000 - estimatorBaseHeight - 200);
it('should set the chart height when the component is rendered', () => {
// Check that the height is set to a positive value.
// (Checking for a specific value would require spying on the window object before
// the test starts for consistent local and CI/CD results.)
expect(component.chartOptions().chart.height).toBeGreaterThan(0);
});

it('should subtract the extraHeight input from the chart height on laptop screens', () => {
Expand Down Expand Up @@ -224,11 +219,11 @@ describe('CarbonEstimationComponent', () => {
},
];

expect(component.emissions).toEqual(expectedEmissions);
expect(component.chartData()).toEqual(expectedEmissions);
});

it('should have detailed aria label', () => {
expect(component.emissionAriaLabel.length).toBeGreaterThan(25);
expect(component.emissionAriaLabel().length).toBeGreaterThan(25);
});

it('should set label to <1% if emission is less than 1', () => {
Expand Down Expand Up @@ -259,7 +254,7 @@ describe('CarbonEstimationComponent', () => {

fixture.detectChanges();

expect(component.emissions[0].name).toBe('Upstream Emissions - <1%');
expect(component.chartData()[0].name).toBe('Upstream Emissions - <1%');
});

it('should remove categories when they are 0', () => {
Expand Down Expand Up @@ -337,7 +332,7 @@ describe('CarbonEstimationComponent', () => {
},
];

expect(component.emissions).toEqual(expectedEmissions);
expect(component.chartData()).toEqual(expectedEmissions);
});

it('should remove parent categories when all values are 0', () => {
Expand Down Expand Up @@ -393,6 +388,6 @@ describe('CarbonEstimationComponent', () => {
},
];

expect(component.emissions).toEqual(expectedEmissions);
expect(component.chartData()).toEqual(expectedEmissions);
});
});
55 changes: 27 additions & 28 deletions src/app/carbon-estimation/carbon-estimation.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild, effect, input } from '@angular/core';
import { CarbonEstimation, ChartOptions } from '../types/carbon-estimator';
import { ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild, computed, input } from '@angular/core';
import { CarbonEstimation } from '../types/carbon-estimator';
import { NumberObject, sumValues } from '../utils/number-object';
import { ApexAxisChartSeries, ChartComponent, NgApexchartsModule } from 'ng-apexcharts';

Expand All @@ -8,21 +8,16 @@ import {
EmissionsColours,
EmissionsLabels,
SVG,
chartOptions,
getBaseChartOptions,
estimatorHeights,
tooltipFormatter,
placeholderData,
ApexChartSeriesItem,
ApexChartDataItem,
} from './carbon-estimation.constants';
import { ExpansionPanelComponent } from '../expansion-panel/expansion-panel.component';
import { Subscription, debounceTime, fromEvent } from 'rxjs';

type ApexChartDataItem = { x: string; y: number; meta: { svg: string; parent: string } };

type ApexChartSeries = {
name: string;
color: string;
data: ApexChartDataItem[];
};

@Component({
selector: 'carbon-estimation',
standalone: true,
Expand All @@ -31,13 +26,13 @@ type ApexChartSeries = {
styleUrls: ['./carbon-estimation.component.css'],
})
export class CarbonEstimationComponent implements OnInit, OnDestroy {
public carbonEstimation = input.required<CarbonEstimation>();
public carbonEstimation = input<CarbonEstimation>();
public extraHeight = input<string>();

public emissions: ApexAxisChartSeries = [];
public emissionAriaLabel = 'Estimations of emissions.';
public chartData = computed(() => this.getChartData(this.carbonEstimation()));
public emissionAriaLabel = computed(() => this.getEmissionAriaLabel(this.chartData(), !this.carbonEstimation()));

public chartOptions: ChartOptions = chartOptions;
public chartOptions = computed(() => this.getChartOptions(!this.carbonEstimation()));
private tooltipFormatter = tooltipFormatter;
private estimatorBaseHeight = sumValues(estimatorHeights);

Expand All @@ -46,19 +41,9 @@ export class CarbonEstimationComponent implements OnInit, OnDestroy {
@ViewChild('chart') chart: ChartComponent | undefined;
@ViewChild('detailsPanel', { static: true, read: ElementRef }) detailsPanel!: ElementRef;

constructor(private changeDetectorRef: ChangeDetectorRef) {
effect(() => {
this.emissions = this.getOverallEmissionPercentages(this.carbonEstimation());
this.emissionAriaLabel = this.getAriaLabel(this.emissions);
});
}
constructor(private changeDetectorRef: ChangeDetectorRef) {}

public ngOnInit(): void {
const chartHeight = this.getChartHeight(window.innerHeight, window.innerWidth, window.screen.height);
if (chartHeight > 0) {
this.chartOptions.chart.height = chartHeight;
}

this.resizeSubscription = fromEvent(window, 'resize')
.pipe(debounceTime(500))
.subscribe(() => this.onResize(window.innerHeight, window.innerWidth, window.screen.height));
Expand Down Expand Up @@ -104,10 +89,14 @@ export class CarbonEstimationComponent implements OnInit, OnDestroy {
}

private getAriaLabel(emission: ApexAxisChartSeries): string {
return `Estimation of emissions. ${emission.map(entry => this.getAriaLabelForCategory(entry as ApexChartSeries)).join(' ')}`;
return `Estimation of emissions. ${emission.map(entry => this.getAriaLabelForCategory(entry as ApexChartSeriesItem)).join(' ')}`;
}

private getAriaLabelForCategory(series: ApexChartSeries): string {
private getEmissionAriaLabel(chartData: ApexAxisChartSeries, isPlaceholder: boolean) {
return isPlaceholder ? 'Placeholder for estimation of emissions' : this.getAriaLabel(chartData);
}

private getAriaLabelForCategory(series: ApexChartSeriesItem): string {
const category = series.name.replace('-', 'are');
return `${category}${this.getEmissionMadeUp(series.data)}`;
}
Expand Down Expand Up @@ -161,6 +150,16 @@ export class CarbonEstimationComponent implements OnInit, OnDestroy {
return heightBoundedAboveAndBelow;
}

private getChartOptions(isPlaceholder: boolean) {
const chartOptions = getBaseChartOptions(isPlaceholder);
chartOptions.chart.height = this.getChartHeight(window.innerHeight, window.innerWidth, window.screen.height);
return chartOptions;
}

private getChartData(estimation?: CarbonEstimation): ApexAxisChartSeries {
return estimation ? this.getOverallEmissionPercentages(estimation) : placeholderData;
}

private getDataItem(key: string, value: number, parent: string): ApexChartDataItem {
switch (key) {
case 'software':
Expand Down
Loading

0 comments on commit 01a0881

Please sign in to comment.