Skip to content

Commit c4c4d11

Browse files
committed
feat(charts): implement responsive chart sizing with window resize handling
1 parent eeba54b commit c4c4d11

File tree

17 files changed

+181
-21
lines changed

17 files changed

+181
-21
lines changed

src/app/reports/run-report/chart/chart.component.html

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,27 @@
66
file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
-->
88

9-
<div class="m-b-20 layout-align-end">
10-
<mat-button-toggle-group aria-label="Select Chart Type">
11-
<mat-button-toggle value="Bar" (click)="setBarChart(inputData)">{{
12-
'labels.buttons.Bar Chart' | translate
13-
}}</mat-button-toggle>
14-
<mat-button-toggle value="Pie" (click)="setPieChart(inputData)">{{
15-
'labels.buttons.Pie Chart' | translate
16-
}}</mat-button-toggle>
17-
</mat-button-toggle-group>
18-
</div>
9+
<div class="p-20 m-b-20">
10+
<div class="layout-align-end m-b-20">
11+
<mat-button-toggle-group
12+
[value]="selectedChartType"
13+
[disabled]="hideOutput"
14+
aria-label="{{ 'labels.buttons.Select Chart Type' | translate }}"
15+
(change)="selectChart($event.value)"
16+
>
17+
<mat-button-toggle value="Bar" (click)="refreshChartIfSameType('Bar')">{{
18+
'labels.buttons.Bar Chart' | translate
19+
}}</mat-button-toggle>
20+
<mat-button-toggle value="Pie" (click)="refreshChartIfSameType('Pie')">{{
21+
'labels.buttons.Pie Chart' | translate
22+
}}</mat-button-toggle>
23+
<mat-button-toggle value="Polar" (click)="refreshChartIfSameType('Polar')">{{
24+
'labels.buttons.Polar Area Chart' | translate
25+
}}</mat-button-toggle>
26+
</mat-button-toggle-group>
27+
</div>
1928

20-
<div [ngStyle]="{ display: hideOutput ? 'none' : 'block' }">
21-
<canvas id="output"></canvas>
29+
<div [ngStyle]="{ display: hideOutput ? 'none' : 'block' }" class="chart-output-container">
30+
<canvas id="output"></canvas>
31+
</div>
2232
</div>

src/app/reports/run-report/chart/chart.component.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,14 @@
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
66
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
8+
9+
.chart-output-container {
10+
position: relative;
11+
width: 100%;
12+
height: 500px;
13+
14+
canvas {
15+
width: 100% !important;
16+
height: 100% !important;
17+
}
18+
}

src/app/reports/run-report/chart/chart.component.ts

Lines changed: 121 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
/** Angular Imports */
10-
import { Component, OnChanges, Input, inject } from '@angular/core';
10+
import { Component, OnChanges, OnInit, OnDestroy, Input, inject } from '@angular/core';
1111

