@ojiepermana/angular-chart 22.0.27

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.
Files changed (32) hide show
  1. package/README.md +249 -0
  2. package/fesm2022/ojiepermana-angular-chart-area.mjs +266 -0
  3. package/fesm2022/ojiepermana-angular-chart-area.mjs.map +1 -0
  4. package/fesm2022/ojiepermana-angular-chart-bar.mjs +674 -0
  5. package/fesm2022/ojiepermana-angular-chart-bar.mjs.map +1 -0
  6. package/fesm2022/ojiepermana-angular-chart-core.mjs +764 -0
  7. package/fesm2022/ojiepermana-angular-chart-core.mjs.map +1 -0
  8. package/fesm2022/ojiepermana-angular-chart-line.mjs +281 -0
  9. package/fesm2022/ojiepermana-angular-chart-line.mjs.map +1 -0
  10. package/fesm2022/ojiepermana-angular-chart-pie.mjs +248 -0
  11. package/fesm2022/ojiepermana-angular-chart-pie.mjs.map +1 -0
  12. package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1186 -0
  13. package/fesm2022/ojiepermana-angular-chart-primitives.mjs.map +1 -0
  14. package/fesm2022/ojiepermana-angular-chart-radar.mjs +329 -0
  15. package/fesm2022/ojiepermana-angular-chart-radar.mjs.map +1 -0
  16. package/fesm2022/ojiepermana-angular-chart-radial.mjs +255 -0
  17. package/fesm2022/ojiepermana-angular-chart-radial.mjs.map +1 -0
  18. package/fesm2022/ojiepermana-angular-chart-scatter.mjs +253 -0
  19. package/fesm2022/ojiepermana-angular-chart-scatter.mjs.map +1 -0
  20. package/fesm2022/ojiepermana-angular-chart.mjs +20 -0
  21. package/fesm2022/ojiepermana-angular-chart.mjs.map +1 -0
  22. package/package.json +76 -0
  23. package/types/ojiepermana-angular-chart-area.d.ts +58 -0
  24. package/types/ojiepermana-angular-chart-bar.d.ts +171 -0
  25. package/types/ojiepermana-angular-chart-core.d.ts +369 -0
  26. package/types/ojiepermana-angular-chart-line.d.ts +57 -0
  27. package/types/ojiepermana-angular-chart-pie.d.ts +93 -0
  28. package/types/ojiepermana-angular-chart-primitives.d.ts +265 -0
  29. package/types/ojiepermana-angular-chart-radar.d.ts +89 -0
  30. package/types/ojiepermana-angular-chart-radial.d.ts +86 -0
  31. package/types/ojiepermana-angular-chart-scatter.d.ts +95 -0
  32. package/types/ojiepermana-angular-chart.d.ts +2 -0
