ng-prime-tools 1.0.84 → 1.0.85

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Pipe, EventEmitter, ViewChild, Output, Input, Component, NgModule, Injectable, HostListener, ContentChild, HostBinding } from '@angular/core';
2
+ import { Pipe, EventEmitter, ViewChild, Output, Input, Component, NgModule, Injectable, Inject, HostListener, ContentChild, HostBinding } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
4
+ import { CommonModule, DOCUMENT } from '@angular/common';
5
5
  import * as i2 from '@angular/forms';
6
6
  import { FormGroup, FormControl, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
7
7
  import * as i3 from 'primeng/table';
@@ -3798,66 +3798,602 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
3798
3798
  }] });
3799
3799
 
3800
3800
  class PTChartComponent {
3801
- constructor() {
3801
+ constructor(document) {
3802
+ this.document = document;
3803
+ this.viewInitialized = false;
3804
+ this.colorSchemeChangeListener = () => {
3805
+ this.refreshTheme();
3806
+ };
3802
3807
  Chart.register(...registerables, ChartDataLabels);
3803
3808
  }
3804
- ngOnInit() {
3809
+ ngAfterViewInit() {
3810
+ this.viewInitialized = true;
3805
3811
  this.initializeChart();
3812
+ this.observeContainerResize();
3813
+ this.observeThemeChanges();
3814
+ }
3815
+ ngOnChanges(changes) {
3816
+ if (this.viewInitialized && changes['chartConfig'] && this.chartConfig) {
3817
+ this.updateChart();
3818
+ }
3806
3819
  }
3807
3820
  ngOnDestroy() {
3821
+ this.resizeObserver?.disconnect();
3822
+ this.themeMutationObserver?.disconnect();
3823
+ this.colorSchemeMediaQuery?.removeEventListener('change', this.colorSchemeChangeListener);
3808
3824
  this.destroyChart();
3809
3825
  }
3826
+ get chartContainerStyle() {
3827
+ return {
3828
+ width: this.chartConfig?.chartWidth?.trim() || '100%',
3829
+ height: this.chartConfig?.chartHeight?.trim() || '100%',
3830
+ };
3831
+ }
3832
+ get chartAriaLabel() {
3833
+ return this.chartConfig?.medianTitle?.trim() || 'Graphique de données';
3834
+ }
3810
3835
  initializeChart() {
3836
+ if (!this.viewInitialized || !this.chartConfig) {
3837
+ return;
3838
+ }
3811
3839
  const canvas = this.canvasRef.nativeElement;
3812
- // Destroy the existing chart instance if it already exists
3813
3840
  this.destroyChart();
3814
- const config = {
3815
- type: this.chartConfig.type,
3816
- data: this.chartConfig.data,
3817
- options: {
3818
- ...this.chartConfig.options,
3819
- plugins: {
3820
- datalabels: {
3821
- formatter: (value, context) => {
3822
- const data = context.chart.data.datasets[0].data;
3823
- const total = data.reduce((sum, val) => sum + val, 0);
3824
- const percentage = ((value / total) * 100).toFixed(1) + '%';
3825
- return percentage;
3826
- },
3827
- color: '#000',
3841
+ const configuration = this.buildChartConfiguration();
3842
+ this.chart = new Chart(canvas, configuration);
3843
+ this.currentChartType = this.chartConfig.type;
3844
+ }
3845
+ updateChart() {
3846
+ if (!this.viewInitialized || !this.chartConfig) {
3847
+ return;
3848
+ }
3849
+ if (!this.chart) {
3850
+ this.initializeChart();
3851
+ return;
3852
+ }
3853
+ const requestedType = this.chartConfig.type;
3854
+ /*
3855
+ * Chart.js does not safely support changing the root chart type
3856
+ * dynamically. Recreate the chart when the requested type changes.
3857
+ */
3858
+ if (this.currentChartType !== requestedType) {
3859
+ this.initializeChart();
3860
+ return;
3861
+ }
3862
+ const configuration = this.buildChartConfiguration();
3863
+ this.chart.data = configuration.data;
3864
+ if (configuration.options) {
3865
+ this.chart.options = configuration.options;
3866
+ }
3867
+ this.chart.update();
3868
+ }
3869
+ buildChartConfiguration() {
3870
+ const chartType = this.chartConfig.type;
3871
+ const theme = this.resolveTheme();
3872
+ const defaultOptions = this.buildDefaultOptions(chartType, theme);
3873
+ const consumerOptions = this.chartConfig.options ?? {};
3874
+ return {
3875
+ type: chartType,
3876
+ data: this.cloneChartData(this.chartConfig.data),
3877
+ options: this.mergeChartOptions(defaultOptions, consumerOptions, chartType),
3878
+ };
3879
+ }
3880
+ buildDefaultOptions(chartType, theme) {
3881
+ const isCartesianChart = this.isCartesianChart(chartType);
3882
+ const isCircularChart = this.isCircularChart(chartType);
3883
+ const options = {
3884
+ responsive: true,
3885
+ maintainAspectRatio: false,
3886
+ resizeDelay: 100,
3887
+ interaction: {
3888
+ intersect: false,
3889
+ mode: isCartesianChart ? 'index' : 'nearest',
3890
+ },
3891
+ animation: {
3892
+ duration: 450,
3893
+ easing: 'easeOutQuart',
3894
+ },
3895
+ layout: {
3896
+ padding: {
3897
+ top: 12,
3898
+ right: 12,
3899
+ bottom: 8,
3900
+ left: 12,
3901
+ },
3902
+ },
3903
+ plugins: {
3904
+ legend: {
3905
+ display: true,
3906
+ position: 'bottom',
3907
+ align: 'center',
3908
+ labels: {
3909
+ color: theme.textColor,
3910
+ usePointStyle: true,
3911
+ pointStyle: 'circle',
3912
+ boxWidth: 9,
3913
+ boxHeight: 9,
3914
+ padding: 18,
3828
3915
  font: {
3829
- weight: 'bold',
3916
+ family: this.resolveFontFamily(),
3917
+ size: 12,
3918
+ weight: 500,
3919
+ },
3920
+ },
3921
+ },
3922
+ title: {
3923
+ display: Boolean(this.chartConfig.medianTitle?.trim()),
3924
+ text: this.chartConfig.medianTitle?.trim() || '',
3925
+ align: 'start',
3926
+ color: theme.textColor,
3927
+ padding: {
3928
+ top: 4,
3929
+ bottom: 18,
3930
+ },
3931
+ font: {
3932
+ family: this.resolveFontFamily(),
3933
+ size: 16,
3934
+ weight: 600,
3935
+ },
3936
+ },
3937
+ tooltip: {
3938
+ enabled: true,
3939
+ backgroundColor: theme.tooltipBackgroundColor,
3940
+ titleColor: theme.tooltipTextColor,
3941
+ bodyColor: theme.tooltipTextColor,
3942
+ footerColor: theme.secondaryTextColor,
3943
+ borderColor: theme.tooltipBorderColor,
3944
+ borderWidth: 1,
3945
+ cornerRadius: 10,
3946
+ caretSize: 7,
3947
+ caretPadding: 8,
3948
+ padding: 12,
3949
+ boxPadding: 6,
3950
+ usePointStyle: true,
3951
+ displayColors: true,
3952
+ titleFont: {
3953
+ family: this.resolveFontFamily(),
3954
+ size: 13,
3955
+ weight: 600,
3956
+ },
3957
+ bodyFont: {
3958
+ family: this.resolveFontFamily(),
3959
+ size: 12,
3960
+ weight: 400,
3961
+ },
3962
+ callbacks: {
3963
+ label: (context) => {
3964
+ return this.buildTooltipLabel(context, isCircularChart);
3830
3965
  },
3831
3966
  },
3832
- ...this.chartConfig.options?.plugins,
3967
+ },
3968
+ datalabels: {
3969
+ display: isCircularChart,
3970
+ color: theme.textColor,
3971
+ anchor: isCircularChart ? 'center' : 'end',
3972
+ align: isCircularChart ? 'center' : 'top',
3973
+ clamp: true,
3974
+ clip: false,
3975
+ formatter: (value, context) => {
3976
+ return this.formatDataLabel(value, context.chart, context.datasetIndex, isCircularChart);
3977
+ },
3978
+ font: {
3979
+ family: this.resolveFontFamily(),
3980
+ size: 11,
3981
+ weight: 'bold',
3982
+ },
3983
+ textStrokeColor: theme.surfaceColor,
3984
+ textStrokeWidth: isCircularChart ? 2 : 0,
3833
3985
  },
3834
3986
  },
3835
3987
  };
3836
- // Create a new Chart instance
3837
- this.chart = new Chart(canvas, config);
3988
+ if (isCartesianChart) {
3989
+ options.scales = this.buildDefaultScales(theme);
3990
+ }
3991
+ return options;
3838
3992
  }
3839
- updateChart() {
3840
- if (this.chart) {
3841
- this.chart.data = this.chartConfig.data;
3842
- if (this.chartConfig.options) {
3843
- this.chart.options = this.chartConfig.options;
3993
+ buildDefaultScales(theme) {
3994
+ const commonTickFont = {
3995
+ family: this.resolveFontFamily(),
3996
+ size: 11,
3997
+ weight: 400,
3998
+ };
3999
+ return {
4000
+ x: {
4001
+ display: true,
4002
+ beginAtZero: false,
4003
+ border: {
4004
+ display: false,
4005
+ },
4006
+ grid: {
4007
+ display: false,
4008
+ color: theme.gridColor,
4009
+ drawTicks: false,
4010
+ },
4011
+ ticks: {
4012
+ color: theme.secondaryTextColor,
4013
+ padding: 10,
4014
+ maxRotation: 0,
4015
+ autoSkip: true,
4016
+ font: commonTickFont,
4017
+ },
4018
+ title: {
4019
+ display: Boolean(this.chartConfig.xAxisTitle?.trim()),
4020
+ text: this.chartConfig.xAxisTitle?.trim() || '',
4021
+ color: theme.textColor,
4022
+ padding: {
4023
+ top: 12,
4024
+ },
4025
+ font: {
4026
+ family: this.resolveFontFamily(),
4027
+ size: 12,
4028
+ weight: 600,
4029
+ },
4030
+ },
4031
+ },
4032
+ y: {
4033
+ display: true,
4034
+ beginAtZero: this.chartConfig.scales?.y?.ticks?.beginAtZero ?? true,
4035
+ min: this.chartConfig.scales?.y?.min,
4036
+ max: this.chartConfig.scales?.y?.max,
4037
+ border: {
4038
+ display: false,
4039
+ },
4040
+ grid: {
4041
+ display: true,
4042
+ color: theme.gridColor,
4043
+ drawTicks: false,
4044
+ lineWidth: 1,
4045
+ },
4046
+ ticks: {
4047
+ color: theme.secondaryTextColor,
4048
+ padding: 10,
4049
+ stepSize: this.chartConfig.scales?.y?.ticks?.stepSize,
4050
+ font: commonTickFont,
4051
+ },
4052
+ title: {
4053
+ display: Boolean(this.chartConfig.yAxisTitle?.trim()),
4054
+ text: this.chartConfig.yAxisTitle?.trim() || '',
4055
+ color: theme.textColor,
4056
+ padding: {
4057
+ bottom: 12,
4058
+ },
4059
+ font: {
4060
+ family: this.resolveFontFamily(),
4061
+ size: 12,
4062
+ weight: 600,
4063
+ },
4064
+ },
4065
+ },
4066
+ };
4067
+ }
4068
+ mergeChartOptions(defaultOptions, consumerOptions, chartType) {
4069
+ const defaultPlugins = defaultOptions.plugins;
4070
+ const consumerPlugins = consumerOptions.plugins;
4071
+ const mergedOptions = {
4072
+ ...defaultOptions,
4073
+ ...consumerOptions,
4074
+ interaction: {
4075
+ ...defaultOptions.interaction,
4076
+ ...consumerOptions.interaction,
4077
+ },
4078
+ animation: consumerOptions.animation === false
4079
+ ? false
4080
+ : {
4081
+ ...(typeof defaultOptions.animation === 'object'
4082
+ ? defaultOptions.animation
4083
+ : {}),
4084
+ ...(typeof consumerOptions.animation === 'object'
4085
+ ? consumerOptions.animation
4086
+ : {}),
4087
+ },
4088
+ layout: {
4089
+ ...defaultOptions.layout,
4090
+ ...consumerOptions.layout,
4091
+ padding: consumerOptions.layout?.padding ?? defaultOptions.layout?.padding,
4092
+ },
4093
+ plugins: {
4094
+ ...defaultPlugins,
4095
+ ...consumerPlugins,
4096
+ legend: {
4097
+ ...defaultPlugins?.legend,
4098
+ ...consumerPlugins?.legend,
4099
+ labels: {
4100
+ ...defaultPlugins?.legend?.labels,
4101
+ ...consumerPlugins?.legend?.labels,
4102
+ /*
4103
+ * Chart.js font options may be scriptable callbacks.
4104
+ * Keep the complete consumer value rather than spreading it.
4105
+ */
4106
+ font: consumerPlugins?.legend?.labels?.font ??
4107
+ defaultPlugins?.legend?.labels?.font,
4108
+ },
4109
+ },
4110
+ title: {
4111
+ ...defaultPlugins?.title,
4112
+ ...consumerPlugins?.title,
4113
+ font: consumerPlugins?.title?.font ?? defaultPlugins?.title?.font,
4114
+ },
4115
+ tooltip: {
4116
+ ...defaultPlugins?.tooltip,
4117
+ ...consumerPlugins?.tooltip,
4118
+ titleFont: consumerPlugins?.tooltip?.titleFont ??
4119
+ defaultPlugins?.tooltip?.titleFont,
4120
+ bodyFont: consumerPlugins?.tooltip?.bodyFont ??
4121
+ defaultPlugins?.tooltip?.bodyFont,
4122
+ footerFont: consumerPlugins?.tooltip?.footerFont ??
4123
+ defaultPlugins?.tooltip?.footerFont,
4124
+ callbacks: {
4125
+ ...defaultPlugins?.tooltip?.callbacks,
4126
+ ...consumerPlugins?.tooltip?.callbacks,
4127
+ },
4128
+ },
4129
+ datalabels: {
4130
+ ...defaultPlugins?.datalabels,
4131
+ ...consumerPlugins?.datalabels,
4132
+ },
4133
+ },
4134
+ };
4135
+ if (this.isCartesianChart(chartType)) {
4136
+ mergedOptions.scales = this.mergeScales(defaultOptions.scales, consumerOptions.scales);
4137
+ }
4138
+ else if (consumerOptions.scales) {
4139
+ mergedOptions.scales = consumerOptions.scales;
4140
+ }
4141
+ return mergedOptions;
4142
+ }
4143
+ mergeScales(defaultScales, consumerScales) {
4144
+ const defaultScaleRecord = defaultScales ??
4145
+ {};
4146
+ const consumerScaleRecord = consumerScales ??
4147
+ {};
4148
+ const scaleKeys = new Set([
4149
+ ...Object.keys(defaultScaleRecord),
4150
+ ...Object.keys(consumerScaleRecord),
4151
+ ]);
4152
+ const mergedScales = {};
4153
+ scaleKeys.forEach((scaleKey) => {
4154
+ const defaultScale = defaultScaleRecord[scaleKey] ?? {};
4155
+ const consumerScale = consumerScaleRecord[scaleKey] ?? {};
4156
+ mergedScales[scaleKey] = {
4157
+ ...defaultScale,
4158
+ ...consumerScale,
4159
+ border: {
4160
+ ...this.asObject(defaultScale['border']),
4161
+ ...this.asObject(consumerScale['border']),
4162
+ },
4163
+ grid: {
4164
+ ...this.asObject(defaultScale['grid']),
4165
+ ...this.asObject(consumerScale['grid']),
4166
+ },
4167
+ ticks: {
4168
+ ...this.asObject(defaultScale['ticks']),
4169
+ ...this.asObject(consumerScale['ticks']),
4170
+ },
4171
+ title: {
4172
+ ...this.asObject(defaultScale['title']),
4173
+ ...this.asObject(consumerScale['title']),
4174
+ },
4175
+ };
4176
+ });
4177
+ return mergedScales;
4178
+ }
4179
+ buildTooltipLabel(context, includePercentage) {
4180
+ const datasetLabel = context.dataset.label?.trim();
4181
+ const value = this.extractNumericValue(context.raw);
4182
+ const formattedValue = value !== null ? this.formatNumber(value) : context.formattedValue;
4183
+ const prefix = datasetLabel ? `${datasetLabel}: ` : '';
4184
+ if (!includePercentage || value === null) {
4185
+ return `${prefix}${formattedValue}`;
4186
+ }
4187
+ const total = this.calculateDatasetTotal(context.dataset);
4188
+ if (total <= 0) {
4189
+ return `${prefix}${formattedValue}`;
4190
+ }
4191
+ const percentage = ((Math.abs(value) / total) * 100).toFixed(1);
4192
+ return `${prefix}${formattedValue} (${percentage} %)`;
4193
+ }
4194
+ formatDataLabel(value, chart, datasetIndex, displayPercentage) {
4195
+ const numericValue = this.extractNumericValue(value);
4196
+ if (numericValue === null) {
4197
+ return '';
4198
+ }
4199
+ if (!displayPercentage) {
4200
+ return this.formatNumber(numericValue);
4201
+ }
4202
+ const dataset = chart.data.datasets[datasetIndex];
4203
+ if (!dataset) {
4204
+ return '';
4205
+ }
4206
+ const total = this.calculateDatasetTotal(dataset);
4207
+ if (total <= 0) {
4208
+ return '';
4209
+ }
4210
+ const percentage = (Math.abs(numericValue) / total) * 100;
4211
+ return percentage >= 1 ? `${percentage.toFixed(1)}%` : '';
4212
+ }
4213
+ calculateDatasetTotal(dataset) {
4214
+ return dataset.data.reduce((total, currentValue) => {
4215
+ const numericValue = this.extractNumericValue(currentValue);
4216
+ return numericValue !== null ? total + Math.abs(numericValue) : total;
4217
+ }, 0);
4218
+ }
4219
+ extractNumericValue(value) {
4220
+ if (typeof value === 'number' && Number.isFinite(value)) {
4221
+ return value;
4222
+ }
4223
+ if (typeof value === 'string') {
4224
+ const parsedValue = Number(value);
4225
+ return Number.isFinite(parsedValue) ? parsedValue : null;
4226
+ }
4227
+ if (Array.isArray(value)) {
4228
+ const candidate = value.find((item) => typeof item === 'number' && Number.isFinite(item));
4229
+ return typeof candidate === 'number' ? candidate : null;
4230
+ }
4231
+ if (value && typeof value === 'object') {
4232
+ const point = value;
4233
+ const candidate = point['y'] ?? point['r'] ?? point['value'] ?? point['x'];
4234
+ return this.extractNumericValue(candidate);
4235
+ }
4236
+ return null;
4237
+ }
4238
+ formatNumber(value) {
4239
+ return new Intl.NumberFormat(undefined, {
4240
+ maximumFractionDigits: 2,
4241
+ }).format(value);
4242
+ }
4243
+ cloneChartData(data) {
4244
+ return {
4245
+ ...data,
4246
+ labels: data.labels ? [...data.labels] : undefined,
4247
+ xLabels: data.xLabels ? [...data.xLabels] : undefined,
4248
+ yLabels: data.yLabels ? [...data.yLabels] : undefined,
4249
+ datasets: data.datasets.map((dataset) => ({
4250
+ ...dataset,
4251
+ data: [...dataset.data],
4252
+ })),
4253
+ };
4254
+ }
4255
+ observeContainerResize() {
4256
+ if (typeof ResizeObserver === 'undefined') {
4257
+ return;
4258
+ }
4259
+ const container = this.canvasRef.nativeElement.parentElement;
4260
+ if (!container) {
4261
+ return;
4262
+ }
4263
+ this.resizeObserver = new ResizeObserver(() => {
4264
+ this.chart?.resize();
4265
+ });
4266
+ this.resizeObserver.observe(container);
4267
+ }
4268
+ observeThemeChanges() {
4269
+ const documentElement = this.document.documentElement;
4270
+ if (typeof MutationObserver !== 'undefined') {
4271
+ this.themeMutationObserver = new MutationObserver(() => {
4272
+ this.refreshTheme();
4273
+ });
4274
+ this.themeMutationObserver.observe(documentElement, {
4275
+ attributes: true,
4276
+ attributeFilter: ['class', 'style', 'data-theme'],
4277
+ });
4278
+ if (this.document.body) {
4279
+ this.themeMutationObserver.observe(this.document.body, {
4280
+ attributes: true,
4281
+ attributeFilter: ['class', 'style', 'data-theme'],
4282
+ });
3844
4283
  }
3845
- this.chart.update();
4284
+ }
4285
+ if (typeof window !== 'undefined' && window.matchMedia) {
4286
+ this.colorSchemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
4287
+ this.colorSchemeMediaQuery.addEventListener('change', this.colorSchemeChangeListener);
3846
4288
  }
3847
4289
  }
3848
- destroyChart() {
3849
- if (this.chart) {
3850
- this.chart.destroy();
3851
- this.chart = undefined;
4290
+ refreshTheme() {
4291
+ if (!this.chart || !this.chartConfig) {
4292
+ return;
4293
+ }
4294
+ const configuration = this.buildChartConfiguration();
4295
+ if (configuration.options) {
4296
+ this.chart.options = configuration.options;
3852
4297
  }
4298
+ this.chart.update('none');
3853
4299
  }
3854
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3855
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PTChartComponent, isStandalone: false, selector: "pt-chart", inputs: { chartConfig: "chartConfig" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["chartCanvas"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas #chartCanvas></canvas>\n</div>\n", styles: [""] }); }
4300
+ resolveTheme() {
4301
+ const rootStyles = getComputedStyle(this.document.documentElement);
4302
+ const bodyStyles = this.document.body
4303
+ ? getComputedStyle(this.document.body)
4304
+ : rootStyles;
4305
+ const isDarkMode = this.isDarkMode(rootStyles, bodyStyles);
4306
+ return {
4307
+ textColor: this.resolveCssVariable(rootStyles, ['--p-text-color', '--text-color'], isDarkMode ? '#f8fafc' : '#0f172a'),
4308
+ secondaryTextColor: this.resolveCssVariable(rootStyles, [
4309
+ '--p-text-muted-color',
4310
+ '--p-text-secondary-color',
4311
+ '--text-color-secondary',
4312
+ ], isDarkMode ? '#94a3b8' : '#64748b'),
4313
+ surfaceColor: this.resolveCssVariable(rootStyles, [
4314
+ '--p-content-background',
4315
+ '--p-surface-0',
4316
+ '--surface-card',
4317
+ '--surface-ground',
4318
+ ], isDarkMode ? '#0f172a' : '#ffffff'),
4319
+ gridColor: this.resolveCssVariable(rootStyles, ['--p-content-border-color', '--p-surface-border', '--surface-border'], isDarkMode ? 'rgba(148, 163, 184, 0.16)' : 'rgba(15, 23, 42, 0.08)'),
4320
+ tooltipBackgroundColor: this.resolveCssVariable(rootStyles, ['--p-tooltip-background', '--p-surface-900', '--surface-900'], isDarkMode ? 'rgba(15, 23, 42, 0.96)' : 'rgba(15, 23, 42, 0.94)'),
4321
+ tooltipTextColor: this.resolveCssVariable(rootStyles, ['--p-tooltip-color', '--p-surface-0', '--surface-0'], '#f8fafc'),
4322
+ tooltipBorderColor: this.resolveCssVariable(rootStyles, ['--p-content-border-color', '--p-surface-border', '--surface-border'], isDarkMode ? 'rgba(148, 163, 184, 0.35)' : 'rgba(255, 255, 255, 0.18)'),
4323
+ };
4324
+ }
4325
+ isDarkMode(rootStyles, bodyStyles) {
4326
+ const root = this.document.documentElement;
4327
+ const body = this.document.body;
4328
+ const darkClassDetected = root.classList.contains('p-dark') ||
4329
+ root.classList.contains('dark') ||
4330
+ root.classList.contains('dark-mode') ||
4331
+ body?.classList.contains('p-dark') ||
4332
+ body?.classList.contains('dark') ||
4333
+ body?.classList.contains('dark-mode') ||
4334
+ root.getAttribute('data-theme') === 'dark' ||
4335
+ body?.getAttribute('data-theme') === 'dark';
4336
+ if (darkClassDetected) {
4337
+ return true;
4338
+ }
4339
+ const rootColorScheme = rootStyles
4340
+ .getPropertyValue('color-scheme')
4341
+ .trim()
4342
+ .toLowerCase();
4343
+ const bodyColorScheme = bodyStyles
4344
+ .getPropertyValue('color-scheme')
4345
+ .trim()
4346
+ .toLowerCase();
4347
+ if (rootColorScheme === 'dark' || bodyColorScheme === 'dark') {
4348
+ return true;
4349
+ }
4350
+ return (typeof window !== 'undefined' &&
4351
+ window.matchMedia?.('(prefers-color-scheme: dark)').matches === true);
4352
+ }
4353
+ resolveCssVariable(styles, variableNames, fallback) {
4354
+ for (const variableName of variableNames) {
4355
+ const value = styles.getPropertyValue(variableName).trim();
4356
+ if (value) {
4357
+ return value;
4358
+ }
4359
+ }
4360
+ return fallback;
4361
+ }
4362
+ resolveFontFamily() {
4363
+ const rootStyles = getComputedStyle(this.document.documentElement);
4364
+ return this.resolveCssVariable(rootStyles, ['--p-font-family', '--font-family'], 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif');
4365
+ }
4366
+ asObject(value) {
4367
+ return value !== null && typeof value === 'object'
4368
+ ? value
4369
+ : {};
4370
+ }
4371
+ isCircularChart(chartType) {
4372
+ return (chartType === 'pie' ||
4373
+ chartType === 'doughnut' ||
4374
+ chartType === 'polarArea');
4375
+ }
4376
+ isCartesianChart(chartType) {
4377
+ return (chartType === 'bar' ||
4378
+ chartType === 'line' ||
4379
+ chartType === 'scatter' ||
4380
+ chartType === 'bubble');
4381
+ }
4382
+ destroyChart() {
4383
+ this.chart?.destroy();
4384
+ this.chart = undefined;
4385
+ this.currentChartType = undefined;
4386
+ }
4387
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChartComponent, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
4388
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.14", type: PTChartComponent, isStandalone: false, selector: "pt-chart", inputs: { chartConfig: "chartConfig" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["chartCanvas"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"pt-chart\"\n [ngStyle]=\"chartContainerStyle\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel\"\n>\n <div class=\"pt-chart__canvas-container\">\n <canvas #chartCanvas></canvas>\n </div>\n</div>\n", styles: [":host{display:block;width:100%;min-width:0;height:100%;min-height:0}.pt-chart{position:relative;display:block;box-sizing:border-box;min-width:0;min-height:18rem;overflow:hidden;color:var(--p-text-color, var(--text-color, #0f172a));background:linear-gradient(145deg,color-mix(in srgb,var(--p-content-background, var(--surface-card, #ffffff)) 97%,var(--p-primary-color, #3b82f6) 3%),var(--p-content-background, var(--surface-card, #ffffff)));border:1px solid var(--p-content-border-color, var(--surface-border, rgba(15, 23, 42, .1)));border-radius:var(--p-content-border-radius, .875rem);box-shadow:0 1px 2px #0f172a0a,0 8px 24px #0f172a0d;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pt-chart:before{position:absolute;top:0;right:12%;left:12%;z-index:0;height:1px;pointer-events:none;content:\"\";background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--p-primary-color, #3b82f6) 45%,transparent),transparent)}.pt-chart__canvas-container{position:relative;z-index:1;width:100%;height:100%;min-width:0;min-height:inherit;padding:clamp(.75rem,1.5vw,1.25rem);box-sizing:border-box}.pt-chart canvas{display:block;width:100%!important;max-width:100%;height:100%!important;max-height:100%;outline:none}.pt-chart:focus-within{border-color:var(--p-primary-color, #3b82f6);box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color, #3b82f6) 18%,transparent),0 10px 30px #0f172a14}:host-context(.p-dark) .pt-chart,:host-context(.dark) .pt-chart,:host-context(.dark-mode) .pt-chart,:host-context([data-theme=\"dark\"]) .pt-chart{background:linear-gradient(145deg,color-mix(in srgb,var(--p-content-background, var(--surface-card, #0f172a)) 96%,var(--p-primary-color, #60a5fa) 4%),var(--p-content-background, var(--surface-card, #0f172a)));border-color:var( --p-content-border-color, var(--surface-border, rgba(148, 163, 184, .2)) );box-shadow:0 1px 2px #0000002e,0 12px 32px #00000038}@media(prefers-color-scheme:dark){.pt-chart{box-shadow:0 1px 2px #0000002e,0 12px 32px #0000002e}}@media(max-width:768px){.pt-chart{min-height:16rem;border-radius:.75rem}.pt-chart__canvas-container{padding:.75rem .625rem}}@media(max-width:480px){.pt-chart{min-height:15rem}.pt-chart__canvas-container{padding:.625rem .375rem}}@media(prefers-reduced-motion:reduce){.pt-chart{transition:none}}@media print{.pt-chart{overflow:visible;background:#fff;border:1px solid #d1d5db;box-shadow:none}}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
3856
4389
  }
3857
4390
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PTChartComponent, decorators: [{
3858
4391
  type: Component,
3859
- args: [{ selector: 'pt-chart', standalone: false, template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas #chartCanvas></canvas>\n</div>\n" }]
3860
- }], ctorParameters: () => [], propDecorators: { chartConfig: [{
4392
+ args: [{ selector: 'pt-chart', standalone: false, template: "<div\n class=\"pt-chart\"\n [ngStyle]=\"chartContainerStyle\"\n role=\"img\"\n [attr.aria-label]=\"chartAriaLabel\"\n>\n <div class=\"pt-chart__canvas-container\">\n <canvas #chartCanvas></canvas>\n </div>\n</div>\n", styles: [":host{display:block;width:100%;min-width:0;height:100%;min-height:0}.pt-chart{position:relative;display:block;box-sizing:border-box;min-width:0;min-height:18rem;overflow:hidden;color:var(--p-text-color, var(--text-color, #0f172a));background:linear-gradient(145deg,color-mix(in srgb,var(--p-content-background, var(--surface-card, #ffffff)) 97%,var(--p-primary-color, #3b82f6) 3%),var(--p-content-background, var(--surface-card, #ffffff)));border:1px solid var(--p-content-border-color, var(--surface-border, rgba(15, 23, 42, .1)));border-radius:var(--p-content-border-radius, .875rem);box-shadow:0 1px 2px #0f172a0a,0 8px 24px #0f172a0d;transition:background-color .18s ease,border-color .18s ease,box-shadow .18s ease}.pt-chart:before{position:absolute;top:0;right:12%;left:12%;z-index:0;height:1px;pointer-events:none;content:\"\";background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--p-primary-color, #3b82f6) 45%,transparent),transparent)}.pt-chart__canvas-container{position:relative;z-index:1;width:100%;height:100%;min-width:0;min-height:inherit;padding:clamp(.75rem,1.5vw,1.25rem);box-sizing:border-box}.pt-chart canvas{display:block;width:100%!important;max-width:100%;height:100%!important;max-height:100%;outline:none}.pt-chart:focus-within{border-color:var(--p-primary-color, #3b82f6);box-shadow:0 0 0 3px color-mix(in srgb,var(--p-primary-color, #3b82f6) 18%,transparent),0 10px 30px #0f172a14}:host-context(.p-dark) .pt-chart,:host-context(.dark) .pt-chart,:host-context(.dark-mode) .pt-chart,:host-context([data-theme=\"dark\"]) .pt-chart{background:linear-gradient(145deg,color-mix(in srgb,var(--p-content-background, var(--surface-card, #0f172a)) 96%,var(--p-primary-color, #60a5fa) 4%),var(--p-content-background, var(--surface-card, #0f172a)));border-color:var( --p-content-border-color, var(--surface-border, rgba(148, 163, 184, .2)) );box-shadow:0 1px 2px #0000002e,0 12px 32px #00000038}@media(prefers-color-scheme:dark){.pt-chart{box-shadow:0 1px 2px #0000002e,0 12px 32px #0000002e}}@media(max-width:768px){.pt-chart{min-height:16rem;border-radius:.75rem}.pt-chart__canvas-container{padding:.75rem .625rem}}@media(max-width:480px){.pt-chart{min-height:15rem}.pt-chart__canvas-container{padding:.625rem .375rem}}@media(prefers-reduced-motion:reduce){.pt-chart{transition:none}}@media print{.pt-chart{overflow:visible;background:#fff;border:1px solid #d1d5db;box-shadow:none}}\n"] }]
4393
+ }], ctorParameters: () => [{ type: Document, decorators: [{
4394
+ type: Inject,
4395
+ args: [DOCUMENT]
4396
+ }] }], propDecorators: { chartConfig: [{
3861
4397
  type: Input
3862
4398
  }], canvasRef: [{
3863
4399
  type: ViewChild,