1212
/** Custom Services */
1313
import { ReportsService } from '../../reports.service';
@@ -38,7 +38,7 @@ Chart.register(...registerables);
3838
NgStyle
3939
]
4040
})
41-
export class ChartComponent implements OnChanges {
41+
export class ChartComponent implements OnChanges, OnInit, OnDestroy {
4242
private reportsService = inject(ReportsService);
4343

4444
/** Run Report Data */
@@ -50,6 +50,39 @@ export class ChartComponent implements OnChanges {
5050
hideOutput = true;
5151
/** Data object for witching charts in view. */
5252
inputData: ChartData;
53+
/** Tracks the currently selected chart type */
54+
selectedChartType: string = 'Pie';
55+
/** Resize listener */
56+
private readonly resizeListener = () => this.resizeChart();
57+
58+
/**
59+
* Initialize component and add resize listener.
60+
*/
61+
ngOnInit() {
62+
window.addEventListener('resize', this.resizeListener);
63+
}
64+
65+
/**
66+
* Clean up on component destroy.
67+
*/
68+
ngOnDestroy() {
69+
window.removeEventListener('resize', this.resizeListener);
70+
if (this.chart) {
71+
this.chart.destroy();
72+
}
73+
}
74+
75+
/**
76+
* Resize and redraw chart when window size changes.
77+
*/
78+
resizeChart() {
79+
if (this.chart) {
80+
// Resize the chart canvas
81+
setTimeout(() => {
82+
this.chart.resize();
83+
}, 100);
84+
}
85+
}
5386

5487
/**
5588
* Fetches run report data post changes in run report form.
@@ -63,19 +96,53 @@ export class ChartComponent implements OnChanges {
6396
.getChartRunReportData(this.dataObject.report.name, this.dataObject.formData)
6497
.subscribe((response: ChartData) => {
6598
this.inputData = response;
66-
this.setPieChart(this.inputData);
99+
this.selectedChartType = 'Pie';
67100
this.hideOutput = false;
101+
setTimeout(() => this.setPieChart(this.inputData));
68102
});
69103
}
70104

105+
/**
106+
* Handles chart type selection and renders the selected chart.
107+
* @param {string} chartType The type of chart to display
108+
*/
109+
selectChart(chartType: string) {
110+
if (!this.inputData) {
111+
return;
112+
}
113+
const chartColors = this.randomColorArray(this.inputData.values.length);
114+
this.selectedChartType = chartType;
115+
switch (chartType) {
116+
case 'Bar':
117+
this.setBarChart(this.inputData, chartColors);
118+
break;
119+
case 'Pie':
120+
this.setPieChart(this.inputData, chartColors);
121+
break;
122+
case 'Polar':
123+
this.setPolarAreaChart(this.inputData, chartColors);
124+
break;
125+
}
126+
}
127+
128+
/**
129+
* Refreshes colors when user clicks the currently selected toggle.
130+
*/
131+
refreshChartIfSameType(chartType: string) {
132+
if (chartType === this.selectedChartType) {
133+
this.selectChart(chartType);
134+
}
135+
}
136+
71137
/**
72138
* Creates instance of chart.js pie chart.
73139
* Refer: https://www.chartjs.org/docs/latest/charts/doughnut.html for configuration details.
74140
*/
75-
setPieChart(inputData: ChartData) {
141+
setPieChart(inputData: ChartData, chartColors?: string[]) {
76142
if (this.chart) {
77143
this.chart.destroy();
78144
}
145+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
79146
this.chart = new Chart('output', {
80147
type: 'pie',
81148
data: {
@@ -84,11 +151,13 @@ export class ChartComponent implements OnChanges {
84151
{
85152
label: inputData.valuesLabel,
86153
data: inputData.values,
87-
backgroundColor: this.randomColorArray(inputData.values.length)
154+
backgroundColor: colors
88155
}
89156
]
90157
},
91158
options: {
159+
responsive: true,
160+
maintainAspectRatio: false,
92161
plugins: {
93162
title: {
94163
display: true,
@@ -103,10 +172,11 @@ export class ChartComponent implements OnChanges {
103172
* Creates instance of chart.js bar chart.
104173
* Refer: https://www.chartjs.org/docs/latest/charts/bar.html for configuration details.
105174
*/
106-
setBarChart(inputData: ChartData) {
175+
setBarChart(inputData: ChartData, chartColors?: string[]) {
107176
if (this.chart) {
108177
this.chart.destroy();
109178
}
179+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
110180
this.chart = new Chart('output', {
111181
type: 'bar',
112182
data: {
@@ -115,11 +185,13 @@ export class ChartComponent implements OnChanges {
115185
{
116186
label: inputData.valuesLabel,
117187
data: inputData.values,
118-
backgroundColor: this.randomColorArray(inputData.values.length)
188+
backgroundColor: colors
119189
}
120190
]
121191
},
122192
options: {
193+
responsive: true,
194+
maintainAspectRatio: false,
123195
plugins: {
124196
legend: { display: false }
125197
},
@@ -138,6 +210,47 @@ export class ChartComponent implements OnChanges {
138210
});
139211
}
140212

213+
/**
214+
* Creates instance of chart.js polar area chart.
215+
* Refer: https://www.chartjs.org/docs/latest/charts/polar.html for configuration details.
216+
*/
217+
setPolarAreaChart(inputData: ChartData, chartColors?: string[]) {
218+
if (this.chart) {
219+
this.chart.destroy();
220+
}
221+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
222+
this.chart = new Chart('output', {
223+
type: 'polarArea',
224+
data: {
225+
labels: inputData.keys,
226+
datasets: [
227+
{
228+
label: inputData.valuesLabel,
229+
data: inputData.values,
230+
backgroundColor: colors,
231+
borderColor: colors
232+
}
233+
]
234+
},
235+
options: {
236+
responsive: true,
237+
maintainAspectRatio: false,
238+
plugins: {
239+
title: {
240+
display: true,
241+
text: inputData.keysLabel
242+
},
243+
legend: { display: true }
244+
},
245+
scales: {
246+
r: {
247+
min: 0
248+
}
249+
}
250+
}
251+
});
252+
}
253+
141254
/**
142255
* Generates bar/pie-slice colors array for dynamic charts.
143256
* @param {number} length Length of dataset array.
@@ -158,6 +271,6 @@ export class ChartComponent implements OnChanges {
158271
const r = Math.floor(Math.random() * 255);
159272
const g = Math.floor(Math.random() * 255);
160273
const b = Math.floor(Math.random() * 255);
161-
return `rgb(${r},${g},${b},0.6)`;
274+
return `rgba(${r},${g},${b},0.6)`;
162275
}
163276
}

src/app/reports/run-report/run-report.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119

120120
<div class="container output" *ngIf="isCollapsed">
121121
<mat-card>
122-
<div class="m-b-20">
122+
<div class="m-b-20 p-20">
123123
<button mat-raised-button color="primary" (click)="isCollapsed = false">
124124
{{ 'labels.buttons.Parameters' | translate }}
125125
</button>

src/assets/translations/cs-CS.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@
524524
"Payments": "Platby",
525525
"Permissions": "Oprávnění",
526526
"Pie Chart": "Koláčový graf",
527+
"Polar Area Chart": "Polární plošný graf",
527528
"Post Dividend": "Vyplácet dividendu",
528529
"Previous": "Předchozí",
529530
"Preview": "Náhled",
@@ -562,6 +563,7 @@
562563
"Setup Products": "Nastavení produktů",
563564
"Setup System": "Systém nastavení",
564565
"Select All": "Vybrat vše",
566+
"Select Chart Type": "Vybrat typ grafu",
565567
"Show more": "Zobrazit více",
566568
"Show less": "Ukaž méně",
567569
"Signing in...": "Přihlašování",

src/assets/translations/de-DE.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@
525525
"Payments": "Zahlungen",
526526
"Permissions": "Berechtigungen",
527527
"Pie Chart": "Kuchendiagramm",
528+
"Polar Area Chart": "Polarflächendiagramm",
528529
"Post Dividend": "Post-Dividende",
529530
"Previous": "Vorherige",
530531
"Preview": "Vorschau",
@@ -563,6 +564,7 @@
563564
"Setup Products": "Setup-Produkte",
564565
"Setup System": "Setup-System",
565566
"Select All": "Wählen Sie Alle",
567+
"Select Chart Type": "Diagrammtyp auswählen",
566568
"Show more": "Zeig mehr",
567569
"Show less": "Zeige weniger",
568570
"Signing in...": "Anmelden",

src/assets/translations/en-US.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@
529529
"Payments": "Payments",
530530
"Permissions": "Permissions",
531531
"Pie Chart": "Pie Chart",
532+
"Polar Area Chart": "Polar Area Chart",
532533
"Post Dividend": "Post Dividend",
533534
"Previous": "Previous",
534535
"Preview": "Preview",
@@ -568,6 +569,7 @@
568569
"Setup Products": "Setup Products",
569570
"Setup System": "Setup System",
570571
"Select All": "Select All",
572+
"Select Chart Type": "Select Chart Type",
571573
"Show less": "Show less",
572574
"Show more": "Show more",
573575
"Signing in...": "Signing in...",

src/assets/translations/es-CL.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@
525525
"Payments": "Pagos",
526526
"Permissions": "Permisos",
527527
"Pie Chart": "Gráfico circular",
528+
"Polar Area Chart": "Gráfico de área polar",
528529
"Post Dividend": "Publicar dividendo",
529530
"Previous": "Anterior",
530531
"Preview": "Vista previa",
@@ -563,6 +564,7 @@
563564
"Setup Products": "Configuración de Productos",
564565
"Setup System": "Configuración de Sistema",
565566
"Select All": "Seleccionar todo",
567+
"Select Chart Type": "Seleccionar tipo de gráfico",
566568
"Show more": "Mostrar más",
567569
"Show less": "Muestra menos",
568570
"Signing in...": "Iniciando sesión",

src/assets/translations/es-MX.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@
525525
"Payments": "Pagos",
526526
"Permissions": "Permisos",
527527
"Pie Chart": "Gráfico circular",
528+
"Polar Area Chart": "Gráfico de área polar",
528529
"Post Dividend": "Publicar dividendo",
529530
"Previous": "Anterior",
530531
"Preview": "Vista previa",
@@ -563,6 +564,7 @@
563564
"Setup Products": "Configuración de Productos",
564565
"Setup System": "Configuración de Sistema",
565566
"Select All": "Seleccionar todo",
567+
"Select Chart Type": "Seleccionar tipo de gráfico",
566568
"Show more": "Mostrar más",
567569
"Show less": "Muestra menos",
568570
"Signing in...": "Iniciando sesión",

src/assets/translations/fr-FR.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@
525525
"Payments": "Paiements",
526526
"Permissions": "Autorisations",
527527
"Pie Chart": "Diagramme circulaire",
528+
"Polar Area Chart": "Diagramme en aires polaires",
528529
"Post Dividend": "Après dividende",
529530
"Previous": "Précédent",
530531
"Preview": "Aperçu",
@@ -563,6 +564,7 @@
563564
"Setup Products": "Produits d'installation",
564565
"Setup System": "Système de configuration",
565566
"Select All": "Tout sélectionner",
567+
"Select Chart Type": "Sélectionner le type de graphique",
566568
"Show more": "Montre plus",
567569
"Show less": "Montrer moins",
568570
"Signing in...": "Connexion",

0 commit comments

Comments
 (0)