Skip to content

Commit ce0827b

Browse files
committed
fix them
1 parent eeba54b commit ce0827b

File tree

17 files changed

+264
-26
lines changed

17 files changed

+264
-26
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: 204 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
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';
14+
import { ThemeStorageService } from 'app/shared/theme-picker/theme-storage.service';
1415

1516
/** Custom Models */
1617
import { ChartData } from '../../common-models/chart-data.model';
@@ -38,8 +39,11 @@ Chart.register(...registerables);
3839
NgStyle
3940
]
4041
})
41-
export class ChartComponent implements OnChanges {
42+
export class ChartComponent implements OnChanges, OnInit, OnDestroy {
4243
private reportsService = inject(ReportsService);
44+
private themeStorageService = inject(ThemeStorageService);
45+
private resizeTimeoutId: ReturnType<typeof setTimeout> | undefined;
46+
private initialRenderTimeoutId: ReturnType<typeof setTimeout> | undefined;
4347

4448
/** Run Report Data */
4549
@Input() dataObject: any;
@@ -50,6 +54,52 @@ export class ChartComponent implements OnChanges {
5054
hideOutput = true;
5155
/** Data object for witching charts in view. */
5256
inputData: ChartData;
57+
/** Tracks the currently selected chart type */
58+
selectedChartType: string = 'Pie';
59+
/** Resize listener */
60+
private readonly resizeListener = () => this.resizeChart();
61+
62+
/**
63+
* Initialize component and add resize listener.
64+
*/
65+
ngOnInit() {
66+
window.addEventListener('resize', this.resizeListener);
67+
}
68+
69+
/**
70+
* Clean up on component destroy.
71+
*/
72+
ngOnDestroy() {
73+
window.removeEventListener('resize', this.resizeListener);
74+
if (this.resizeTimeoutId !== undefined) {
75+
clearTimeout(this.resizeTimeoutId);
76+
this.resizeTimeoutId = undefined;
77+
}
78+
if (this.initialRenderTimeoutId !== undefined) {
79+
clearTimeout(this.initialRenderTimeoutId);
80+
this.initialRenderTimeoutId = undefined;
81+
}
82+
if (this.chart) {
83+
this.chart.destroy();
84+
this.chart = undefined;
85+
}
86+
}
87+
88+
/**
89+
* Resize and redraw chart when window size changes.
90+
*/
91+
resizeChart() {
92+
if (this.chart) {
93+
if (this.resizeTimeoutId !== undefined) {
94+
clearTimeout(this.resizeTimeoutId);
95+
}
96+
// Debounce resize calls to avoid queuing multiple chart operations.
97+
this.resizeTimeoutId = setTimeout(() => {
98+
this.chart?.resize();
99+
this.resizeTimeoutId = undefined;
100+
}, 100);
101+
}
102+
}
53103

54104
/**
55105
* Fetches run report data post changes in run report form.
@@ -62,20 +112,61 @@ export class ChartComponent implements OnChanges {
62112
this.reportsService
63113
.getChartRunReportData(this.dataObject.report.name, this.dataObject.formData)
64114
.subscribe((response: ChartData) => {
115+
console.log(response);
65116
this.inputData = response;
66-
this.setPieChart(this.inputData);
117+
this.selectedChartType = 'Pie';
67118
this.hideOutput = false;
119+
if (this.initialRenderTimeoutId !== undefined) {
120+
clearTimeout(this.initialRenderTimeoutId);
121+
}
122+
this.initialRenderTimeoutId = setTimeout(() => {
123+
this.setPieChart(response);
124+
this.initialRenderTimeoutId = undefined;
125+
});
68126
});
69127
}
70128

129+
/**
130+
* Handles chart type selection and renders the selected chart.
131+
* @param {string} chartType The type of chart to display
132+
*/
133+
selectChart(chartType: string) {
134+
if (!this.inputData) {
135+
return;
136+
}
137+
const chartColors = this.randomColorArray(this.inputData.values.length);
138+
this.selectedChartType = chartType;
139+
switch (chartType) {
140+
case 'Bar':
141+
this.setBarChart(this.inputData, chartColors);
142+
break;
143+
case 'Pie':
144+
this.setPieChart(this.inputData, chartColors);
145+
break;
146+
case 'Polar':
147+
this.setPolarAreaChart(this.inputData, chartColors);
148+
break;
149+
}
150+
}
151+
152+
/**
153+
* Refreshes colors when user clicks the currently selected toggle.
154+
*/
155+
refreshChartIfSameType(chartType: string) {
156+
if (chartType === this.selectedChartType) {
157+
this.selectChart(chartType);
158+
}
159+
}
160+
71161
/**
72162
* Creates instance of chart.js pie chart.
73163
* Refer: https://www.chartjs.org/docs/latest/charts/doughnut.html for configuration details.
74164
*/
75-
setPieChart(inputData: ChartData) {
165+
setPieChart(inputData: ChartData, chartColors?: string[]) {
76166
if (this.chart) {
77167
this.chart.destroy();
78168
}
169+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
79170
this.chart = new Chart('output', {
80171
type: 'pie',
81172
data: {
@@ -84,11 +175,13 @@ export class ChartComponent implements OnChanges {
84175
{
85176
label: inputData.valuesLabel,
86177
data: inputData.values,
87-
backgroundColor: this.randomColorArray(inputData.values.length)
178+
backgroundColor: colors
88179
}
89180
]
90181
},
91182
options: {
183+
responsive: true,
184+
maintainAspectRatio: false,
92185
plugins: {
93186
title: {
94187
display: true,
@@ -103,10 +196,11 @@ export class ChartComponent implements OnChanges {
103196
* Creates instance of chart.js bar chart.
104197
* Refer: https://www.chartjs.org/docs/latest/charts/bar.html for configuration details.
105198
*/
106-
setBarChart(inputData: ChartData) {
199+
setBarChart(inputData: ChartData, chartColors?: string[]) {
107200
if (this.chart) {
108201
this.chart.destroy();
109202
}
203+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
110204
this.chart = new Chart('output', {
111205
type: 'bar',
112206
data: {
@@ -115,11 +209,13 @@ export class ChartComponent implements OnChanges {
115209
{
116210
label: inputData.valuesLabel,
117211
data: inputData.values,
118-
backgroundColor: this.randomColorArray(inputData.values.length)
212+
backgroundColor: colors
119213
}
120214
]
121215
},
122216
options: {
217+
responsive: true,
218+
maintainAspectRatio: false,
123219
plugins: {
124220
legend: { display: false }
125221
},
@@ -138,12 +234,53 @@ export class ChartComponent implements OnChanges {
138234
});
139235
}
140236

237+
/**
238+
* Creates instance of chart.js polar area chart.
239+
* Refer: https://www.chartjs.org/docs/latest/charts/polar.html for configuration details.
240+
*/
241+
setPolarAreaChart(inputData: ChartData, chartColors?: string[]) {
242+
if (this.chart) {
243+
this.chart.destroy();
244+
}
245+
const colors = chartColors ?? this.randomColorArray(inputData.values.length);
246+
this.chart = new Chart('output', {
247+
type: 'polarArea',
248+
data: {
249+
labels: inputData.keys,
250+
datasets: [
251+
{
252+
label: inputData.valuesLabel,
253+
data: inputData.values,
254+
backgroundColor: colors,
255+
borderColor: colors
256+
}
257+
]
258+
},
259+
options: {
260+
responsive: true,
261+
maintainAspectRatio: false,
262+
plugins: {
263+
title: {
264+
display: true,
265+
text: inputData.keysLabel
266+
},
267+
legend: { display: true }
268+
},
269+
scales: {
270+
r: {
271+
min: 0
272+
}
273+
}
274+
}
275+
});
276+
}
277+
141278
/**
142279
* Generates bar/pie-slice colors array for dynamic charts.
143280
* @param {number} length Length of dataset array.
144281
*/
145282
randomColorArray(length: number) {
146-
const colorArray: any[] = [];
283+
const colorArray: string[] = [];
147284
while (length--) {
148285
const color = this.randomColor();
149286
colorArray.push(color);
@@ -152,12 +289,66 @@ export class ChartComponent implements OnChanges {
152289
}
153290

154291
/**
155-
* Returns a random rgb color.
292+
* Returns a semi-random color based on the active theme palette.
156293
*/
157294
randomColor() {
158-
const r = Math.floor(Math.random() * 255);
159-
const g = Math.floor(Math.random() * 255);
160-
const b = Math.floor(Math.random() * 255);
161-
return `rgb(${r},${g},${b},0.6)`;
295+
const baseColors = this.getThemeBaseColors();
296+
const baseColor = baseColors[Math.floor(Math.random() * baseColors.length)];
297+
const variation = Math.floor(Math.random() * 61) - 30;
298+
const [
299+
r,
300+
g,
301+
b
302+
] = this.hexToRgb(baseColor).map((channel) => this.clamp(channel + variation));
303+
return `rgba(${r},${g},${b},0.6)`;
304+
}
305+
306+
/**
307+
* Derives chart base colors from the user's selected theme and current dark mode.
308+
*/
309+
private getThemeBaseColors(): string[] {
310+
const savedTheme = this.themeStorageService.getTheme();
311+
const primary = savedTheme?.primary || '#1074B9';
312+
const accent = savedTheme?.accent || '#B4D575';
313+
const isDark = document.body.classList.contains('dark-theme');
314+
315+
if (isDark) {
316+
return [
317+
primary,
318+
accent,
319+
'#5BA2EC',
320+
'#83A447',
321+
'#C4C6D0'
322+
];
323+
}
324+
325+
return [
326+
primary,
327+
accent,
328+
'#004989',
329+
'#E7FFA5',
330+
'#6E8A3B'
331+
];
332+
}
333+
334+
private hexToRgb(hexColor: string): number[] {
335+
const hex = hexColor.replace('#', '');
336+
const normalized =
337+
hex.length === 3
338+
? hex
339+
.split('')
340+
.map((char) => char + char)
341+
.join('')
342+
: hex;
343+
const numeric = parseInt(normalized, 16);
344+
return [
345+
(numeric >> 16) & 255,
346+
(numeric >> 8) & 255,
347+
numeric & 255
348+
];
349+
}
350+
351+
private clamp(value: number): number {
352+
return Math.max(0, Math.min(255, value));
162353
}
163354
}

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í",

0 commit comments

Comments
 (0)