@tapsellorg/angular-material-library
Version:
Angular library for Tapsell
1 lines • 82.4 kB
Source Map (JSON)
{"version":3,"file":"tapsellorg-angular-material-library-chart.mjs","sources":["../../projects/pegah-library/chart/chart-parent.ts","../../projects/pegah-library/chart/chart-tooltip.service.ts","../../projects/pegah-library/chart/configs.ts","../../projects/pegah-library/chart/chart-colors.service.ts","../../projects/pegah-library/chart/statbox.service.ts","../../projects/pegah-library/chart/mini-chart/mini-chart.component.ts","../../projects/pegah-library/chart/mini-chart/mini-chart.component.html","../../projects/pegah-library/chart/full-chart/full-chart.component.ts","../../projects/pegah-library/chart/full-chart/full-chart.component.html","../../projects/pegah-library/chart/map-chart/map-chart.component.ts","../../projects/pegah-library/chart/map-chart/map-chart.component.html","../../projects/pegah-library/chart/chart-stat-box.directive.ts","../../projects/pegah-library/chart/models.ts","../../projects/pegah-library/chart/chart-date-range-picker.directive.ts","../../projects/pegah-library/chart/chart-header.directive.ts","../../projects/pegah-library/chart/chart-box/chart-box.component.ts","../../projects/pegah-library/chart/chart-box/chart-box.component.html","../../projects/pegah-library/chart/chart-stat-box/chart-stat-box.component.ts","../../projects/pegah-library/chart/chart-stat-box/chart-stat-box.component.html","../../projects/pegah-library/chart/pie-chart/pie-chart.component.ts","../../projects/pegah-library/chart/pie-chart/pie-chart.component.html","../../projects/pegah-library/chart/chart.module.ts","../../projects/pegah-library/chart/chart.utils.ts","../../projects/pegah-library/chart/tapsellorg-angular-material-library-chart.ts"],"sourcesContent":["import { PghStatBoxService } from './statbox.service';\nimport { PghChartColorsService } from './chart-colors.service';\nimport { PghChartTooltipFormatter, PghSimpleHighchartsSeries } from './models';\nimport Highcharts from 'highcharts';\nimport { ObjectUtils } from '@tapsellorg/angular-material-library/src/lib/common';\nimport { PghChartTooltipService } from './chart-tooltip.service';\nimport { signal, Signal } from '@angular/core';\nimport highchartsMap from 'highcharts/modules/map';\n\nhighchartsMap(Highcharts);\n\nexport abstract class ChartParent {\n highcharts = Highcharts;\n abstract series: Signal<PghSimpleHighchartsSeries<any>[]>;\n protected abstract CHART_PLACEHOLDER_SERIES: any[];\n protected abstract statBoxService?: PghStatBoxService;\n protected abstract chartColorsService: PghChartColorsService;\n protected abstract chartTooltipService: PghChartTooltipService;\n abstract userCustomChartOptions: Signal<Highcharts.Options>;\n abstract defaultSeriesType: Signal<string>;\n tooltip = signal<string | PghChartTooltipFormatter | null>(null);\n\n get hasNoData() {\n return (\n !this.series()?.length ||\n (this.series().length === 1 && !(this.series()[0] as any).data?.length) ||\n this.series() === this.CHART_PLACEHOLDER_SERIES\n );\n }\n\n protected getChartSeriesColor(index: number) {\n const activeStatBoxes = this.statBoxService?.activeStatBoxes;\n\n if (!activeStatBoxes || activeStatBoxes.length !== this.series()?.length) {\n return this.chartColorsService.getChartSeriesColor(index);\n }\n\n return activeStatBoxes[index].color;\n }\n\n protected getChartSeries() {\n if (this.hasNoData) {\n return this.CHART_PLACEHOLDER_SERIES;\n }\n\n return (this.series() ?? []).map((s, i) => ({\n ...s,\n type: s.type ?? this.defaultSeriesType(),\n data: s.data.slice(),\n color: this.getChartSeriesColor(i),\n }));\n }\n\n protected createChartOptions(customOptions: Highcharts.Options): Highcharts.Options {\n const tooltipFormatter = this.getTooltipFormatter();\n const series = this.getChartSeries();\n\n return ObjectUtils.mergeDeep(\n {\n chart: {\n backgroundColor: 'var(--fff)',\n style: {\n fontFamily: 'inherit',\n },\n },\n colors: this.chartColorsService.chartColors,\n title: { text: undefined },\n credits: { enabled: false },\n tooltip: {\n borderWidth: 0,\n backgroundColor: '',\n useHTML: true,\n formatter() {\n return tooltipFormatter(this);\n },\n shared: true,\n },\n legend: {\n itemStyle: {\n cursor: 'pointer',\n 'font-size': '12px',\n 'font-weight': 'bold',\n color: 'var(--000)',\n fill: 'var(--000)',\n },\n },\n series,\n } as Highcharts.Options,\n customOptions,\n this.userCustomChartOptions(),\n );\n }\n\n protected getTooltipFormatter(): (data: Highcharts.TooltipFormatterContextObject) => string {\n if (typeof this.tooltip() === 'function') {\n return this.chartTooltipService.wrapTemplateOnFormatter(\n this.tooltip() as PghChartTooltipFormatter,\n this.series(),\n );\n } else {\n return this.chartTooltipService.wrapTemplateOnFormatter(\n this.chartTooltipService.getPredefinedFormatter((this.tooltip() as string) ?? 'number'),\n this.series(),\n );\n }\n }\n}\n","import { CurrencyPipe, DecimalPipe, PercentPipe } from '@angular/common';\nimport { Injectable } from '@angular/core';\nimport {\n PghChartTooltipFormatter,\n PghChartXAxisTooltipFormat,\n PghChartYAxisTooltip,\n PghChartYAxisTooltipFormat,\n PghChartYAxisTooltipFormatter,\n PghSimpleHighchartsSeries,\n} from './models';\nimport { DateUtils } from '@tapsellorg/angular-material-library/src/lib/jalali-date-adapter';\nimport { TooltipFormatterContextObject } from 'highcharts';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class PghChartTooltipService {\n constructor(\n private currencyPipe: CurrencyPipe,\n private percentPipe: PercentPipe,\n private decimalPipe: DecimalPipe,\n ) {}\n\n getPredefinedYAxisFormatter(tooltipType: PghChartYAxisTooltip): PghChartYAxisTooltipFormatter {\n if (typeof tooltipType === 'function') {\n return tooltipType;\n }\n return this.yAxisFormatters[tooltipType];\n }\n\n getPredefinedFormatter(tooltipType: string): PghChartTooltipFormatter {\n const [yAxis, xAxis] = tooltipType.split(':');\n const xAxisFormatter = this.xAxisFormatters[xAxis];\n const yAxisFormatter = this.yAxisFormatters[yAxis];\n\n if (!yAxisFormatter && !xAxisFormatter) {\n throw new Error(`PghChartTooltipService: ${tooltipType} tooltip not found.`);\n }\n return (data: TooltipFormatterContextObject) => ({\n data: (data.points || [data]).map(p => yAxisFormatter?.(p) ?? p.y),\n name: xAxisFormatter?.(data) ?? data.key,\n });\n }\n\n wrapTemplateOnFormatter(tooltip: PghChartTooltipFormatter, series: PghSimpleHighchartsSeries[]) {\n return (data: TooltipFormatterContextObject) => {\n const res = tooltip(data);\n this.applySeriesTooltipFormatters(res, data, series);\n // TODO: 'res.name ?? data.key' doesn't satisfy the 'tooltipTemplate' argument type and adding '?? ''' isn't very safe\n return this.tooltipTemplate(\n res.data ?? (data.points || [data]).map(p => p.y),\n res.name ?? data.key ?? '',\n data,\n );\n };\n }\n\n private applySeriesTooltipFormatters(\n res: ReturnType<PghChartTooltipFormatter>,\n data: TooltipFormatterContextObject,\n series: PghSimpleHighchartsSeries[],\n ) {\n res.data = (data.points || [data]).map((p, i) => {\n const seriesTooltipFormatter = this.getPredefinedYAxisFormatter(series[i].tooltip || '');\n return seriesTooltipFormatter ? seriesTooltipFormatter(p) : res.data?.[i];\n });\n }\n\n fillUndefinedAxisFormattersWithDefaults(\n tooltip: string | PghChartTooltipFormatter,\n defaultValues: { yAxis?: PghChartYAxisTooltipFormat; xAxis?: PghChartXAxisTooltipFormat },\n ) {\n if (typeof tooltip === 'function') return tooltip;\n const [yAxis, xAxis] = tooltip.split(':');\n\n return `${yAxis || defaultValues.yAxis}:${xAxis || defaultValues.xAxis}`;\n }\n\n //\n // ***\n // The followings are formatter util functions. They just get a point and format it\n // ***\n //\n\n tooltipTemplate = (\n y: (string | number | null | undefined)[],\n x: string | number,\n data: TooltipFormatterContextObject,\n ) => {\n const yAxisValuesTemplate = (data.points || [data])\n .map(\n (point, i) => `<div class=\"pgh-chart-tooltip-point\">\n <span>${y[i] || ''}</span>\n <span class=\"pgh-chart-tooltip-point-indicator ms-1\" style=\"--series-color:${\n point.color\n }\"></span>\n </div>`,\n )\n .join('');\n return `<div class=\"pgh-highcharts-tooltip\">\n <div class=\"pgh-highcharts-tooltip-values\">${yAxisValuesTemplate}</div>\n <div class=\"tooltip-x\" dir=\"auto\">${x}</div>\n </div>`;\n };\n\n // TODO: 'y' property existence isn't guaranteed\n numberFormatter = (point: TooltipFormatterContextObject) =>\n this.decimalPipe.transform(point.y) ?? point.y!.toString();\n\n // TODO: 'y' property existence isn't guaranteed and adding '?? 0' is not safe\n percentFormatter = (point: TooltipFormatterContextObject) =>\n this.percentPipe.transform(point.y ?? 0 / 100, '.2') ?? point.y!.toString();\n\n percentPieFormatter = (point: TooltipFormatterContextObject) =>\n `${point.percentage?.toFixed(2)}%`;\n\n // TODO: 'y' property existence isn't guaranteed\n currencyFormatter = (point: TooltipFormatterContextObject) =>\n this.currencyPipe.transform(point.y) ?? point.y!.toString();\n\n // TODO: 'x' property existence isn't guaranteed\n xAxisDateTimeFormatter = (data: TooltipFormatterContextObject) => {\n const x = data.x || data.key;\n return DateUtils.isValidDate(x)\n ? `${DateUtils.gregorianToJalali(x).format()} ${DateUtils.format(x, 'HH:MM')}`\n : x!.toString();\n };\n\n // TODO: 'x' property existence isn't guaranteed\n xAxisDateFormatter = (data: TooltipFormatterContextObject) => {\n const x = data.x || data.key;\n return DateUtils.isValidDate(x) ? DateUtils.gregorianToJalali(x).format() : x!.toString();\n };\n\n // TODO: 'x' property existence isn't guaranteed\n xAxisTimeFormatter = (data: TooltipFormatterContextObject) => {\n const x = data.x || data.key;\n return DateUtils.isValidDate(x) ? DateUtils.format(x, 'HH:MM') : x!.toString();\n };\n\n yAxisFormatters: Record<\n PghChartYAxisTooltipFormat | string,\n (data: TooltipFormatterContextObject) => string\n > = {\n number: this.numberFormatter,\n currency: this.currencyFormatter,\n percent: this.percentFormatter,\n 'percent-pie': this.percentPieFormatter,\n };\n\n xAxisFormatters: Record<\n PghChartXAxisTooltipFormat | string,\n (data: TooltipFormatterContextObject) => string\n > = {\n 'date-time': this.xAxisDateTimeFormatter,\n date: this.xAxisDateFormatter,\n time: this.xAxisTimeFormatter,\n };\n}\n","import { InjectionToken } from '@angular/core';\nimport { PghGlobalChartOptions } from './models';\n\nexport const PGH_CHART_COLORS = new InjectionToken<string[]>('chartColors', {\n providedIn: 'root',\n factory: () => ['var(--primary)', 'var(--accent)'],\n});\n\nexport const PGH_CHART_OPTIONS = new InjectionToken<PghGlobalChartOptions>('chartOptions', {\n providedIn: 'root',\n factory: () => ({}),\n});\n","import { Inject, Injectable } from '@angular/core';\nimport { PGH_CHART_COLORS } from './configs';\nimport { MiscUtils } from '@tapsellorg/angular-material-library/src/lib/common';\n\n@Injectable({ providedIn: 'root' })\nexport class PghChartColorsService {\n readonly FALL_BACK_COLORS = [...MiscUtils.ALL_MATERIAL_COLORS, ...MiscUtils.RANDOM_COLORS];\n private colors: string[] = [];\n\n constructor(@Inject(PGH_CHART_COLORS) colors: string[]) {\n this.updateColors(colors);\n }\n\n get chartColors() {\n return this.colors;\n }\n\n updateColors(colors: string[]) {\n this.colors = [...colors, ...this.FALL_BACK_COLORS.filter(c => !colors.includes(c))];\n }\n\n getStatBoxColor(index: number) {\n return this.colors[index % this.colors.length];\n }\n\n getChartSeriesColor(index: number) {\n return this.colors[index % this.colors.length];\n }\n}\n","import { ReplaySubject } from 'rxjs';\nimport { PghChartStatBox } from './models';\nimport { Injectable } from '@angular/core';\n\n@Injectable()\nexport class PghStatBoxService {\n statBoxes: PghChartStatBox[] = [];\n $activeStatBoxes = new ReplaySubject<PghChartStatBox[]>(1);\n\n get activeStatBoxes() {\n return this.statBoxes.filter(sb => sb.isActive);\n }\n\n constructor() {}\n\n setActiveStatBoxes(statBoxes: PghChartStatBox[]) {\n this.$activeStatBoxes.next(statBoxes);\n }\n\n addActiveStatBox(statBox: PghChartStatBox) {\n statBox.isActive = true;\n this.setActiveStatBoxes(this.statBoxes.filter(sb => sb.isActive));\n }\n\n removeActiveStatBox(statBox: PghChartStatBox) {\n statBox.isActive = false;\n this.setActiveStatBoxes(this.statBoxes.filter(sb => sb.isActive));\n }\n\n setOnlyActiveStatBox(statBox: PghChartStatBox) {\n this.statBoxes.forEach(sb => {\n sb.isActive = false;\n });\n statBox.isActive = true;\n this.setActiveStatBoxes([statBox]);\n }\n}\n","import {\n Component,\n input,\n OnChanges,\n Optional,\n signal,\n SimpleChanges,\n ViewEncapsulation,\n} from '@angular/core';\nimport * as Highcharts from 'highcharts';\nimport { PghSimpleHighchartsSeries } from '../models';\nimport { ChartParent } from '../chart-parent';\nimport { PghChartTooltipService } from '../chart-tooltip.service';\nimport { PghStatBoxService } from '../statbox.service';\nimport { PghChartColorsService } from '../chart-colors.service';\n\n@Component({\n selector: 'pgh-mini-chart',\n templateUrl: './mini-chart.component.html',\n styleUrls: ['./mini-chart.component.scss'],\n encapsulation: ViewEncapsulation.None,\n standalone: false,\n})\nexport class PghMiniChartComponent extends ChartParent implements OnChanges {\n chartOptions = signal<Highcharts.Options>({});\n userCustomChartOptions = input<Highcharts.Options>(\n {},\n {\n alias: 'customChartOptions',\n },\n );\n series = input<PghSimpleHighchartsSeries[]>([]);\n defaultSeriesType = input<'areaspline' | 'column'>('column', {\n alias: 'seriesType',\n });\n protected readonly CHART_PLACEHOLDER_SERIES = [\n { name: 'name', data: [3, 5, 1, 2, 3, 2, 3, 5, 1, 10, 9, 13], type: this.defaultSeriesType() },\n ];\n\n constructor(\n protected chartTooltipService: PghChartTooltipService,\n protected chartColorsService: PghChartColorsService,\n @Optional() protected statBoxService?: PghStatBoxService,\n ) {\n super();\n }\n\n ngOnChanges(_changes: SimpleChanges) {\n this.updateChartOptions();\n }\n\n private updateChartOptions() {\n const columnBorderRadius = (this.chartOptions().series?.length ?? 0) > 1 ? 0 : 4;\n\n this.chartOptions.set(\n this.createChartOptions({\n chart: {\n className: 'mini-chart',\n width: 90,\n height: 80,\n },\n xAxis: {\n lineWidth: 0,\n gridLineWidth: 0,\n lineColor: 'transparent',\n minorTickLength: 0,\n title: { text: undefined },\n labels: { enabled: false },\n tickLength: 0,\n },\n yAxis: {\n min: 0,\n title: { text: '' },\n lineWidth: 0,\n gridLineWidth: 0,\n lineColor: 'transparent',\n minorTickLength: 0,\n tickLength: 0,\n labels: { enabled: false },\n },\n plotOptions: {\n column: {\n pointPadding: 0.1,\n borderWidth: 0,\n stacking: 'normal',\n borderRadius: columnBorderRadius,\n },\n },\n legend: { enabled: false },\n tooltip: { enabled: false },\n }),\n );\n }\n}\n","<div class=\"pgh-chart-wrapper\">\n <div class=\"pgh-chart-content\" [class.pgh-chart-no-data]=\"hasNoData\">\n <highcharts-chart\n [Highcharts]=\"highcharts\"\n constructorType=\"chart\"\n [options]=\"chartOptions()\"\n [oneToOne]=\"true\"\n [runOutsideAngular]=\"true\"\n ></highcharts-chart>\n </div>\n</div>\n","import {\n AfterViewChecked,\n Component,\n ElementRef,\n Inject,\n input,\n model,\n OnChanges,\n Optional,\n signal,\n SimpleChanges,\n ViewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ChartParent } from '../chart-parent';\nimport { PghChartTooltipService } from '../chart-tooltip.service';\nimport { PghStatBoxService } from '../statbox.service';\nimport { PghChartColorsService } from '../chart-colors.service';\nimport {\n PghChartTooltipFormatter,\n PghFullChartYAxis,\n PghGlobalChartOptions,\n PghSimpleHighchartsSeries,\n} from '../models';\nimport { DateUtils } from '@tapsellorg/angular-material-library/src/lib/jalali-date-adapter';\nimport { PGH_CHART_OPTIONS } from '../configs';\nimport { Chart, Options } from 'highcharts';\n\n@Component({\n selector: 'pgh-full-chart',\n templateUrl: './full-chart.component.html',\n styleUrls: ['./full-chart.component.scss'],\n encapsulation: ViewEncapsulation.None,\n standalone: false,\n})\nexport class PghFullChartComponent extends ChartParent implements OnChanges, AfterViewChecked {\n private readonly MIN_ZOOM_ENABLED_CHART_SERIES = 8;\n chartOptions = signal<Options>({});\n userCustomChartOptions = input<Options>(\n {},\n {\n alias: 'customChartOptions',\n },\n );\n\n series = input<PghSimpleHighchartsSeries[]>([]);\n defaultSeriesType = input<'areaspline' | 'column'>('areaspline', {\n alias: 'seriesType',\n });\n\n xAxis = input<(string | Date)[]>([]);\n yAxis = model<PghFullChartYAxis[]>([{}]);\n // TODO: use typescript's template string `${PghChartTooltipType}:${PghChartTooltipXAxis}`\n tooltip = model<string | PghChartTooltipFormatter | null>('percent-pie');\n\n protected readonly CHART_PLACEHOLDER_SERIES = [\n { name: 'name', data: [3, 5, 1, 2, 3, 2, 3, 5, 1, 10, 9, 13], type: this.defaultSeriesType() },\n ];\n\n @ViewChild('chartWrapperRef') chartWrapper?: ElementRef;\n private lastChartWrapperWidth?: number;\n private chartInstance?: Chart;\n\n /** TODO: 'chartColorsService' injected but never used review its usage if the 'updateColors' in its constructor doesn't do anything in this scenario */\n constructor(\n protected chartTooltipService: PghChartTooltipService,\n protected chartColorsService: PghChartColorsService,\n @Inject(PGH_CHART_OPTIONS) private globalChartOptions: PghGlobalChartOptions,\n @Optional() protected statBoxService?: PghStatBoxService,\n ) {\n super();\n }\n\n ngAfterViewChecked() {\n this.handleChartReflow();\n }\n\n private handleChartReflow() {\n if (\n !this.chartInstance ||\n this.lastChartWrapperWidth === this.chartWrapper?.nativeElement.offsetWidth\n )\n return;\n\n this.lastChartWrapperWidth = this.chartWrapper?.nativeElement.offsetWidth;\n /**\n * TODO: using ChangeDetectorRef can be a better option instead of setTimeout\n * see https://stackoverflow.com/questions/73145234/what-to-use-in-angular-instead-of-settimeout-for-certain-changes\n * The decorator introduced in the above link is quite useful for this purpose\n * */\n setTimeout(() => {\n this.chartInstance?.reflow();\n });\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes.yAxis && this.yAxis().length === 0) {\n this.yAxis.set([{}]);\n }\n this.updateChartOptions();\n }\n\n private getXAxis = (xAxisValue: string | Date | number): string =>\n DateUtils.isValidDate(xAxisValue)\n ? DateUtils.gregorianToJalali(xAxisValue).format()\n : xAxisValue.toString();\n\n private updateChartOptions() {\n this.tooltip.set(\n this.chartTooltipService.fillUndefinedAxisFormattersWithDefaults(this.tooltip()!, {\n xAxis: this.globalChartOptions.fullChartTooltip?.xAxis || 'date',\n yAxis: this.globalChartOptions.fullChartTooltip?.yAxis,\n }),\n );\n const xAxis = this.xAxis() ?? [];\n this.chartOptions.set(\n this.createChartOptions({\n chart: {\n zooming: {\n type: xAxis.length > this.MIN_ZOOM_ENABLED_CHART_SERIES ? 'x' : undefined,\n },\n className: 'full-chart',\n type: 'areaspline',\n },\n xAxis: {\n categories: xAxis as string[],\n labels: {\n style: { fontSize: '14px', color: 'var(--444)' },\n formatter: that => this.getXAxis(that.value),\n },\n zoomEnabled: true,\n crosshair: true,\n },\n yAxis: this.yAxis().map(y => ({\n title: { text: null },\n labels: {\n format: y?.labels?.format ?? '',\n style: { fontSize: '13px', color: 'var(--666)' },\n },\n opposite: y.opposite,\n gridLineColor: 'var(--eee)',\n gridLineDashStyle: 'LongDashDot',\n })),\n plotOptions: {\n column: {\n borderColor: 'var(--fff)',\n },\n },\n }),\n );\n }\n\n onSetChartInstance(chartInstance: Chart) {\n this.chartInstance = chartInstance;\n }\n}\n","<div #chartWrapperRef class=\"pgh-chart-wrapper\">\n <span class=\"pgh-chart-placeholder-text\">{{ 'FULL_CHART_PLACEHOLDER_TEXT' | translate }}</span>\n <div class=\"pgh-chart-content\" [class.pgh-chart-no-data]=\"hasNoData\">\n <highcharts-chart\n [Highcharts]=\"highcharts\"\n constructorType=\"chart\"\n [options]=\"chartOptions()\"\n [oneToOne]=\"true\"\n class=\"w-100 d-block\"\n [runOutsideAngular]=\"true\"\n (chartInstance)=\"onSetChartInstance($event)\"\n ></highcharts-chart>\n </div>\n</div>\n","import {\n Component,\n inject,\n input,\n OnChanges,\n OnInit,\n Optional,\n signal,\n SimpleChanges,\n ViewEncapsulation,\n} from '@angular/core';\nimport iranMap from '@highcharts/map-collection/countries/ir/ir-all.geo.json';\nimport { ChartParent } from '../chart-parent';\nimport { PghChartTooltipService } from '../chart-tooltip.service';\nimport { PghStatBoxService } from '../statbox.service';\nimport { PghChartColorsService } from '../chart-colors.service';\nimport { PghMapChartDataItem, PghSimpleHighchartsSeries } from '../models';\n\n@Component({\n selector: 'pgh-map-chart',\n templateUrl: './map-chart.component.html',\n styleUrl: './map-chart.component.scss',\n encapsulation: ViewEncapsulation.None,\n standalone: false,\n})\nexport class PghMapChartComponent extends ChartParent implements OnChanges, OnInit {\n chartInstance = signal<Highcharts.Chart | undefined>(undefined);\n\n chartOptions = signal<Highcharts.Options>({});\n series = input<PghSimpleHighchartsSeries<PghMapChartDataItem[]>[]>([]);\n userCustomChartOptions = input<Highcharts.Options>(\n {},\n {\n alias: 'customChartOptions',\n },\n );\n defaultSeriesType = signal<string>('map');\n\n protected CHART_PLACEHOLDER_SERIES = [];\n protected chartTooltipService = inject(PghChartTooltipService);\n protected chartColorsService = inject(PghChartColorsService);\n constructor(@Optional() protected statBoxService?: PghStatBoxService) {\n super();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes['userCustomChartOptions']) {\n this.setChartOptions();\n }\n\n if (changes['series']) {\n this.updateChartData();\n }\n }\n\n ngOnInit() {\n this.setChartOptions();\n }\n\n private setChartOptions() {\n this.chartOptions.set(\n this.createChartOptions({\n chart: {\n map: iranMap,\n backgroundColor: 'transparent',\n },\n title: { text: undefined },\n credits: { enabled: false },\n legend: { enabled: false },\n colorAxis: {\n stops: [\n [0, '#B3ECDA'],\n [1, '#00865C'],\n ],\n },\n tooltip: {\n enabled: false,\n },\n plotOptions: {\n series: {\n animation: false,\n },\n },\n series: [\n {\n type: 'map',\n animation: false,\n joinBy: ['hc-key', 'id'],\n borderColor: '#FFFFFF',\n borderWidth: 1,\n states: {\n hover: {\n color: '#006042',\n borderColor: '#FFFFFF',\n borderWidth: 2,\n },\n },\n },\n ],\n }),\n );\n }\n\n updateChartData(): void {\n const seriesData = this.series()?.[0].data ?? [];\n const chart = this.chartInstance();\n\n if (chart && seriesData?.length) {\n chart.series[0].setData(seriesData, true, false);\n }\n }\n\n onChartInstanceReady(chart: Highcharts.Chart) {\n this.chartInstance.set(chart);\n this.updateChartData();\n }\n}\n","<div #chartWrapperRef class=\"pgh-chart-wrapper\">\n <div class=\"pgh-chart-content\" [class.pgh-chart-no-data]=\"hasNoData\">\n <highcharts-chart\n [Highcharts]=\"highcharts\"\n constructorType=\"mapChart\"\n [options]=\"chartOptions()\"\n [oneToOne]=\"true\"\n [runOutsideAngular]=\"true\"\n (chartInstance)=\"onChartInstanceReady($event)\"\n class=\"pgh-iran-map-chart w-100 d-block\"\n ></highcharts-chart>\n </div>\n</div>\n","import { Directive, input, OnChanges, OnInit, SimpleChanges, TemplateRef } from '@angular/core';\n\n@Directive({\n selector: '[pghStatsBox]',\n exportAs: 'pghStatsBox',\n standalone: false,\n})\nexport class PghChartStatBoxDirective implements OnChanges, OnInit {\n statBoxData = input<any | undefined>(undefined, {\n alias: 'pghStatsBox',\n });\n constructor(public template: TemplateRef<any>) {}\n ngOnChanges(changes: SimpleChanges) {\n this.handleNoStatBoxDataError();\n }\n\n ngOnInit() {\n this.handleNoStatBoxDataError();\n }\n\n private handleNoStatBoxDataError() {\n if (!this.statBoxData()) {\n throw new Error(\n 'Pass a statBox data to *pghStatsBox so you can use it in the (activeStatBoxesChange) listener',\n );\n }\n }\n}\n","import { TooltipFormatterContextObject } from 'highcharts';\nimport { PghChartStatBoxDirective } from './chart-stat-box.directive';\n\nexport type PghChartTooltipFormatter = (data: TooltipFormatterContextObject) => {\n data?: ReturnType<PghChartYAxisTooltipFormatter>[];\n name?: string | null | undefined;\n};\n\nexport type PghChartYAxisTooltipFormat = 'number' | 'percent' | 'currency' | 'percent-pie';\nexport type PghChartXAxisTooltipFormat = 'date-time' | 'date' | 'time';\nexport type PghFullChartTooltipFormat =\n | PghChartYAxisTooltipFormat\n | `${PghChartYAxisTooltipFormat}:${PghChartXAxisTooltipFormat}`;\n\nexport interface PghChartActiveStatBoxesChangeEvent<D = any> {\n statBoxes: PghChartStatBox<D>[];\n indexes: number[];\n}\n\nexport type PghChartYAxisTooltipFormatter = (\n data: TooltipFormatterContextObject,\n) => string | number | null | undefined;\n\nexport class PghChartStatBox<D = any> {\n isActive = false;\n get inputData(): D {\n return this.markerDirective.statBoxData();\n }\n constructor(\n public markerDirective: PghChartStatBoxDirective,\n public index: number,\n public color: string,\n ) {}\n}\n\nexport type PghChartYAxisTooltip =\n | PghChartYAxisTooltipFormat\n | string\n | PghChartYAxisTooltipFormatter;\n\nexport interface PghSimpleHighchartsSeries<D = PghSimpleChartData> {\n name: string;\n data: D;\n type?: 'areaspline' | 'column' | 'pie' | 'map';\n yAxis?: number;\n tooltip?: PghChartYAxisTooltip;\n}\n\nexport interface PghFullChartYAxis {\n labels?: {\n format?: string;\n };\n opposite?: boolean;\n}\n\nexport type PghSimpleChartData = number[];\nexport type PghPieChartData = { name: string; y: number }[];\n\nexport interface PghGlobalChartOptions {\n disableChartBoxScroll?: boolean;\n maxActiveChartBoxes?: PghMaxActiveChartBox;\n fullChartTooltip?: { xAxis?: PghChartXAxisTooltipFormat; yAxis?: PghChartYAxisTooltipFormat };\n}\n\nexport type PghMaxActiveChartBox = number | 'infinite';\n\nexport interface PghMapChartDataItem {\n id?: string;\n name: string;\n value: number | null;\n tooltipValue: string | number;\n changed: boolean;\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[pgh-chart-date-range-picker]',\n standalone: false,\n})\nexport class PghChartDateRangePickerDirective {\n constructor() {}\n}\n","import { Directive } from '@angular/core';\n\n@Directive({\n selector: '[pgh-chart-header]',\n standalone: false,\n})\nexport class PghChartHeaderDirective {\n constructor() {}\n}\n","import {\n AfterContentChecked,\n AfterContentInit,\n Component,\n ContentChild,\n ContentChildren,\n ElementRef,\n Inject,\n input,\n model,\n OnChanges,\n OnInit,\n output,\n QueryList,\n signal,\n SimpleChanges,\n ViewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { PghFilterChipsComponent } from '@tapsellorg/angular-material-library/src/lib/filter-chips';\nimport { PghChartColorsService } from '../chart-colors.service';\nimport { PghChartStatBoxDirective } from '../chart-stat-box.directive';\nimport { PghStatBoxService } from '../statbox.service';\nimport {\n PghChartActiveStatBoxesChangeEvent,\n PghChartStatBox,\n PghGlobalChartOptions,\n PghMaxActiveChartBox,\n} from '../models';\nimport { withDestroy } from '@tapsellorg/angular-material-library/src/lib/common';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { PGH_CHART_OPTIONS } from '../configs';\nimport { PghChartDateRangePickerDirective } from '../chart-date-range-picker.directive';\nimport { PghChartHeaderDirective } from '../chart-header.directive';\n\n@Component({\n selector: 'pgh-chart-box',\n templateUrl: './chart-box.component.html',\n styleUrls: ['./chart-box.component.scss'],\n encapsulation: ViewEncapsulation.None,\n providers: [PghStatBoxService],\n standalone: false,\n})\nexport class PghChartBoxComponent\n extends withDestroy()\n implements OnInit, AfterContentChecked, AfterContentInit, OnChanges\n{\n @ContentChildren(PghChartStatBoxDirective)\n statBoxesDirectives?: QueryList<PghChartStatBoxDirective>;\n @ContentChild(PghFilterChipsComponent) filterChipsComponent?: PghFilterChipsComponent;\n chartTitle = input<string>();\n activeMax = model<PghMaxActiveChartBox>(1);\n colors = input<string[] | undefined>();\n disableChartBoxScroll = model<boolean>(false);\n activeStatBoxesChange = output<PghChartActiveStatBoxesChangeEvent>();\n @ViewChild('statBoxesScroller', { static: true }) statBoxesScroller?: ElementRef<HTMLDivElement>;\n @ContentChild(PghChartDateRangePickerDirective)\n dateRangePickerDirective = PghChartDateRangePickerDirective;\n @ContentChild(PghChartHeaderDirective) headerDirective?: PghChartHeaderDirective;\n displayStatBoxesVertically = input<boolean>(false);\n\n isContainerOverflown = signal<boolean>(false);\n isContainerAtStart = signal(true);\n isContainerAtEnd = signal(false);\n\n constructor(\n public statBoxService: PghStatBoxService,\n private chartColorsService: PghChartColorsService,\n @Inject(PGH_CHART_OPTIONS) chartOptions: PghGlobalChartOptions,\n ) {\n super();\n this.activeMax.set(chartOptions.maxActiveChartBoxes ?? this.activeMax());\n this.disableChartBoxScroll.set(\n chartOptions.disableChartBoxScroll ?? this.disableChartBoxScroll(),\n );\n }\n\n ngOnInit(): void {\n this.handleActiveMaxChange();\n let noDuplicate$ = this.statBoxService.$activeStatBoxes.pipe(\n takeUntil(this._destroyed$),\n distinctUntilChanged(),\n );\n\n if (this.activeMax() === 'infinite' || Number(this.activeMax()) > 2) {\n noDuplicate$ = noDuplicate$.pipe(debounceTime(700));\n }\n\n noDuplicate$.subscribe(activeStatBoxes => {\n this.activeStatBoxesChange.emit({\n statBoxes: activeStatBoxes.map(sb => sb),\n indexes: activeStatBoxes.map(sb => sb.index),\n });\n });\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (changes.color && this.colors()) {\n this.chartColorsService.updateColors(this.colors()!);\n }\n if (changes.activeMax) {\n this.handleActiveMaxChange();\n }\n }\n\n private handleActiveMaxChange() {\n if (this.activeMax() === 'infinite') {\n this.activeMax.set(999999999999999);\n } else if (Number(this.activeMax()) < 1) {\n this.activeMax.set(1);\n }\n }\n\n ngAfterContentInit() {\n this.statBoxesTemplateChanged();\n\n this.statBoxesDirectives?.changes.pipe(takeUntil(this._destroyed$)).subscribe(() => {\n this.statBoxesTemplateChanged();\n });\n }\n\n ngAfterContentChecked(): void {\n this.isContainerOverflown.set(this.isStatBoxesContainerOverflown());\n }\n\n private statBoxesTemplateChanged() {\n this.updateStatBoxesBasedOnDirectives();\n\n const { activeStatBoxes } = this.statBoxService;\n if (!activeStatBoxes.length && this.statBoxService.statBoxes.length) {\n this.changeStatBoxActiveState(this.statBoxService.statBoxes[0]);\n }\n }\n\n private updateStatBoxesBasedOnDirectives() {\n if (!this.statBoxesDirectives) return;\n\n this.statBoxService.statBoxes = this.statBoxesDirectives.map((directive, i) => {\n const existingStatBoxWithSameId = this.statBoxService.statBoxes.find(\n sb => sb.markerDirective.statBoxData() === directive.statBoxData(),\n );\n return (\n existingStatBoxWithSameId ??\n new PghChartStatBox(directive, i, this.chartColorsService.getStatBoxColor(i))\n );\n });\n }\n\n changeStatBoxActiveState(statBox: PghChartStatBox, statBoxContainerElm?: HTMLDivElement) {\n const activeCount = this.statBoxService.activeStatBoxes.length;\n\n if (this.activeMax() === 1) {\n if (statBox.isActive) return;\n this.statBoxService.setOnlyActiveStatBox(statBox);\n this.scrollIntoView(statBoxContainerElm);\n return;\n }\n\n const canChangeState =\n this.activeMax() === 'infinite' ||\n activeCount < Number(this.activeMax()) ||\n (statBox.isActive && activeCount > 1);\n if (!canChangeState) return;\n\n if (statBox.isActive) {\n this.statBoxService.removeActiveStatBox(statBox);\n } else {\n this.statBoxService.addActiveStatBox(statBox);\n this.scrollIntoView(statBoxContainerElm);\n }\n }\n\n shift(direction: number) {\n if (\n !this.statBoxesScroller ||\n (direction === 1 && this.isContainerAtStart()) ||\n (direction === -1 && this.isContainerAtEnd())\n )\n return;\n this.statBoxesScroller.nativeElement.scrollBy({ left: direction * 300 });\n }\n\n isStatBoxesContainerOverflown(): boolean {\n if (!this.statBoxesScroller || this.disableChartBoxScroll()) {\n return false;\n }\n\n const element = this.statBoxesScroller.nativeElement;\n return element.scrollWidth > element.clientWidth;\n }\n\n scrollIntoView(element: HTMLElement | undefined) {\n if (!element) return;\n element.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'center',\n });\n }\n\n statBoxContainerScrollHandler(): void {\n if (!this.statBoxesScroller) return;\n const element = this.statBoxesScroller.nativeElement;\n this.isContainerAtStart.set(!element.scrollLeft);\n this.isContainerAtEnd.set(element.scrollWidth + element.scrollLeft === element.clientWidth);\n }\n}\n","<div class=\"pgh-chart-box\" [class.pgh-chart-box-vertical-stats]=\"displayStatBoxesVertically()\">\n <div class=\"pgh-chart-box-header\">\n <div class=\"pgh-chart-box-header-section\" [hidden]=\"!chartTitle() && !headerDirective\">\n @if (chartTitle()) {\n <h4>{{ chartTitle() }}</h4>\n }\n <ng-content select=\"[pgh-chart-header]\"></ng-content>\n </div>\n <div class=\"pgh-chart-box-header-section\" [hidden]=\"!dateRangePickerDirective\">\n <ng-content select=\"[pgh-chart-date-range-picker]\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"pgh-filters-wrapper\"\n [hidden]=\"!filtersWrapperRef.innerHTML.trim() && !actionButtonsWrapperRef.innerHTML.trim()\"\n >\n <div #filtersWrapperRef>\n <ng-content select=\"pgh-filter-chips\"></ng-content>\n <ng-content select=\"[pgh-chart-filters]\"></ng-content>\n </div>\n <div #actionButtonsWrapperRef class=\"pgh-action-buttons\">\n <ng-content select=\"[pgh-action-buttons]\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"pgh-stats-container\"\n [hidden]=\"!statBoxService.statBoxes.length\"\n [class.pgh-chart-box-no-scroll-stats]=\"disableChartBoxScroll()\"\n >\n <div class=\"pgh-chart-stat-boxes\">\n <div\n #statBoxesScroller\n class=\"pgh-chart-stat-scroller\"\n [class.pgh-chart-stat-boxes-overflow]=\"isContainerOverflown()\"\n (scroll)=\"statBoxContainerScrollHandler()\"\n >\n @for (sb of statBoxService.statBoxes; track sb) {\n <div\n class=\"pgh-stat-box-container\"\n [class.pgh-is-active]=\"sb.isActive\"\n #statBoxContainerElm\n (click)=\"changeStatBoxActiveState(sb, statBoxContainerElm)\"\n [style.--chart-stat-box-bg-color]=\"sb.color\"\n >\n <ng-container\n *ngTemplateOutlet=\"sb.markerDirective.template; context: { isActive: sb.isActive }\"\n ></ng-container>\n </div>\n }\n </div>\n </div>\n @if (isContainerOverflown()) {\n <div\n class=\"pgh-slide-button pgh-chart-stat-boxes-slide-right\"\n [class.pgh-disabled]=\"isContainerAtStart()\"\n (click)=\"shift(1)\"\n >\n <mat-icon svgIcon=\"chevron_right\"></mat-icon>\n </div>\n } @if (isContainerOverflown()) {\n <div\n class=\"pgh-slide-button pgh-chart-stat-boxes-slide-left\"\n [class.pgh-disabled]=\"isContainerAtEnd()\"\n (click)=\"shift(-1)\"\n >\n <mat-icon svgIcon=\"chevron_left\"></mat-icon>\n </div>\n }\n </div>\n\n <div class=\"pgh-chart-container\">\n <ng-content></ng-content>\n </div>\n</div>\n","import {\n Component,\n Input,\n ViewEncapsulation,\n DEFAULT_CURRENCY_CODE,\n Inject,\n LOCALE_ID,\n input,\n signal,\n} from '@angular/core';\nimport { getCurrencySymbol } from '@angular/common';\n\n@Component({\n selector: 'pgh-chart-stat-box',\n templateUrl: './chart-stat-box.component.html',\n styleUrls: ['./chart-stat-box.component.scss'],\n encapsulation: ViewEncapsulation.None,\n standalone: false,\n})\nexport class PghChartStatBoxComponent {\n name = input.required<string>();\n value = input<number | undefined>();\n valueType = input<'number' | 'percent' | 'currency'>('number');\n tooltip = input<string | undefined>();\n\n currencyCode = signal<string | undefined>(undefined);\n\n constructor(\n @Inject(DEFAULT_CURRENCY_CODE) private defaultCurrencyCode: string,\n @Inject(LOCALE_ID) private localeId: string,\n ) {\n this.currencyCode.set(getCurrencySymbol(this.defaultCurrencyCode, 'wide', localeId));\n }\n}\n","<div class=\"pgh-chart-stat-box\" matRipple>\n <div class=\"pgh-chart-stat-title\">\n <span>{{ name() }}</span>\n <pgh-help-indicator [tooltip]=\"tooltip()\" class=\"ms-2\"></pgh-help-indicator>\n </div>\n <div class=\"pgh-chart-stat-value\">\n @if (valueType() === 'number') {\n {{ value() | number }}\n } @if (valueType() === 'percent') {\n {{ value() | percent : '.0-2' }}\n } @if (valueType() === 'currency') {\n <span>{{ value() | number }}</span>\n <span class=\"pgh-chart-stat-box-currency-label\">{{ currencyCode() }}</span>\n }\n <ng-content></ng-content>\n </div>\n</div>\n","import {\n AfterViewChecked,\n Component,\n ElementRef,\n input,\n model,\n OnChanges,\n Optional,\n signal,\n SimpleChanges,\n ViewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { StringUtils } from '@tapsellorg/angular-material-library/src/lib/common';\nimport * as Highcharts from 'highcharts';\nimport { Point } from 'highcharts';\nimport { PghChartYAxisTooltipFormat, PghPieChartData, PghSimpleHighchartsSeries } from '../models';\nimport { PghChartTooltipService } from '../chart-tooltip.service';\nimport { ChartParent } from '../chart-parent';\nimport { PghChartColorsService } from '../chart-colors.service';\nimport { PghStatBoxService } from '../statbox.service';\n\n@Component({\n selector: 'pgh-pie-chart',\n templateUrl: './pie-chart.component.html',\n styleUrls: ['./pie-chart.component.scss'],\n encapsulation: ViewEncapsulation.None,\n standalone: false,\n})\nexport class PghPieChartComponent extends ChartParent implements OnChanges, AfterViewChecked {\n chartOptions = signal<Highcharts.Options>({});\n userCustomChartOptions = input<Highcharts.Options>(\n {},\n {\n alias: 'customChartOptions',\n },\n );\n series = input<PghSimpleHighchartsSeries<PghPieChartData>[]>([]);\n\n tooltip = model<string | PghChartYAxisTooltipFormat | null>('percent-pie');\n\n pieType = input<'donut' | 'pie'>('pie');\n defaultSeriesType = signal<string>('pie');\n @ViewChild('chartWrapperRef') chartWrapper?: ElementRef<HTMLDivElement>;\n private lastChartWrapperWidth?: number;\n private chartInstance?: Highcharts.Chart;\n\n protected CHART_PLACEHOLDER_SERIES = [\n { name: 'Mobile', value: 1100, type: 'pie' },\n { name: 'Tablet', value: 3200, type: 'pie' },\n ];\n constructor(\n protected chartTooltipService: PghChartTooltipService,\n protected chartColorsService: PghChartColorsService,\n @Optional() protected statBoxService?: PghStatBoxService,\n ) {\n super();\n }\n\n ngOnChanges(_changes: SimpleChanges) {\n this.configureChartOptions();\n }\n\n ngAfterViewChecked() {\n this.handleChartReflow();\n }\n\n private handleChartReflow() {\n if (\n !this.chartInstance ||\n this.lastChartWrapperWidth === this.chartWrapper?.nativeElement.offsetWidth\n )\n return;\n\n this.lastChartWrapperWidth = this.chartWrapper?.nativeElement.offsetWidth;\n setTimeout(() => {\n this.chartInstance?.reflow();\n });\n }\n\n configureChartOptions() {\n this.chartOptions.set(\n this.createChartOptions({\n chart: { className: 'pie-chart', type: 'pie' },\n plotOptions: {\n pie: {\n dataLabels: {\n enabled: false,\n },\n showInLegend: true,\n innerSize: this.pieType() === 'pie' ? '0' : '80%',\n },\n },\n legend: {\n useHTML: true,\n labelFormatter() {\n const { color, percentage } = this as Point;\n const percentageLabel = StringUtils.convertEnglishNumbersToPersian(\n `${Math.round(Number(percentage))}٪`,\n );\n return `<div class=\"custom-highcharts-legend\">\n <div class=\"legend-percentage\" style=\"color:${String(color)}\">${percentageLabel}</div>\n <div class=\"legend-title\">${this.name}</div>\n </div>`;\n },\n },\n }),\n );\n }\n\n onSetChartInstance(chartInstance: Highcharts.Chart) {\n this.chartInstance = chartInstance;\n }\n}\n","<div #chartWrapperRef class=\"pgh-chart-wrapper\">\n <div class=\"pgh-chart-content\" [class.pgh-chart-no-data]=\"hasNoData\">\n <highcharts-chart\n [Highcharts]=\"highcharts\"\n constructorType=\"chart\"\n [options]=\"chartOptions()\"\n [oneToOne]=\"true\"\n [runOutsideAngular]=\"true\"\n (chartInstance)=\"onSetChartInstance($event)\"\n class=\"pgh-pie-chart w-100 d-block\"\n ></highcharts-chart>\n </div>\n</div>\n","import { CommonModule, CurrencyPipe, DecimalPipe, PercentPipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ObserversModule } from '@angular/cdk/observers';\nimport { HighchartsChartModule } from 'highcharts-angular';\nimport { PghHelpIndicatorModule } from '@tapsellorg/angular-material-library/src/lib/help-indicator';\nimport { PghMiniChartComponent } from './mini-chart/mini-chart.component';\nimport { PghFullChartComponent } from './full-chart/full-chart.component';\nimport { PghMapChartComponent } from './map-chart/map-chart.component';\nimport { PghChartBoxComponent } from './chart-box/chart-box.component';\nimport { PghChartStatBoxDirective } from './chart-stat-box.directive';\nimport { PghChartStatBoxComponent } from './chart-stat-box/chart-stat-box.component';\nimport { PghPieChartComponent } from './pie-chart/pie-chart.component';\nimport { MatRippleModule } from '@angular/material/core';\nimport { PghChartDateRangePickerDirective } from './chart-date-range-picker.directive';\nimport { PghChartHeaderDirective } from './chart-header.directive';\nimport { MatIconModule } from '@angular/material/icon';\nimport { TranslateModule } from '@tapsellorg/angular-material-library/src/lib/translate';\n\n@NgModule({\n declarations: [\n PghMiniChartComponent,\n PghMapChartComponent,\n PghFullChartComponent,\n PghChartBoxComponent,\n PghChartStatBoxComponent,\n PghChartStatBoxDirective,\n PghPieChartComponent,\n PghChartDateRangePickerDirective,\n PghChartHeaderDirective,\n ],\n imports: [\n CommonModule,\n MatRippleModule,\n HighchartsChartModule,\n PghHelpIndicatorModule,\n ObserversModule,\n MatIconModule,\n TranslateModule,\n ],\n exports: [\n PghMiniChartComponent,\n PghFullChartComponent,\n PghMapChartComponent,\n PghChartBoxComponent,\n PghChartStatBoxComponent,\n PghChartStatBoxDirective,\n PghPieChartComponent,\n PghChartDateRangePickerDirective,\n PghChartHeaderDirective,\n ],\n providers: [DecimalPipe, PercentPipe, CurrencyPipe],\n})\nexport class PghChartModule {}\n","import {\n PghChartYAxisTooltip,\n PghMapChartDataItem,\n PghPieChartData,\n PghSimpleHighchartsSeries,\n} from './models';\n\n// @dynamic\nexport class PghChartUtils {\n static getChartSeries<T>(\n data: T[],\n seriesOptions: {\n name: string;\n dataGetter: (item: T) => number;\n yAxis?: number;\n tooltip?: PghChartYAxisTooltip;\n },\n ): PghSimpleHighchartsSeries {\n const modifiedData = data.map(item => seriesOptions.dataGetter(item));\n if (seriesOptions.tooltip === 'percent') {\n modifiedData.forEach((value, index) => {\n modifiedData[index] = value * 100;\n });\n }\n\n return {\n name: seriesOptions.name,\n yAxis: seriesOptions.yAxis,\n data: modifiedData,\n tooltip: seriesOptions.tooltip,\n };\n }\n\n static getPieChartSeries<T>(\n data: T[],\n seriesOptions: {\n name: string;\n dataGetter: (item: T) => { name: string; y: number };\n tooltip?: PghChartYAxisTooltip;\n },\n ): PghSimpleHighchartsSeries<PghPieChartData> {\n return {\n name: seriesOptions.name,\n type: 'pie',\n data: data.map(item => seriesOptions.dataGetter(item)),\n tooltip: seriesOptions.tooltip,\n };\n }\n static getMapChartSeries(\n data: PghMapChartDataItem[],\n options: {\n name: string;\n yAxis?: number;\n tooltip?: PghChartYAxisTooltip;\n },\n ): PghSimpleHighchartsSeries<PghMapChartDataItem[]> {\n return {\n type: 'map',\n name: options.name,\n yAxis: options.yAxis,\n tooltip: options.tooltip,\n data,\n };\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.PghChartTooltipService","i2.PghChartColorsService","i3.PghStatBoxService","i1.PghStatBoxService","i2","i3","i4","i1"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AASA,aAAa,CAAC,UAAU,CAAC;MAEH,WAAW,CAAA;AAAjC,IAAA,WAAA,GAAA;QACE,IAAU,CAAA,UAAA,GAAG,UAAU;AAQvB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAA2C,IAAI,CAAC;;AAEhE,IAAA,IAAI,SAAS,GAAA;AACX,QAAA,QACE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM;aACrB,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,CAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAS,CAAC,IAAI,EAAE,MAAM,CAAC;YACvE,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,wBAAwB;;AAIzC,IAAA,mBAAmB,CAAC,KAAa,EAAA;AACzC,QAAA,MAAM,eAAe,GAAG,IAAI,CAAC,cAAc,EAAE,eAAe;AAE5D,QAAA,IAAI,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE;YACxE,OAAO,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,KAAK,CAAC;;AAG3D,QAAA,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,KAAK;;IAG3B,cAAc,GAAA;AACtB,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;YAClB,OAAO,IAAI,CAAC,wBAAwB;;AAGtC,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM;AAC1C,YAAA,GAAG,CAAC;YACJ,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE;AACxC,YAAA,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;AACpB,YAAA,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACnC,SAAA,CAAC,CAAC;;AAGK,IAAA,kBAAkB,CAAC,aAAiC,EAAA;AAC5D,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,EAAE;AACnD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE;QAEpC,OAAO,WAAW,CAAC,SAAS,CAC1B;AACE,YAAA,KAAK,EAAE;AACL,gBAAA,eAAe,EAAE,YAAY;AAC7B,gBAAA,KAAK,EAAE;AACL,oBAAA,UAAU,EAAE,SAAS;AACtB,iBAAA;AACF,aAAA;AACD,YAAA,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,WAAW;AAC3C,YAAA,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;AAC1B,YAAA,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;AAC3B,YAAA,OAAO,EAAE;AACP,gBAAA,WAAW,EAAE,CAAC;AACd,gBAAA,eAAe,EAAE,EAAE;AACnB,gBAAA,OAAO,EAAE,IAAI;gBACb,SAAS,GAAA;AACP,oBAAA,OAAO,gBAAgB,CAAC,IAAI,CAAC;iBAC9B;AACD,gBAAA,MAAM,EAAE,IAAI;AACb,aAAA;AACD,YAAA,MAAM,EAAE;AACN,gBAAA,SAAS,EAAE;AACT,oBAAA,MAAM,EAAE,SAAS;AACjB,oBAAA,WAAW,EAAE,MAAM;AACnB,oBAAA,aAAa,EAAE,MAAM;AACrB,oBAAA,KAAK,EAAE,YAAY;AACnB,oBAAA,IAAI,EAAE,YAAY;AACnB,iBAAA;AACF,aAAA;YACD,MAAM;AACe,SAAA,EACvB,aAAa,EACb,IAAI,CAAC,sBAAsB,EAAE,CAC9B;;IAGO,mBAAmB,GAAA;QAC3B,IAAI,OAAO,IAAI