@@ -0,0 +1,248 @@
1
+ import { pie, arc } from 'd3-shape';
2
+ import { seriesColorVar, ChartContext } from '@ojiepermana/angular-chart/core';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, input, output, computed, ChangeDetectionStrategy, Component } from '@angular/core';
5
+
6
+ function computePieLayout(input) {
7
+ const { data, valueKey, nameKey, seriesKeys, innerWidth, innerHeight, innerRadius, padAngle, cornerRadius, startAngle, endAngle, activeIndex, activeOffset = 12, } = input;
8
+ const outerRadius = Math.max(0, Math.min(innerWidth, innerHeight) / 2);
9
+ const centerX = innerWidth / 2;
10
+ const centerY = innerHeight / 2;
11
+ if (data.length === 0 || outerRadius === 0) {
12
+ return { slices: [], centerX, centerY, outerRadius };
13
+ }
14
+ const pieGen = pie()
15
+ .value((d) => Number(d[valueKey] ?? 0))
16
+ .sort(null)
17
+ .padAngle(padAngle)
18
+ .startAngle(startAngle)
19
+ .endAngle(endAngle);
20
+ const arcGen = arc()
21
+ .innerRadius(innerRadius)
22
+ .outerRadius(outerRadius)
23
+ .cornerRadius(cornerRadius);
24
+ const arcs = pieGen(data);
25
+ const slices = arcs.map((a, i) => {
26
+ const d = a.data;
27
+ const key = seriesKeys?.[i] ?? String(d[nameKey] ?? i);
28
+ const centroid = arcGen.centroid(a);
29
+ const magnitude = Math.hypot(centroid[0], centroid[1]) || 1;
30
+ const isActive = i === activeIndex;
31
+ return {
32
+ seriesKey: key,
33
+ name: String(d[nameKey] ?? key),
34
+ value: Number(d[valueKey] ?? 0),
35
+ datumIndex: i,
36
+ color: seriesColorVar(key),
37
+ arcPath: arcGen(a) ?? '',
38
+ centroid,
39
+ startAngle: a.startAngle,
40
+ endAngle: a.endAngle,
41
+ translateX: isActive ? (centroid[0] / magnitude) * activeOffset : 0,
42
+ translateY: isActive ? (centroid[1] / magnitude) * activeOffset : 0,
43
+ };
44
+ });
45
+ return { slices, centerX, centerY, outerRadius };
46
+ }
47
+
48
+ const DEFAULT_MARGIN = { top: 8, right: 8, bottom: 8, left: 8 };
49
+ class PieChart {
50
+ root = inject(ChartContext);
51
+ data = input.required(/* @ts-ignore */
52
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
53
+ valueKey = input.required(/* @ts-ignore */
54
+ ...(ngDevMode ? [{ debugName: "valueKey" }] : /* istanbul ignore next */ []));
55
+ nameKey = input.required(/* @ts-ignore */
56
+ ...(ngDevMode ? [{ debugName: "nameKey" }] : /* istanbul ignore next */ []));
57
+ seriesKeys = input(undefined, /* @ts-ignore */
58
+ ...(ngDevMode ? [{ debugName: "seriesKeys" }] : /* istanbul ignore next */ []));
59
+ styles = input('base', /* @ts-ignore */
60
+ ...(ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []));
61
+ margin = input(DEFAULT_MARGIN, /* @ts-ignore */
62
+ ...(ngDevMode ? [{ debugName: "margin" }] : /* istanbul ignore next */ []));
63
+ innerRadius = input(0, /* @ts-ignore */
64
+ ...(ngDevMode ? [{ debugName: "innerRadius" }] : /* istanbul ignore next */ []));
65
+ padAngle = input(0.01, /* @ts-ignore */
66
+ ...(ngDevMode ? [{ debugName: "padAngle" }] : /* istanbul ignore next */ []));
67
+ cornerRadius = input(0, /* @ts-ignore */
68
+ ...(ngDevMode ? [{ debugName: "cornerRadius" }] : /* istanbul ignore next */ []));
69
+ startAngle = input(-Math.PI / 2, /* @ts-ignore */
70
+ ...(ngDevMode ? [{ debugName: "startAngle" }] : /* istanbul ignore next */ []));
71
+ endAngle = input((3 * Math.PI) / 2, /* @ts-ignore */
72
+ ...(ngDevMode ? [{ debugName: "endAngle" }] : /* istanbul ignore next */ []));
73
+ showLabels = input(false, /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "showLabels" }] : /* istanbul ignore next */ []));
75
+ activeIndex = input(undefined, /* @ts-ignore */
76
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
77
+ activeOffset = input(12, /* @ts-ignore */
78
+ ...(ngDevMode ? [{ debugName: "activeOffset" }] : /* istanbul ignore next */ []));
79
+ sliceClick = output();
80
+ innerWidth = computed(() => Math.max(0, this.root.dimensions().width - this.margin().left - this.margin().right), /* @ts-ignore */
81
+ ...(ngDevMode ? [{ debugName: "innerWidth" }] : /* istanbul ignore next */ []));
82
+ innerHeight = computed(() => Math.max(0, this.root.dimensions().height - this.margin().top - this.margin().bottom), /* @ts-ignore */
83
+ ...(ngDevMode ? [{ debugName: "innerHeight" }] : /* istanbul ignore next */ []));
84
+ layout = computed(() => computePieLayout({
85
+ data: this.data(),
86
+ valueKey: this.valueKey(),
87
+ nameKey: this.nameKey(),
88
+ seriesKeys: this.seriesKeys(),
89
+ innerWidth: this.innerWidth(),
90
+ innerHeight: this.innerHeight(),
91
+ innerRadius: this.innerRadius(),
92
+ padAngle: this.padAngle(),
93
+ cornerRadius: this.cornerRadius(),
94
+ startAngle: this.startAngle(),
95
+ endAngle: this.endAngle(),
96
+ activeIndex: this.activeIndex(),
97
+ activeOffset: this.activeOffset(),
98
+ }), /* @ts-ignore */
99
+ ...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
100
+ viewBox = computed(() => {
101
+ const { width, height } = this.root.dimensions();
102
+ return `0 0 ${Math.max(0, width)} ${Math.max(0, height)}`;
103
+ }, /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
105
+ innerTransform = computed(() => `translate(${this.margin().left},${this.margin().top})`, /* @ts-ignore */
106
+ ...(ngDevMode ? [{ debugName: "innerTransform" }] : /* istanbul ignore next */ []));
107
+ ariaSummary = computed(() => `Pie chart, ${this.data().length} slices.`, /* @ts-ignore */
108
+ ...(ngDevMode ? [{ debugName: "ariaSummary" }] : /* istanbul ignore next */ []));
109
+ sliceAriaLabel(s) {
110
+ return `${s.name}: ${s.value}`;
111
+ }
112
+ sliceTransform(s) {
113
+ return s.translateX || s.translateY ? `translate(${s.translateX}, ${s.translateY})` : null;
114
+ }
115
+ emitClick(s) {
116
+ this.sliceClick.emit({
117
+ seriesKey: s.seriesKey,
118
+ name: s.name,
119
+ value: s.value,
120
+ datumIndex: s.datumIndex,
121
+ datum: this.data()[s.datumIndex],
122
+ });
123
+ }
124
+ setActive(event, s) {
125
+ const clientX = event instanceof PointerEvent ? event.clientX : event.target.getBoundingClientRect().left;
126
+ const clientY = event instanceof PointerEvent ? event.clientY : event.target.getBoundingClientRect().top;
127
+ this.root.activePoint.set({
128
+ index: s.datumIndex,
129
+ datumIndex: s.datumIndex,
130
+ seriesKey: s.seriesKey,
131
+ clientX,
132
+ clientY,
133
+ });
134
+ }
135
+ clearActive() {
136
+ this.root.activePoint.set(null);
137
+ }
138
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
139
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.2", type: PieChart, isStandalone: true, selector: "ChartPie", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: true, transformFunction: null }, nameKey: { classPropertyName: "nameKey", publicName: "nameKey", isSignal: true, isRequired: true, transformFunction: null }, seriesKeys: { classPropertyName: "seriesKeys", publicName: "seriesKeys", isSignal: true, isRequired: false, transformFunction: null }, styles: { classPropertyName: "styles", publicName: "styles", isSignal: true, isRequired: false, transformFunction: null }, margin: { classPropertyName: "margin", publicName: "margin", isSignal: true, isRequired: false, transformFunction: null }, innerRadius: { classPropertyName: "innerRadius", publicName: "innerRadius", isSignal: true, isRequired: false, transformFunction: null }, padAngle: { classPropertyName: "padAngle", publicName: "padAngle", isSignal: true, isRequired: false, transformFunction: null }, cornerRadius: { classPropertyName: "cornerRadius", publicName: "cornerRadius", isSignal: true, isRequired: false, transformFunction: null }, startAngle: { classPropertyName: "startAngle", publicName: "startAngle", isSignal: true, isRequired: false, transformFunction: null }, endAngle: { classPropertyName: "endAngle", publicName: "endAngle", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, activeOffset: { classPropertyName: "activeOffset", publicName: "activeOffset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sliceClick: "sliceClick" }, host: { properties: { "attr.data-style": "styles()" }, classAttribute: "relative block h-full w-full" }, ngImport: i0, template: `
140
+ <svg:svg
141
+ class="block h-full w-full overflow-visible"
142
+ [attr.viewBox]="viewBox()"
143
+ preserveAspectRatio="xMidYMid meet"
144
+ role="img"
145
+ [attr.aria-label]="ariaSummary()">
146
+ <svg:g [attr.transform]="innerTransform()">
147
+ <svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
148
+ @for (s of layout().slices; track s.seriesKey) {
149
+ <svg:path
150
+ class="chart-slice cursor-pointer transition-opacity hover:opacity-80"
151
+ [attr.d]="s.arcPath"
152
+ [attr.fill]="s.color"
153
+ [attr.transform]="sliceTransform(s)"
154
+ [attr.aria-label]="sliceAriaLabel(s)"
155
+ tabindex="0"
156
+ (click)="emitClick(s)"
157
+ (keydown.enter)="emitClick(s)"
158
+ (keydown.space)="emitClick(s); $event.preventDefault()"
159
+ (pointerenter)="setActive($event, s)"
160
+ (pointermove)="setActive($event, s)"
161
+ (pointerleave)="clearActive()"
162
+ (focus)="setActive($event, s)"
163
+ (blur)="clearActive()" />
164
+ }
165
+ @if (showLabels()) {
166
+ @for (s of layout().slices; track s.seriesKey) {
167
+ <svg:text
168
+ class="chart-slice-label fill-foreground text-2xs"
169
+ text-anchor="middle"
170
+ dominant-baseline="middle"
171
+ [attr.x]="s.centroid[0] + s.translateX"
172
+ [attr.y]="s.centroid[1] + s.translateY">
173
+ {{ s.value }}
174
+ </svg:text>
175
+ }
176
+ }
177
+ </svg:g>
178
+ </svg:g>
179
+ </svg:svg>
180
+ <div class="pointer-events-none absolute inset-0 flex items-center justify-center">
181
+ <ng-content select="ChartPieCenter" />
182
+ </div>
183
+ <ng-content select="ChartTooltip" />
184
+ <ng-content select="ChartLegend" />
185
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
186
+ }
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PieChart, decorators: [{
188
+ type: Component,
189
+ args: [{
190
+ selector: 'ChartPie',
191
+ changeDetection: ChangeDetectionStrategy.OnPush,
192
+ host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
193
+ template: `
194
+ <svg:svg
195
+ class="block h-full w-full overflow-visible"
196
+ [attr.viewBox]="viewBox()"
197
+ preserveAspectRatio="xMidYMid meet"
198
+ role="img"
199
+ [attr.aria-label]="ariaSummary()">
200
+ <svg:g [attr.transform]="innerTransform()">
201
+ <svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
202
+ @for (s of layout().slices; track s.seriesKey) {
203
+ <svg:path
204
+ class="chart-slice cursor-pointer transition-opacity hover:opacity-80"
205
+ [attr.d]="s.arcPath"
206
+ [attr.fill]="s.color"
207
+ [attr.transform]="sliceTransform(s)"
208
+ [attr.aria-label]="sliceAriaLabel(s)"
209
+ tabindex="0"
210
+ (click)="emitClick(s)"
211
+ (keydown.enter)="emitClick(s)"
212
+ (keydown.space)="emitClick(s); $event.preventDefault()"
213
+ (pointerenter)="setActive($event, s)"
214
+ (pointermove)="setActive($event, s)"
215
+ (pointerleave)="clearActive()"
216
+ (focus)="setActive($event, s)"
217
+ (blur)="clearActive()" />
218
+ }
219
+ @if (showLabels()) {
220
+ @for (s of layout().slices; track s.seriesKey) {
221
+ <svg:text
222
+ class="chart-slice-label fill-foreground text-2xs"
223
+ text-anchor="middle"
224
+ dominant-baseline="middle"
225
+ [attr.x]="s.centroid[0] + s.translateX"
226
+ [attr.y]="s.centroid[1] + s.translateY">
227
+ {{ s.value }}
228
+ </svg:text>
229
+ }
230
+ }
231
+ </svg:g>
232
+ </svg:g>
233
+ </svg:svg>
234
+ <div class="pointer-events-none absolute inset-0 flex items-center justify-center">
235
+ <ng-content select="ChartPieCenter" />
236
+ </div>
237
+ <ng-content select="ChartTooltip" />
238
+ <ng-content select="ChartLegend" />
239
+ `,
240
+ }]
241
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: true }] }], nameKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nameKey", required: true }] }], seriesKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "seriesKeys", required: false }] }], styles: [{ type: i0.Input, args: [{ isSignal: true, alias: "styles", required: false }] }], margin: [{ type: i0.Input, args: [{ isSignal: true, alias: "margin", required: false }] }], innerRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "innerRadius", required: false }] }], padAngle: [{ type: i0.Input, args: [{ isSignal: true, alias: "padAngle", required: false }] }], cornerRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "cornerRadius", required: false }] }], startAngle: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAngle", required: false }] }], endAngle: [{ type: i0.Input, args: [{ isSignal: true, alias: "endAngle", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], activeOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeOffset", required: false }] }], sliceClick: [{ type: i0.Output, args: ["sliceClick"] }] } });
242
+
243
+ /**
244
+ * Generated bundle index. Do not edit.
245
+ */
246
+
247
+ export { PieChart, computePieLayout };
248
+ //# sourceMappingURL=ojiepermana-angular-chart-pie.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ojiepermana-angular-chart-pie.mjs","sources":["../../../library/chart/pie/pie-layout.ts","../../../library/chart/pie/pie-chart.ts","../../../library/chart/pie/ojiepermana-angular-chart-pie.ts"],"sourcesContent":["import { arc as d3arc, pie as d3pie, type PieArcDatum } from 'd3-shape';\nimport type { ChartDatum } from '@ojiepermana/angular-chart/core';\nimport { seriesColorVar } from '@ojiepermana/angular-chart/core';\n\nexport interface PieLayoutInput {\n readonly data: readonly ChartDatum[];\n /** Field on each datum whose value is the slice's numeric magnitude. */\n readonly valueKey: string;\n /** Field on each datum whose value is the slice's categorical label. */\n readonly nameKey: string;\n /**\n * Ordered series keys used to resolve color (`var(--color-<key>)`).\n * Must have the same length as `data`. If omitted, falls back to\n * `nameKey` values.\n */\n readonly seriesKeys?: readonly string[];\n readonly innerWidth: number;\n readonly innerHeight: number;\n /** Inner radius for donut-style charts (0 = full pie). */\n readonly innerRadius: number;\n /** Gap between slices, in radians. */\n readonly padAngle: number;\n /** Corner radius for slices (px). */\n readonly cornerRadius: number;\n /** Starting angle in radians (default −π/2 = 12 o'clock). */\n readonly startAngle: number;\n /** Ending angle in radians (default 3π/2). */\n readonly endAngle: number;\n readonly activeIndex?: number;\n readonly activeOffset?: number;\n}\n\nexport interface PieSliceRect {\n readonly seriesKey: string;\n readonly name: string;\n readonly value: number;\n readonly datumIndex: number;\n readonly color: string;\n readonly arcPath: string;\n readonly centroid: readonly [number, number];\n readonly startAngle: number;\n readonly endAngle: number;\n readonly translateX: number;\n readonly translateY: number;\n}\n\nexport interface PieLayout {\n readonly slices: readonly PieSliceRect[];\n readonly centerX: number;\n readonly centerY: number;\n readonly outerRadius: number;\n}\n\nexport function computePieLayout(input: PieLayoutInput): PieLayout {\n const {\n data,\n valueKey,\n nameKey,\n seriesKeys,\n innerWidth,\n innerHeight,\n innerRadius,\n padAngle,\n cornerRadius,\n startAngle,\n endAngle,\n activeIndex,\n activeOffset = 12,\n } = input;\n\n const outerRadius = Math.max(0, Math.min(innerWidth, innerHeight) / 2);\n const centerX = innerWidth / 2;\n const centerY = innerHeight / 2;\n\n if (data.length === 0 || outerRadius === 0) {\n return { slices: [], centerX, centerY, outerRadius };\n }\n\n const pieGen = d3pie<ChartDatum>()\n .value((d) => Number(d[valueKey] ?? 0))\n .sort(null)\n .padAngle(padAngle)\n .startAngle(startAngle)\n .endAngle(endAngle);\n\n const arcGen = d3arc<PieArcDatum<ChartDatum>>()\n .innerRadius(innerRadius)\n .outerRadius(outerRadius)\n .cornerRadius(cornerRadius);\n\n const arcs = pieGen(data as ChartDatum[]);\n const slices: PieSliceRect[] = arcs.map((a, i) => {\n const d = a.data;\n const key = seriesKeys?.[i] ?? String(d[nameKey] ?? i);\n const centroid = arcGen.centroid(a) as [number, number];\n const magnitude = Math.hypot(centroid[0], centroid[1]) || 1;\n const isActive = i === activeIndex;\n return {\n seriesKey: key,\n name: String(d[nameKey] ?? key),\n value: Number(d[valueKey] ?? 0),\n datumIndex: i,\n color: seriesColorVar(key),\n arcPath: arcGen(a) ?? '',\n centroid,\n startAngle: a.startAngle,\n endAngle: a.endAngle,\n translateX: isActive ? (centroid[0] / magnitude) * activeOffset : 0,\n translateY: isActive ? (centroid[1] / magnitude) * activeOffset : 0,\n };\n });\n\n return { slices, centerX, centerY, outerRadius };\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\nimport { ChartContext } from '@ojiepermana/angular-chart/core';\nimport type { ChartDatum, ChartMargin, ChartStyleVariant } from '@ojiepermana/angular-chart/core';\nimport { computePieLayout, type PieSliceRect } from './pie-layout';\n\nconst DEFAULT_MARGIN: ChartMargin = { top: 8, right: 8, bottom: 8, left: 8 };\n\nexport interface PieSliceClickEvent {\n readonly seriesKey: string;\n readonly name: string;\n readonly value: number;\n readonly datumIndex: number;\n readonly datum: ChartDatum;\n}\n\n@Component({\n selector: 'ChartPie',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },\n template: `\n <svg:svg\n class=\"block h-full w-full overflow-visible\"\n [attr.viewBox]=\"viewBox()\"\n preserveAspectRatio=\"xMidYMid meet\"\n role=\"img\"\n [attr.aria-label]=\"ariaSummary()\">\n <svg:g [attr.transform]=\"innerTransform()\">\n <svg:g [attr.transform]=\"'translate(' + layout().centerX + ',' + layout().centerY + ')'\">\n @for (s of layout().slices; track s.seriesKey) {\n <svg:path\n class=\"chart-slice cursor-pointer transition-opacity hover:opacity-80\"\n [attr.d]=\"s.arcPath\"\n [attr.fill]=\"s.color\"\n [attr.transform]=\"sliceTransform(s)\"\n [attr.aria-label]=\"sliceAriaLabel(s)\"\n tabindex=\"0\"\n (click)=\"emitClick(s)\"\n (keydown.enter)=\"emitClick(s)\"\n (keydown.space)=\"emitClick(s); $event.preventDefault()\"\n (pointerenter)=\"setActive($event, s)\"\n (pointermove)=\"setActive($event, s)\"\n (pointerleave)=\"clearActive()\"\n (focus)=\"setActive($event, s)\"\n (blur)=\"clearActive()\" />\n }\n @if (showLabels()) {\n @for (s of layout().slices; track s.seriesKey) {\n <svg:text\n class=\"chart-slice-label fill-foreground text-2xs\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n [attr.x]=\"s.centroid[0] + s.translateX\"\n [attr.y]=\"s.centroid[1] + s.translateY\">\n {{ s.value }}\n </svg:text>\n }\n }\n </svg:g>\n </svg:g>\n </svg:svg>\n <div class=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <ng-content select=\"ChartPieCenter\" />\n </div>\n <ng-content select=\"ChartTooltip\" />\n <ng-content select=\"ChartLegend\" />\n `,\n})\nexport class PieChart {\n private readonly root = inject(ChartContext);\n\n readonly data = input.required<readonly ChartDatum[]>();\n readonly valueKey = input.required<string>();\n readonly nameKey = input.required<string>();\n readonly seriesKeys = input<readonly string[] | undefined>(undefined);\n readonly styles = input<ChartStyleVariant>('base');\n readonly margin = input<ChartMargin>(DEFAULT_MARGIN);\n readonly innerRadius = input<number>(0);\n readonly padAngle = input<number>(0.01);\n readonly cornerRadius = input<number>(0);\n readonly startAngle = input<number>(-Math.PI / 2);\n readonly endAngle = input<number>((3 * Math.PI) / 2);\n readonly showLabels = input<boolean>(false);\n readonly activeIndex = input<number | undefined>(undefined);\n readonly activeOffset = input<number>(12);\n\n readonly sliceClick = output<PieSliceClickEvent>();\n\n protected readonly innerWidth = computed(() =>\n Math.max(0, this.root.dimensions().width - this.margin().left - this.margin().right),\n );\n protected readonly innerHeight = computed(() =>\n Math.max(0, this.root.dimensions().height - this.margin().top - this.margin().bottom),\n );\n\n protected readonly layout = computed(() =>\n computePieLayout({\n data: this.data(),\n valueKey: this.valueKey(),\n nameKey: this.nameKey(),\n seriesKeys: this.seriesKeys(),\n innerWidth: this.innerWidth(),\n innerHeight: this.innerHeight(),\n innerRadius: this.innerRadius(),\n padAngle: this.padAngle(),\n cornerRadius: this.cornerRadius(),\n startAngle: this.startAngle(),\n endAngle: this.endAngle(),\n activeIndex: this.activeIndex(),\n activeOffset: this.activeOffset(),\n }),\n );\n\n protected readonly viewBox = computed(() => {\n const { width, height } = this.root.dimensions();\n return `0 0 ${Math.max(0, width)} ${Math.max(0, height)}`;\n });\n\n protected readonly innerTransform = computed(() => `translate(${this.margin().left},${this.margin().top})`);\n protected readonly ariaSummary = computed(() => `Pie chart, ${this.data().length} slices.`);\n\n protected sliceAriaLabel(s: PieSliceRect): string {\n return `${s.name}: ${s.value}`;\n }\n\n protected sliceTransform(s: PieSliceRect): string | null {\n return s.translateX || s.translateY ? `translate(${s.translateX}, ${s.translateY})` : null;\n }\n\n protected emitClick(s: PieSliceRect): void {\n this.sliceClick.emit({\n seriesKey: s.seriesKey,\n name: s.name,\n value: s.value,\n datumIndex: s.datumIndex,\n datum: this.data()[s.datumIndex],\n });\n }\n\n protected setActive(event: PointerEvent | FocusEvent, s: PieSliceRect): void {\n const clientX =\n event instanceof PointerEvent ? event.clientX : (event.target as Element).getBoundingClientRect().left;\n const clientY =\n event instanceof PointerEvent ? event.clientY : (event.target as Element).getBoundingClientRect().top;\n this.root.activePoint.set({\n index: s.datumIndex,\n datumIndex: s.datumIndex,\n seriesKey: s.seriesKey,\n clientX,\n clientY,\n });\n }\n\n protected clearActive(): void {\n this.root.activePoint.set(null);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["d3pie","d3arc"],"mappings":"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"}