@ojiepermana/angular-chart 22.0.44 → 22.0.45
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.
- package/fesm2022/ojiepermana-angular-chart-area.mjs +18 -11
- package/fesm2022/ojiepermana-angular-chart-bar.mjs +23 -14
- package/fesm2022/ojiepermana-angular-chart-core.mjs +3 -5
- package/fesm2022/ojiepermana-angular-chart-line.mjs +18 -11
- package/fesm2022/ojiepermana-angular-chart-pie.mjs +20 -11
- package/fesm2022/ojiepermana-angular-chart-primitives.mjs +111 -58
- package/fesm2022/ojiepermana-angular-chart-radar.mjs +54 -21
- package/fesm2022/ojiepermana-angular-chart-radial.mjs +20 -11
- package/fesm2022/ojiepermana-angular-chart-scatter.mjs +10 -7
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, output, computed, effect,
|
|
2
|
+
import { inject, input, output, computed, effect, Component } from '@angular/core';
|
|
3
3
|
import { ChartContext, CartesianContext, CategoricalViewportContext, sliceByIndexRange, computeAreaLayout, provideCartesianFromLineLayout, elementClientCenter } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import { ChartPointerTracker } from '@ojiepermana/angular-chart/primitives';
|
|
5
5
|
|
|
@@ -125,7 +125,8 @@ class AreaChart {
|
|
|
125
125
|
[attr.viewBox]="viewBox()"
|
|
126
126
|
preserveAspectRatio="none"
|
|
127
127
|
role="img"
|
|
128
|
-
[attr.aria-label]="ariaSummary()"
|
|
128
|
+
[attr.aria-label]="ariaSummary()"
|
|
129
|
+
>
|
|
129
130
|
@if (gradient()) {
|
|
130
131
|
<svg:defs>
|
|
131
132
|
@for (s of series(); track s.seriesKey) {
|
|
@@ -144,7 +145,8 @@ class AreaChart {
|
|
|
144
145
|
class="chart-area"
|
|
145
146
|
[attr.d]="s.areaPath"
|
|
146
147
|
[attr.fill]="areaFill(s.seriesKey, s.color)"
|
|
147
|
-
stroke="none"
|
|
148
|
+
stroke="none"
|
|
149
|
+
/>
|
|
148
150
|
<svg:path
|
|
149
151
|
class="chart-area-stroke"
|
|
150
152
|
[attr.d]="s.linePath"
|
|
@@ -152,7 +154,8 @@ class AreaChart {
|
|
|
152
154
|
[attr.stroke-width]="strokeWidth()"
|
|
153
155
|
fill="none"
|
|
154
156
|
stroke-linecap="round"
|
|
155
|
-
stroke-linejoin="round"
|
|
157
|
+
stroke-linejoin="round"
|
|
158
|
+
/>
|
|
156
159
|
@if (showDots()) {
|
|
157
160
|
@for (p of s.points; track p.datumIndex) {
|
|
158
161
|
<svg:circle
|
|
@@ -167,7 +170,8 @@ class AreaChart {
|
|
|
167
170
|
(blur)="clearActivePoint()"
|
|
168
171
|
(click)="emitClick(p)"
|
|
169
172
|
(keydown.enter)="emitClick(p)"
|
|
170
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
173
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
174
|
+
/>
|
|
171
175
|
}
|
|
172
176
|
}
|
|
173
177
|
}
|
|
@@ -181,13 +185,12 @@ class AreaChart {
|
|
|
181
185
|
<ng-content select="ChartTooltip" />
|
|
182
186
|
<ng-content select="ChartLegend" />
|
|
183
187
|
<ng-content select="ChartZoomControls" />
|
|
184
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }]
|
|
188
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }] });
|
|
185
189
|
}
|
|
186
190
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: AreaChart, decorators: [{
|
|
187
191
|
type: Component,
|
|
188
192
|
args: [{
|
|
189
193
|
selector: 'ChartArea',
|
|
190
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
191
194
|
providers: [CartesianContext, CategoricalViewportContext],
|
|
192
195
|
imports: [ChartPointerTracker],
|
|
193
196
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
@@ -198,7 +201,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
198
201
|
[attr.viewBox]="viewBox()"
|
|
199
202
|
preserveAspectRatio="none"
|
|
200
203
|
role="img"
|
|
201
|
-
[attr.aria-label]="ariaSummary()"
|
|
204
|
+
[attr.aria-label]="ariaSummary()"
|
|
205
|
+
>
|
|
202
206
|
@if (gradient()) {
|
|
203
207
|
<svg:defs>
|
|
204
208
|
@for (s of series(); track s.seriesKey) {
|
|
@@ -217,7 +221,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
217
221
|
class="chart-area"
|
|
218
222
|
[attr.d]="s.areaPath"
|
|
219
223
|
[attr.fill]="areaFill(s.seriesKey, s.color)"
|
|
220
|
-
stroke="none"
|
|
224
|
+
stroke="none"
|
|
225
|
+
/>
|
|
221
226
|
<svg:path
|
|
222
227
|
class="chart-area-stroke"
|
|
223
228
|
[attr.d]="s.linePath"
|
|
@@ -225,7 +230,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
225
230
|
[attr.stroke-width]="strokeWidth()"
|
|
226
231
|
fill="none"
|
|
227
232
|
stroke-linecap="round"
|
|
228
|
-
stroke-linejoin="round"
|
|
233
|
+
stroke-linejoin="round"
|
|
234
|
+
/>
|
|
229
235
|
@if (showDots()) {
|
|
230
236
|
@for (p of s.points; track p.datumIndex) {
|
|
231
237
|
<svg:circle
|
|
@@ -240,7 +246,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
240
246
|
(blur)="clearActivePoint()"
|
|
241
247
|
(click)="emitClick(p)"
|
|
242
248
|
(keydown.enter)="emitClick(p)"
|
|
243
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
249
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
250
|
+
/>
|
|
244
251
|
}
|
|
245
252
|
}
|
|
246
253
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, output, computed, effect,
|
|
2
|
+
import { inject, input, output, computed, effect, Component } from '@angular/core';
|
|
3
3
|
import { seriesColorVar, ChartContext, CartesianContext, ChartThemeRadius, elementClientCenter } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import { scaleBand, scaleLinear } from 'd3-scale';
|
|
5
5
|
import { min, max } from 'd3-array';
|
|
@@ -414,7 +414,7 @@ class BarChart {
|
|
|
414
414
|
});
|
|
415
415
|
}, /* @ts-ignore */
|
|
416
416
|
...(ngDevMode ? [{ debugName: "dotLayout" }] : /* istanbul ignore next */ []));
|
|
417
|
-
dotTrackCells = computed(() =>
|
|
417
|
+
dotTrackCells = computed(() => this.showDotTrack() ? (this.dotLayout()?.track ?? []) : [], /* @ts-ignore */
|
|
418
418
|
...(ngDevMode ? [{ debugName: "dotTrackCells" }] : /* istanbul ignore next */ []));
|
|
419
419
|
dotValueCells = computed(() => this.dotLayout()?.values ?? [], /* @ts-ignore */
|
|
420
420
|
...(ngDevMode ? [{ debugName: "dotValueCells" }] : /* istanbul ignore next */ []));
|
|
@@ -534,7 +534,8 @@ class BarChart {
|
|
|
534
534
|
[attr.viewBox]="viewBox()"
|
|
535
535
|
preserveAspectRatio="none"
|
|
536
536
|
role="img"
|
|
537
|
-
[attr.aria-label]="ariaSummary()"
|
|
537
|
+
[attr.aria-label]="ariaSummary()"
|
|
538
|
+
>
|
|
538
539
|
<svg:g [attr.transform]="innerTransform()">
|
|
539
540
|
<ng-content select="svg\\:g[ChartGrid]" />
|
|
540
541
|
<svg:g class="chart-bars">
|
|
@@ -549,7 +550,8 @@ class BarChart {
|
|
|
549
550
|
[attr.height]="cell.height"
|
|
550
551
|
[attr.rx]="resolvedDotCornerRadius()"
|
|
551
552
|
[attr.ry]="resolvedDotCornerRadius()"
|
|
552
|
-
fill="hsl(var(--muted))"
|
|
553
|
+
fill="hsl(var(--muted))"
|
|
554
|
+
/>
|
|
553
555
|
}
|
|
554
556
|
@for (cell of dotValueCells(); track cell.key) {
|
|
555
557
|
<svg:rect
|
|
@@ -561,7 +563,8 @@ class BarChart {
|
|
|
561
563
|
[attr.rx]="resolvedDotCornerRadius()"
|
|
562
564
|
[attr.ry]="resolvedDotCornerRadius()"
|
|
563
565
|
[attr.fill]="cell.color"
|
|
564
|
-
[attr.opacity]="dotCellOpacity(cell)"
|
|
566
|
+
[attr.opacity]="dotCellOpacity(cell)"
|
|
567
|
+
/>
|
|
565
568
|
}
|
|
566
569
|
</svg:g>
|
|
567
570
|
}
|
|
@@ -585,14 +588,16 @@ class BarChart {
|
|
|
585
588
|
(click)="emitClick(bar)"
|
|
586
589
|
(keydown.enter)="emitClick(bar)"
|
|
587
590
|
(keydown.space)="emitClick(bar); $event.preventDefault()"
|
|
588
|
-
(keydown)="onKeydown($event, idx)"
|
|
591
|
+
(keydown)="onKeydown($event, idx)"
|
|
592
|
+
/>
|
|
589
593
|
@if (showValueLabels() && bar.height > 0 && bar.width > 0) {
|
|
590
594
|
<svg:text
|
|
591
595
|
class="chart-bar-value pointer-events-none fill-muted-foreground text-2xs"
|
|
592
596
|
[attr.x]="barLabelX(bar)"
|
|
593
597
|
[attr.y]="barLabelY(bar)"
|
|
594
598
|
[attr.text-anchor]="barLabelAnchor(bar)"
|
|
595
|
-
dominant-baseline="middle"
|
|
599
|
+
dominant-baseline="middle"
|
|
600
|
+
>
|
|
596
601
|
{{ formatValueLabel(bar) }}
|
|
597
602
|
</svg:text>
|
|
598
603
|
}
|
|
@@ -627,13 +632,12 @@ class BarChart {
|
|
|
627
632
|
}
|
|
628
633
|
</tbody>
|
|
629
634
|
</table>
|
|
630
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }]
|
|
635
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }] });
|
|
631
636
|
}
|
|
632
637
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: BarChart, decorators: [{
|
|
633
638
|
type: Component,
|
|
634
639
|
args: [{
|
|
635
640
|
selector: 'ChartBar',
|
|
636
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
637
641
|
providers: [CartesianContext],
|
|
638
642
|
imports: [ChartPointerTracker],
|
|
639
643
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
@@ -644,7 +648,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
644
648
|
[attr.viewBox]="viewBox()"
|
|
645
649
|
preserveAspectRatio="none"
|
|
646
650
|
role="img"
|
|
647
|
-
[attr.aria-label]="ariaSummary()"
|
|
651
|
+
[attr.aria-label]="ariaSummary()"
|
|
652
|
+
>
|
|
648
653
|
<svg:g [attr.transform]="innerTransform()">
|
|
649
654
|
<ng-content select="svg\\:g[ChartGrid]" />
|
|
650
655
|
<svg:g class="chart-bars">
|
|
@@ -659,7 +664,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
659
664
|
[attr.height]="cell.height"
|
|
660
665
|
[attr.rx]="resolvedDotCornerRadius()"
|
|
661
666
|
[attr.ry]="resolvedDotCornerRadius()"
|
|
662
|
-
fill="hsl(var(--muted))"
|
|
667
|
+
fill="hsl(var(--muted))"
|
|
668
|
+
/>
|
|
663
669
|
}
|
|
664
670
|
@for (cell of dotValueCells(); track cell.key) {
|
|
665
671
|
<svg:rect
|
|
@@ -671,7 +677,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
671
677
|
[attr.rx]="resolvedDotCornerRadius()"
|
|
672
678
|
[attr.ry]="resolvedDotCornerRadius()"
|
|
673
679
|
[attr.fill]="cell.color"
|
|
674
|
-
[attr.opacity]="dotCellOpacity(cell)"
|
|
680
|
+
[attr.opacity]="dotCellOpacity(cell)"
|
|
681
|
+
/>
|
|
675
682
|
}
|
|
676
683
|
</svg:g>
|
|
677
684
|
}
|
|
@@ -695,14 +702,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
695
702
|
(click)="emitClick(bar)"
|
|
696
703
|
(keydown.enter)="emitClick(bar)"
|
|
697
704
|
(keydown.space)="emitClick(bar); $event.preventDefault()"
|
|
698
|
-
(keydown)="onKeydown($event, idx)"
|
|
705
|
+
(keydown)="onKeydown($event, idx)"
|
|
706
|
+
/>
|
|
699
707
|
@if (showValueLabels() && bar.height > 0 && bar.width > 0) {
|
|
700
708
|
<svg:text
|
|
701
709
|
class="chart-bar-value pointer-events-none fill-muted-foreground text-2xs"
|
|
702
710
|
[attr.x]="barLabelX(bar)"
|
|
703
711
|
[attr.y]="barLabelY(bar)"
|
|
704
712
|
[attr.text-anchor]="barLabelAnchor(bar)"
|
|
705
|
-
dominant-baseline="middle"
|
|
713
|
+
dominant-baseline="middle"
|
|
714
|
+
>
|
|
706
715
|
{{ formatValueLabel(bar) }}
|
|
707
716
|
</svg:text>
|
|
708
717
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, Injectable, inject, ElementRef, Renderer2, effect,
|
|
2
|
+
import { signal, computed, Injectable, inject, ElementRef, Renderer2, effect, Component, NgZone, PLATFORM_ID, DestroyRef, viewChild, input, afterNextRender, Service } from '@angular/core';
|
|
3
3
|
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
4
4
|
import { scalePoint, scaleLinear, scaleBand } from 'd3-scale';
|
|
5
5
|
import { max } from 'd3-array';
|
|
@@ -140,13 +140,12 @@ class ChartStyle {
|
|
|
140
140
|
});
|
|
141
141
|
}
|
|
142
142
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartStyle, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
143
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: ChartStyle, isStandalone: true, selector: "ChartStyle", ngImport: i0, template: '', isInline: true
|
|
143
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: ChartStyle, isStandalone: true, selector: "ChartStyle", ngImport: i0, template: '', isInline: true });
|
|
144
144
|
}
|
|
145
145
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartStyle, decorators: [{
|
|
146
146
|
type: Component,
|
|
147
147
|
args: [{
|
|
148
148
|
selector: 'ChartStyle',
|
|
149
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
150
149
|
template: '',
|
|
151
150
|
}]
|
|
152
151
|
}], ctorParameters: () => [] });
|
|
@@ -232,13 +231,12 @@ class ChartContainer {
|
|
|
232
231
|
<ng-content />
|
|
233
232
|
</div>
|
|
234
233
|
<ng-content select="ChartLegend" />
|
|
235
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ChartStyle, selector: "ChartStyle" }]
|
|
234
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ChartStyle, selector: "ChartStyle" }] });
|
|
236
235
|
}
|
|
237
236
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartContainer, decorators: [{
|
|
238
237
|
type: Component,
|
|
239
238
|
args: [{
|
|
240
239
|
selector: 'Chart',
|
|
241
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
242
240
|
providers: [ChartContext],
|
|
243
241
|
imports: [ChartStyle],
|
|
244
242
|
host: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, output, computed, effect,
|
|
2
|
+
import { inject, input, output, computed, effect, Component } from '@angular/core';
|
|
3
3
|
import { ChartContext, CartesianContext, CategoricalViewportContext, sliceByIndexRange, computeLineLayout, provideCartesianFromLineLayout, elementClientCenter } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
export { buildCartesianScales, cloneLinear, computeAreaLayout, computeLineLayout, pointToBandAdapter, provideCartesianFromLineLayout } from '@ojiepermana/angular-chart/core';
|
|
5
5
|
import { ChartPointerTracker } from '@ojiepermana/angular-chart/primitives';
|
|
@@ -146,7 +146,8 @@ class LineChart {
|
|
|
146
146
|
[attr.viewBox]="viewBox()"
|
|
147
147
|
preserveAspectRatio="none"
|
|
148
148
|
role="img"
|
|
149
|
-
[attr.aria-label]="ariaSummary()"
|
|
149
|
+
[attr.aria-label]="ariaSummary()"
|
|
150
|
+
>
|
|
150
151
|
<svg:g [attr.transform]="innerTransform()">
|
|
151
152
|
<ng-content select="svg\\:g[ChartGrid]" />
|
|
152
153
|
<svg:g class="chart-lines">
|
|
@@ -158,7 +159,8 @@ class LineChart {
|
|
|
158
159
|
stroke-linejoin="round"
|
|
159
160
|
[attr.stroke]="s.color"
|
|
160
161
|
[attr.stroke-width]="strokeWidth()"
|
|
161
|
-
[attr.d]="s.linePath"
|
|
162
|
+
[attr.d]="s.linePath"
|
|
163
|
+
/>
|
|
162
164
|
@if (showDots()) {
|
|
163
165
|
@for (p of s.points; track p.datumIndex) {
|
|
164
166
|
<svg:circle
|
|
@@ -175,14 +177,16 @@ class LineChart {
|
|
|
175
177
|
(blur)="clearActivePoint()"
|
|
176
178
|
(click)="emitClick(p)"
|
|
177
179
|
(keydown.enter)="emitClick(p)"
|
|
178
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
180
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
181
|
+
/>
|
|
179
182
|
@if (showValueLabels()) {
|
|
180
183
|
<svg:text
|
|
181
184
|
class="chart-line-value pointer-events-none fill-muted-foreground text-2xs"
|
|
182
185
|
[attr.x]="labelX(p)"
|
|
183
186
|
[attr.y]="labelY(p)"
|
|
184
187
|
[attr.text-anchor]="labelAnchor()"
|
|
185
|
-
dominant-baseline="middle"
|
|
188
|
+
dominant-baseline="middle"
|
|
189
|
+
>
|
|
186
190
|
{{ formatValueLabel(p) }}
|
|
187
191
|
</svg:text>
|
|
188
192
|
}
|
|
@@ -199,13 +203,12 @@ class LineChart {
|
|
|
199
203
|
<ng-content select="ChartTooltip" />
|
|
200
204
|
<ng-content select="ChartLegend" />
|
|
201
205
|
<ng-content select="ChartZoomControls" />
|
|
202
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }]
|
|
206
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: ChartPointerTracker, selector: "svg:svg[ChartPointerTracker]" }] });
|
|
203
207
|
}
|
|
204
208
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: LineChart, decorators: [{
|
|
205
209
|
type: Component,
|
|
206
210
|
args: [{
|
|
207
211
|
selector: 'ChartLine',
|
|
208
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
209
212
|
providers: [CartesianContext, CategoricalViewportContext],
|
|
210
213
|
imports: [ChartPointerTracker],
|
|
211
214
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
@@ -216,7 +219,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
216
219
|
[attr.viewBox]="viewBox()"
|
|
217
220
|
preserveAspectRatio="none"
|
|
218
221
|
role="img"
|
|
219
|
-
[attr.aria-label]="ariaSummary()"
|
|
222
|
+
[attr.aria-label]="ariaSummary()"
|
|
223
|
+
>
|
|
220
224
|
<svg:g [attr.transform]="innerTransform()">
|
|
221
225
|
<ng-content select="svg\\:g[ChartGrid]" />
|
|
222
226
|
<svg:g class="chart-lines">
|
|
@@ -228,7 +232,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
228
232
|
stroke-linejoin="round"
|
|
229
233
|
[attr.stroke]="s.color"
|
|
230
234
|
[attr.stroke-width]="strokeWidth()"
|
|
231
|
-
[attr.d]="s.linePath"
|
|
235
|
+
[attr.d]="s.linePath"
|
|
236
|
+
/>
|
|
232
237
|
@if (showDots()) {
|
|
233
238
|
@for (p of s.points; track p.datumIndex) {
|
|
234
239
|
<svg:circle
|
|
@@ -245,14 +250,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
245
250
|
(blur)="clearActivePoint()"
|
|
246
251
|
(click)="emitClick(p)"
|
|
247
252
|
(keydown.enter)="emitClick(p)"
|
|
248
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
253
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
254
|
+
/>
|
|
249
255
|
@if (showValueLabels()) {
|
|
250
256
|
<svg:text
|
|
251
257
|
class="chart-line-value pointer-events-none fill-muted-foreground text-2xs"
|
|
252
258
|
[attr.x]="labelX(p)"
|
|
253
259
|
[attr.y]="labelY(p)"
|
|
254
260
|
[attr.text-anchor]="labelAnchor()"
|
|
255
|
-
dominant-baseline="middle"
|
|
261
|
+
dominant-baseline="middle"
|
|
262
|
+
>
|
|
256
263
|
{{ formatValueLabel(p) }}
|
|
257
264
|
</svg:text>
|
|
258
265
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pie, arc } from 'd3-shape';
|
|
2
2
|
import { seriesColorVar, ChartContext, ChartThemeRadius } from '@ojiepermana/angular-chart/core';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, input, output, computed,
|
|
4
|
+
import { inject, input, output, computed, Component } from '@angular/core';
|
|
5
5
|
|
|
6
6
|
function computePieLayout(input) {
|
|
7
7
|
const { data, valueKey, nameKey, seriesKeys, innerWidth, innerHeight, innerRadius, padAngle, cornerRadius, startAngle, endAngle, activeIndex, activeOffset = 12, } = input;
|
|
@@ -125,8 +125,12 @@ class PieChart {
|
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
setActive(event, s) {
|
|
128
|
-
const clientX = event instanceof PointerEvent
|
|
129
|
-
|
|
128
|
+
const clientX = event instanceof PointerEvent
|
|
129
|
+
? event.clientX
|
|
130
|
+
: event.target.getBoundingClientRect().left;
|
|
131
|
+
const clientY = event instanceof PointerEvent
|
|
132
|
+
? event.clientY
|
|
133
|
+
: event.target.getBoundingClientRect().top;
|
|
130
134
|
this.root.activePoint.set({
|
|
131
135
|
index: s.datumIndex,
|
|
132
136
|
datumIndex: s.datumIndex,
|
|
@@ -145,7 +149,8 @@ class PieChart {
|
|
|
145
149
|
[attr.viewBox]="viewBox()"
|
|
146
150
|
preserveAspectRatio="xMidYMid meet"
|
|
147
151
|
role="img"
|
|
148
|
-
[attr.aria-label]="ariaSummary()"
|
|
152
|
+
[attr.aria-label]="ariaSummary()"
|
|
153
|
+
>
|
|
149
154
|
<svg:g [attr.transform]="innerTransform()">
|
|
150
155
|
<svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
|
|
151
156
|
@for (s of layout().slices; track s.seriesKey) {
|
|
@@ -163,7 +168,8 @@ class PieChart {
|
|
|
163
168
|
(pointermove)="setActive($event, s)"
|
|
164
169
|
(pointerleave)="clearActive()"
|
|
165
170
|
(focus)="setActive($event, s)"
|
|
166
|
-
(blur)="clearActive()"
|
|
171
|
+
(blur)="clearActive()"
|
|
172
|
+
/>
|
|
167
173
|
}
|
|
168
174
|
@if (showLabels()) {
|
|
169
175
|
@for (s of layout().slices; track s.seriesKey) {
|
|
@@ -172,7 +178,8 @@ class PieChart {
|
|
|
172
178
|
text-anchor="middle"
|
|
173
179
|
dominant-baseline="middle"
|
|
174
180
|
[attr.x]="s.centroid[0] + s.translateX"
|
|
175
|
-
[attr.y]="s.centroid[1] + s.translateY"
|
|
181
|
+
[attr.y]="s.centroid[1] + s.translateY"
|
|
182
|
+
>
|
|
176
183
|
{{ s.value }}
|
|
177
184
|
</svg:text>
|
|
178
185
|
}
|
|
@@ -185,13 +192,12 @@ class PieChart {
|
|
|
185
192
|
</div>
|
|
186
193
|
<ng-content select="ChartTooltip" />
|
|
187
194
|
<ng-content select="ChartLegend" />
|
|
188
|
-
`, isInline: true
|
|
195
|
+
`, isInline: true });
|
|
189
196
|
}
|
|
190
197
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PieChart, decorators: [{
|
|
191
198
|
type: Component,
|
|
192
199
|
args: [{
|
|
193
200
|
selector: 'ChartPie',
|
|
194
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
195
201
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
196
202
|
template: `
|
|
197
203
|
<svg:svg
|
|
@@ -199,7 +205,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
199
205
|
[attr.viewBox]="viewBox()"
|
|
200
206
|
preserveAspectRatio="xMidYMid meet"
|
|
201
207
|
role="img"
|
|
202
|
-
[attr.aria-label]="ariaSummary()"
|
|
208
|
+
[attr.aria-label]="ariaSummary()"
|
|
209
|
+
>
|
|
203
210
|
<svg:g [attr.transform]="innerTransform()">
|
|
204
211
|
<svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
|
|
205
212
|
@for (s of layout().slices; track s.seriesKey) {
|
|
@@ -217,7 +224,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
217
224
|
(pointermove)="setActive($event, s)"
|
|
218
225
|
(pointerleave)="clearActive()"
|
|
219
226
|
(focus)="setActive($event, s)"
|
|
220
|
-
(blur)="clearActive()"
|
|
227
|
+
(blur)="clearActive()"
|
|
228
|
+
/>
|
|
221
229
|
}
|
|
222
230
|
@if (showLabels()) {
|
|
223
231
|
@for (s of layout().slices; track s.seriesKey) {
|
|
@@ -226,7 +234,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
226
234
|
text-anchor="middle"
|
|
227
235
|
dominant-baseline="middle"
|
|
228
236
|
[attr.x]="s.centroid[0] + s.translateX"
|
|
229
|
-
[attr.y]="s.centroid[1] + s.translateY"
|
|
237
|
+
[attr.y]="s.centroid[1] + s.translateY"
|
|
238
|
+
>
|
|
230
239
|
{{ s.value }}
|
|
231
240
|
</svg:text>
|
|
232
241
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, input, computed,
|
|
2
|
+
import { inject, input, computed, Component, viewChild, signal, Directive, ElementRef, contentChild, TemplateRef } from '@angular/core';
|
|
3
3
|
import { CartesianContext, linearTicks, bandTicks, ChartContext, CategoricalViewportContext, ScatterViewportContext, nearestCategoryIndex, normalizeIndexRange, panIndexRange, panNumericDomain, indexRangeSize, normalizeNumericDomain, zoomNumericDomain, zoomIndexRange, seriesColorVar } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import { NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
|
|
5
5
|
|
|
@@ -44,18 +44,18 @@ class ChartAxisX {
|
|
|
44
44
|
class="fill-current"
|
|
45
45
|
y="18"
|
|
46
46
|
text-anchor="middle"
|
|
47
|
-
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
47
|
+
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
48
|
+
>
|
|
48
49
|
{{ t.label }}
|
|
49
50
|
</svg:text>
|
|
50
51
|
</svg:g>
|
|
51
52
|
}
|
|
52
|
-
`, isInline: true
|
|
53
|
+
`, isInline: true });
|
|
53
54
|
}
|
|
54
55
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartAxisX, decorators: [{
|
|
55
56
|
type: Component,
|
|
56
57
|
args: [{
|
|
57
58
|
selector: 'svg:g[ChartAxisX]',
|
|
58
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
59
59
|
host: {
|
|
60
60
|
class: 'chart-axis chart-axis-x text-muted-foreground',
|
|
61
61
|
'[attr.transform]': 'transform()',
|
|
@@ -71,7 +71,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
71
71
|
class="fill-current"
|
|
72
72
|
y="18"
|
|
73
73
|
text-anchor="middle"
|
|
74
|
-
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
74
|
+
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
75
|
+
>
|
|
75
76
|
{{ t.label }}
|
|
76
77
|
</svg:text>
|
|
77
78
|
</svg:g>
|
|
@@ -117,18 +118,18 @@ class ChartAxisY {
|
|
|
117
118
|
x="-8"
|
|
118
119
|
dy="0.32em"
|
|
119
120
|
text-anchor="end"
|
|
120
|
-
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
121
|
+
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
122
|
+
>
|
|
121
123
|
{{ t.label }}
|
|
122
124
|
</svg:text>
|
|
123
125
|
</svg:g>
|
|
124
126
|
}
|
|
125
|
-
`, isInline: true
|
|
127
|
+
`, isInline: true });
|
|
126
128
|
}
|
|
127
129
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartAxisY, decorators: [{
|
|
128
130
|
type: Component,
|
|
129
131
|
args: [{
|
|
130
132
|
selector: 'svg:g[ChartAxisY]',
|
|
131
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
132
133
|
host: {
|
|
133
134
|
class: 'chart-axis chart-axis-y text-muted-foreground',
|
|
134
135
|
},
|
|
@@ -144,7 +145,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
144
145
|
x="-8"
|
|
145
146
|
dy="0.32em"
|
|
146
147
|
text-anchor="end"
|
|
147
|
-
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
148
|
+
style="font-size: var(--text-xs); font-family: var(--font-sans)"
|
|
149
|
+
>
|
|
148
150
|
{{ t.label }}
|
|
149
151
|
</svg:text>
|
|
150
152
|
</svg:g>
|
|
@@ -185,15 +187,15 @@ class ChartGrid {
|
|
|
185
187
|
[attr.x1]="line(t.offset).x1"
|
|
186
188
|
[attr.x2]="line(t.offset).x2"
|
|
187
189
|
[attr.y1]="line(t.offset).y1"
|
|
188
|
-
[attr.y2]="line(t.offset).y2"
|
|
190
|
+
[attr.y2]="line(t.offset).y2"
|
|
191
|
+
/>
|
|
189
192
|
}
|
|
190
|
-
`, isInline: true
|
|
193
|
+
`, isInline: true });
|
|
191
194
|
}
|
|
192
195
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartGrid, decorators: [{
|
|
193
196
|
type: Component,
|
|
194
197
|
args: [{
|
|
195
198
|
selector: 'svg:g[ChartGrid]',
|
|
196
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
197
199
|
host: {
|
|
198
200
|
class: 'chart-grid text-border',
|
|
199
201
|
},
|
|
@@ -205,7 +207,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
205
207
|
[attr.x1]="line(t.offset).x1"
|
|
206
208
|
[attr.x2]="line(t.offset).x2"
|
|
207
209
|
[attr.y1]="line(t.offset).y1"
|
|
208
|
-
[attr.y2]="line(t.offset).y2"
|
|
210
|
+
[attr.y2]="line(t.offset).y2"
|
|
211
|
+
/>
|
|
209
212
|
}
|
|
210
213
|
`,
|
|
211
214
|
}]
|
|
@@ -245,15 +248,15 @@ class ChartCrosshair {
|
|
|
245
248
|
[attr.x1]="l.x1"
|
|
246
249
|
[attr.x2]="l.x2"
|
|
247
250
|
[attr.y1]="l.y1"
|
|
248
|
-
[attr.y2]="l.y2"
|
|
251
|
+
[attr.y2]="l.y2"
|
|
252
|
+
/>
|
|
249
253
|
}
|
|
250
|
-
`, isInline: true
|
|
254
|
+
`, isInline: true });
|
|
251
255
|
}
|
|
252
256
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartCrosshair, decorators: [{
|
|
253
257
|
type: Component,
|
|
254
258
|
args: [{
|
|
255
259
|
selector: 'svg:g[ChartCrosshair]',
|
|
256
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
257
260
|
host: { class: 'chart-crosshair' },
|
|
258
261
|
template: `
|
|
259
262
|
@if (line(); as l) {
|
|
@@ -263,7 +266,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
263
266
|
[attr.x1]="l.x1"
|
|
264
267
|
[attr.x2]="l.x2"
|
|
265
268
|
[attr.y1]="l.y1"
|
|
266
|
-
[attr.y2]="l.y2"
|
|
269
|
+
[attr.y2]="l.y2"
|
|
270
|
+
/>
|
|
267
271
|
}
|
|
268
272
|
`,
|
|
269
273
|
}]
|
|
@@ -314,9 +318,19 @@ class ChartBrush {
|
|
|
314
318
|
const first = scale(categories[startVisible]) ?? 0;
|
|
315
319
|
const last = (scale(categories[endVisible]) ?? 0) + scale.bandwidth();
|
|
316
320
|
if (cart.orientation() === 'vertical') {
|
|
317
|
-
return {
|
|
321
|
+
return {
|
|
322
|
+
x: Math.min(first, last),
|
|
323
|
+
y: 0,
|
|
324
|
+
width: Math.abs(last - first),
|
|
325
|
+
height: cart.innerHeight(),
|
|
326
|
+
};
|
|
318
327
|
}
|
|
319
|
-
return {
|
|
328
|
+
return {
|
|
329
|
+
x: 0,
|
|
330
|
+
y: Math.min(first, last),
|
|
331
|
+
width: cart.innerWidth(),
|
|
332
|
+
height: Math.abs(last - first),
|
|
333
|
+
};
|
|
320
334
|
}, /* @ts-ignore */
|
|
321
335
|
...(ngDevMode ? [{ debugName: "categoryPreview" }] : /* istanbul ignore next */ []));
|
|
322
336
|
scatterPreviewRect = computed(() => {
|
|
@@ -368,7 +382,10 @@ class ChartBrush {
|
|
|
368
382
|
const absoluteIndex = visibleStart + index;
|
|
369
383
|
if (event.pointerType === 'touch' && this.categorical.hasZoom()) {
|
|
370
384
|
this.mode.set('category-pan');
|
|
371
|
-
this.categoryPanStart.set({
|
|
385
|
+
this.categoryPanStart.set({
|
|
386
|
+
coord: this.pointerAxis(local),
|
|
387
|
+
range: this.categorical.zoomRange(),
|
|
388
|
+
});
|
|
372
389
|
return;
|
|
373
390
|
}
|
|
374
391
|
this.mode.set('category-brush');
|
|
@@ -585,7 +602,8 @@ class ChartBrush {
|
|
|
585
602
|
(pointerup)="onPointerUp($event)"
|
|
586
603
|
(pointercancel)="onPointerCancel($event)"
|
|
587
604
|
(wheel)="onWheel($event)"
|
|
588
|
-
(dblclick)="resetZoom()"
|
|
605
|
+
(dblclick)="resetZoom()"
|
|
606
|
+
/>
|
|
589
607
|
|
|
590
608
|
@if (categoryPreview(); as rect) {
|
|
591
609
|
<svg:rect
|
|
@@ -594,7 +612,8 @@ class ChartBrush {
|
|
|
594
612
|
[attr.y]="rect.y"
|
|
595
613
|
[attr.width]="rect.width"
|
|
596
614
|
[attr.height]="rect.height"
|
|
597
|
-
stroke-dasharray="4 3"
|
|
615
|
+
stroke-dasharray="4 3"
|
|
616
|
+
/>
|
|
598
617
|
}
|
|
599
618
|
|
|
600
619
|
@if (scatterPreviewRect(); as rect) {
|
|
@@ -604,15 +623,15 @@ class ChartBrush {
|
|
|
604
623
|
[attr.y]="rect.y"
|
|
605
624
|
[attr.width]="rect.width"
|
|
606
625
|
[attr.height]="rect.height"
|
|
607
|
-
stroke-dasharray="4 3"
|
|
626
|
+
stroke-dasharray="4 3"
|
|
627
|
+
/>
|
|
608
628
|
}
|
|
609
|
-
`, isInline: true
|
|
629
|
+
`, isInline: true });
|
|
610
630
|
}
|
|
611
631
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartBrush, decorators: [{
|
|
612
632
|
type: Component,
|
|
613
633
|
args: [{
|
|
614
634
|
selector: 'svg:g[ChartBrush]',
|
|
615
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
616
635
|
host: {
|
|
617
636
|
class: 'chart-brush',
|
|
618
637
|
'(window:pointermove)': 'onPointerMove($event)',
|
|
@@ -632,7 +651,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
632
651
|
(pointerup)="onPointerUp($event)"
|
|
633
652
|
(pointercancel)="onPointerCancel($event)"
|
|
634
653
|
(wheel)="onWheel($event)"
|
|
635
|
-
(dblclick)="resetZoom()"
|
|
654
|
+
(dblclick)="resetZoom()"
|
|
655
|
+
/>
|
|
636
656
|
|
|
637
657
|
@if (categoryPreview(); as rect) {
|
|
638
658
|
<svg:rect
|
|
@@ -641,7 +661,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
641
661
|
[attr.y]="rect.y"
|
|
642
662
|
[attr.width]="rect.width"
|
|
643
663
|
[attr.height]="rect.height"
|
|
644
|
-
stroke-dasharray="4 3"
|
|
664
|
+
stroke-dasharray="4 3"
|
|
665
|
+
/>
|
|
645
666
|
}
|
|
646
667
|
|
|
647
668
|
@if (scatterPreviewRect(); as rect) {
|
|
@@ -651,7 +672,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
651
672
|
[attr.y]="rect.y"
|
|
652
673
|
[attr.width]="rect.width"
|
|
653
674
|
[attr.height]="rect.height"
|
|
654
|
-
stroke-dasharray="4 3"
|
|
675
|
+
stroke-dasharray="4 3"
|
|
676
|
+
/>
|
|
655
677
|
}
|
|
656
678
|
`,
|
|
657
679
|
}]
|
|
@@ -790,7 +812,9 @@ class ChartTooltip {
|
|
|
790
812
|
const rows = this.data();
|
|
791
813
|
if (!active || !rows)
|
|
792
814
|
return null;
|
|
793
|
-
const dataIndex = active.datumIndex != null && active.datumIndex < rows.length
|
|
815
|
+
const dataIndex = active.datumIndex != null && active.datumIndex < rows.length
|
|
816
|
+
? active.datumIndex
|
|
817
|
+
: active.index;
|
|
794
818
|
if (dataIndex < 0 || dataIndex >= rows.length)
|
|
795
819
|
return null;
|
|
796
820
|
const cfg = this.root.config();
|
|
@@ -867,7 +891,8 @@ class ChartTooltip {
|
|
|
867
891
|
role="tooltip"
|
|
868
892
|
class="pointer-events-none absolute grid min-w-32 max-w-72 -translate-x-1/2 -translate-y-full gap-1.5 rounded-lg border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-3 py-1.5 text-xs shadow-md"
|
|
869
893
|
[style.left.px]="position().x"
|
|
870
|
-
[style.top.px]="position().y"
|
|
894
|
+
[style.top.px]="position().y"
|
|
895
|
+
>
|
|
871
896
|
@if (customTpl(); as tpl) {
|
|
872
897
|
<ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }" />
|
|
873
898
|
} @else {
|
|
@@ -883,15 +908,20 @@ class ChartTooltip {
|
|
|
883
908
|
<span
|
|
884
909
|
class="h-2.5 w-2.5 shrink-0 rounded-sm"
|
|
885
910
|
[style.background]="row.color"
|
|
886
|
-
[style.borderColor]="row.color"
|
|
911
|
+
[style.borderColor]="row.color"
|
|
912
|
+
></span>
|
|
887
913
|
}
|
|
888
914
|
@case ('line') {
|
|
889
|
-
<span
|
|
915
|
+
<span
|
|
916
|
+
class="h-full min-h-4 w-1 shrink-0 rounded-sm"
|
|
917
|
+
[style.background]="row.color"
|
|
918
|
+
></span>
|
|
890
919
|
}
|
|
891
920
|
@case ('dashed') {
|
|
892
921
|
<span
|
|
893
922
|
class="h-0 w-3 shrink-0 self-center border-t-2 border-dashed"
|
|
894
|
-
[style.borderColor]="row.color"
|
|
923
|
+
[style.borderColor]="row.color"
|
|
924
|
+
></span>
|
|
895
925
|
}
|
|
896
926
|
}
|
|
897
927
|
@if (row.icon; as icon) {
|
|
@@ -917,13 +947,12 @@ class ChartTooltip {
|
|
|
917
947
|
{{ p.category }}
|
|
918
948
|
}
|
|
919
949
|
</div>
|
|
920
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }]
|
|
950
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }] });
|
|
921
951
|
}
|
|
922
952
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartTooltip, decorators: [{
|
|
923
953
|
type: Component,
|
|
924
954
|
args: [{
|
|
925
955
|
selector: 'ChartTooltip',
|
|
926
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
927
956
|
imports: [NgTemplateOutlet, NgComponentOutlet],
|
|
928
957
|
host: {
|
|
929
958
|
class: 'pointer-events-none absolute inset-0 z-10',
|
|
@@ -935,7 +964,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
935
964
|
role="tooltip"
|
|
936
965
|
class="pointer-events-none absolute grid min-w-32 max-w-72 -translate-x-1/2 -translate-y-full gap-1.5 rounded-lg border border-[hsl(var(--border)/var(--opacity-60))] bg-background px-3 py-1.5 text-xs shadow-md"
|
|
937
966
|
[style.left.px]="position().x"
|
|
938
|
-
[style.top.px]="position().y"
|
|
967
|
+
[style.top.px]="position().y"
|
|
968
|
+
>
|
|
939
969
|
@if (customTpl(); as tpl) {
|
|
940
970
|
<ng-container *ngTemplateOutlet="tpl; context: { $implicit: p }" />
|
|
941
971
|
} @else {
|
|
@@ -951,15 +981,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
951
981
|
<span
|
|
952
982
|
class="h-2.5 w-2.5 shrink-0 rounded-sm"
|
|
953
983
|
[style.background]="row.color"
|
|
954
|
-
[style.borderColor]="row.color"
|
|
984
|
+
[style.borderColor]="row.color"
|
|
985
|
+
></span>
|
|
955
986
|
}
|
|
956
987
|
@case ('line') {
|
|
957
|
-
<span
|
|
988
|
+
<span
|
|
989
|
+
class="h-full min-h-4 w-1 shrink-0 rounded-sm"
|
|
990
|
+
[style.background]="row.color"
|
|
991
|
+
></span>
|
|
958
992
|
}
|
|
959
993
|
@case ('dashed') {
|
|
960
994
|
<span
|
|
961
995
|
class="h-0 w-3 shrink-0 self-center border-t-2 border-dashed"
|
|
962
|
-
[style.borderColor]="row.color"
|
|
996
|
+
[style.borderColor]="row.color"
|
|
997
|
+
></span>
|
|
963
998
|
}
|
|
964
999
|
}
|
|
965
1000
|
@if (row.icon; as icon) {
|
|
@@ -1019,7 +1054,10 @@ class ChartLegend {
|
|
|
1019
1054
|
}
|
|
1020
1055
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartLegend, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1021
1056
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: ChartLegend, isStandalone: true, selector: "ChartLegend", host: { classAttribute: "block pt-3" }, ngImport: i0, template: `
|
|
1022
|
-
<ul
|
|
1057
|
+
<ul
|
|
1058
|
+
class="flex flex-wrap items-center justify-center gap-3 text-xs"
|
|
1059
|
+
aria-label="Toggle chart series visibility"
|
|
1060
|
+
>
|
|
1023
1061
|
@for (item of items(); track item.seriesKey) {
|
|
1024
1062
|
<li>
|
|
1025
1063
|
<button
|
|
@@ -1028,23 +1066,29 @@ class ChartLegend {
|
|
|
1028
1066
|
[class.opacity-50]="item.hidden"
|
|
1029
1067
|
[attr.aria-pressed]="!item.hidden"
|
|
1030
1068
|
[attr.aria-label]="(item.hidden ? 'Show ' : 'Hide ') + item.label"
|
|
1031
|
-
(click)="toggle(item.seriesKey)"
|
|
1032
|
-
|
|
1069
|
+
(click)="toggle(item.seriesKey)"
|
|
1070
|
+
>
|
|
1071
|
+
<span
|
|
1072
|
+
class="inline-block h-2.5 w-2.5 rounded-sm"
|
|
1073
|
+
[style.background]="item.color"
|
|
1074
|
+
></span>
|
|
1033
1075
|
<span class="text-muted-foreground">{{ item.label }}</span>
|
|
1034
1076
|
</button>
|
|
1035
1077
|
</li>
|
|
1036
1078
|
}
|
|
1037
1079
|
</ul>
|
|
1038
|
-
`, isInline: true
|
|
1080
|
+
`, isInline: true });
|
|
1039
1081
|
}
|
|
1040
1082
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartLegend, decorators: [{
|
|
1041
1083
|
type: Component,
|
|
1042
1084
|
args: [{
|
|
1043
1085
|
selector: 'ChartLegend',
|
|
1044
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1045
1086
|
host: { class: 'block pt-3' },
|
|
1046
1087
|
template: `
|
|
1047
|
-
<ul
|
|
1088
|
+
<ul
|
|
1089
|
+
class="flex flex-wrap items-center justify-center gap-3 text-xs"
|
|
1090
|
+
aria-label="Toggle chart series visibility"
|
|
1091
|
+
>
|
|
1048
1092
|
@for (item of items(); track item.seriesKey) {
|
|
1049
1093
|
<li>
|
|
1050
1094
|
<button
|
|
@@ -1053,8 +1097,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1053
1097
|
[class.opacity-50]="item.hidden"
|
|
1054
1098
|
[attr.aria-pressed]="!item.hidden"
|
|
1055
1099
|
[attr.aria-label]="(item.hidden ? 'Show ' : 'Hide ') + item.label"
|
|
1056
|
-
(click)="toggle(item.seriesKey)"
|
|
1057
|
-
|
|
1100
|
+
(click)="toggle(item.seriesKey)"
|
|
1101
|
+
>
|
|
1102
|
+
<span
|
|
1103
|
+
class="inline-block h-2.5 w-2.5 rounded-sm"
|
|
1104
|
+
[style.background]="item.color"
|
|
1105
|
+
></span>
|
|
1058
1106
|
<span class="text-muted-foreground">{{ item.label }}</span>
|
|
1059
1107
|
</button>
|
|
1060
1108
|
</li>
|
|
@@ -1107,37 +1155,44 @@ class ChartZoomControls {
|
|
|
1107
1155
|
|
|
1108
1156
|
@if (status(); as currentStatus) {
|
|
1109
1157
|
<div class="flex flex-wrap items-center gap-2">
|
|
1110
|
-
<span
|
|
1158
|
+
<span
|
|
1159
|
+
class="rounded-full border border-border bg-background px-2.5 py-1 font-medium text-foreground"
|
|
1160
|
+
>
|
|
1111
1161
|
{{ currentStatus }}
|
|
1112
1162
|
</span>
|
|
1113
1163
|
<button
|
|
1114
1164
|
type="button"
|
|
1115
1165
|
class="inline-flex min-h-11 items-center rounded-md border border-border bg-background px-3 text-foreground transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
1116
|
-
(click)="resetZoom()"
|
|
1166
|
+
(click)="resetZoom()"
|
|
1167
|
+
>
|
|
1117
1168
|
Reset zoom
|
|
1118
1169
|
</button>
|
|
1119
1170
|
</div>
|
|
1120
1171
|
}
|
|
1121
|
-
`, isInline: true
|
|
1172
|
+
`, isInline: true });
|
|
1122
1173
|
}
|
|
1123
1174
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ChartZoomControls, decorators: [{
|
|
1124
1175
|
type: Component,
|
|
1125
1176
|
args: [{
|
|
1126
1177
|
selector: 'ChartZoomControls',
|
|
1127
|
-
|
|
1128
|
-
|
|
1178
|
+
host: {
|
|
1179
|
+
class: 'mt-3 flex flex-wrap items-center justify-between gap-3 text-xs text-muted-foreground',
|
|
1180
|
+
},
|
|
1129
1181
|
template: `
|
|
1130
1182
|
<p>{{ hint() }}</p>
|
|
1131
1183
|
|
|
1132
1184
|
@if (status(); as currentStatus) {
|
|
1133
1185
|
<div class="flex flex-wrap items-center gap-2">
|
|
1134
|
-
<span
|
|
1186
|
+
<span
|
|
1187
|
+
class="rounded-full border border-border bg-background px-2.5 py-1 font-medium text-foreground"
|
|
1188
|
+
>
|
|
1135
1189
|
{{ currentStatus }}
|
|
1136
1190
|
</span>
|
|
1137
1191
|
<button
|
|
1138
1192
|
type="button"
|
|
1139
1193
|
class="inline-flex min-h-11 items-center rounded-md border border-border bg-background px-3 text-foreground transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
|
|
1140
|
-
(click)="resetZoom()"
|
|
1194
|
+
(click)="resetZoom()"
|
|
1195
|
+
>
|
|
1141
1196
|
Reset zoom
|
|
1142
1197
|
</button>
|
|
1143
1198
|
</div>
|
|
@@ -1148,13 +1203,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1148
1203
|
|
|
1149
1204
|
class PieCenter {
|
|
1150
1205
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PieCenter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1151
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: PieCenter, isStandalone: true, selector: "ChartPieCenter", host: { classAttribute: "flex max-w-[10rem] flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true
|
|
1206
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: PieCenter, isStandalone: true, selector: "ChartPieCenter", host: { classAttribute: "flex max-w-[10rem] flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
1152
1207
|
}
|
|
1153
1208
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PieCenter, decorators: [{
|
|
1154
1209
|
type: Component,
|
|
1155
1210
|
args: [{
|
|
1156
1211
|
selector: 'ChartPieCenter',
|
|
1157
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1158
1212
|
host: {
|
|
1159
1213
|
class: 'flex max-w-[10rem] flex-col items-center justify-center text-center',
|
|
1160
1214
|
},
|
|
@@ -1164,13 +1218,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1164
1218
|
|
|
1165
1219
|
class RadialCenter {
|
|
1166
1220
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RadialCenter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1167
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: RadialCenter, isStandalone: true, selector: "ChartRadialCenter", host: { classAttribute: "flex max-w-[10rem] flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true
|
|
1221
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.4", type: RadialCenter, isStandalone: true, selector: "ChartRadialCenter", host: { classAttribute: "flex max-w-[10rem] flex-col items-center justify-center text-center" }, ngImport: i0, template: `<ng-content />`, isInline: true });
|
|
1168
1222
|
}
|
|
1169
1223
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RadialCenter, decorators: [{
|
|
1170
1224
|
type: Component,
|
|
1171
1225
|
args: [{
|
|
1172
1226
|
selector: 'ChartRadialCenter',
|
|
1173
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1174
1227
|
host: {
|
|
1175
1228
|
class: 'flex max-w-[10rem] flex-col items-center justify-center text-center',
|
|
1176
1229
|
},
|
|
@@ -2,7 +2,7 @@ import { curveCardinalClosed, curveLinearClosed, lineRadial } from 'd3-shape';
|
|
|
2
2
|
import { max } from 'd3-array';
|
|
3
3
|
import { seriesColorVar, ChartContext } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { inject, input, computed,
|
|
5
|
+
import { inject, input, computed, Component } from '@angular/core';
|
|
6
6
|
|
|
7
7
|
function computeRadarLayout(input) {
|
|
8
8
|
const { data, axisKey, seriesKeys, innerWidth, innerHeight, levels, curve, grid } = input;
|
|
@@ -145,8 +145,12 @@ class RadarChart {
|
|
|
145
145
|
return `${label} at ${p.axis}: ${p.value}`;
|
|
146
146
|
}
|
|
147
147
|
setActive(event, seriesKey, index) {
|
|
148
|
-
const clientX = event instanceof PointerEvent
|
|
149
|
-
|
|
148
|
+
const clientX = event instanceof PointerEvent
|
|
149
|
+
? event.clientX
|
|
150
|
+
: event.target.getBoundingClientRect().left;
|
|
151
|
+
const clientY = event instanceof PointerEvent
|
|
152
|
+
? event.clientY
|
|
153
|
+
: event.target.getBoundingClientRect().top;
|
|
150
154
|
this.root.activePoint.set({ index, datumIndex: index, seriesKey, clientX, clientY });
|
|
151
155
|
}
|
|
152
156
|
clearActive() {
|
|
@@ -159,9 +163,13 @@ class RadarChart {
|
|
|
159
163
|
[attr.viewBox]="viewBox()"
|
|
160
164
|
preserveAspectRatio="xMidYMid meet"
|
|
161
165
|
role="img"
|
|
162
|
-
[attr.aria-label]="ariaSummary()"
|
|
166
|
+
[attr.aria-label]="ariaSummary()"
|
|
167
|
+
>
|
|
163
168
|
<svg:g [attr.transform]="innerTransform()">
|
|
164
|
-
<svg:g
|
|
169
|
+
<svg:g
|
|
170
|
+
class="chart-radar"
|
|
171
|
+
[attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'"
|
|
172
|
+
>
|
|
165
173
|
@if (layout().grid !== 'none') {
|
|
166
174
|
@for (level of layout().levels; track level.value; let levelIndex = $index) {
|
|
167
175
|
@if (layout().grid === 'circle') {
|
|
@@ -172,27 +180,36 @@ class RadarChart {
|
|
|
172
180
|
stroke-dasharray="2 2"
|
|
173
181
|
cx="0"
|
|
174
182
|
cy="0"
|
|
175
|
-
[attr.r]="level.radius"
|
|
183
|
+
[attr.r]="level.radius"
|
|
184
|
+
/>
|
|
176
185
|
} @else {
|
|
177
186
|
<svg:path
|
|
178
187
|
class="chart-radar-level stroke-border"
|
|
179
188
|
[attr.d]="level.path"
|
|
180
189
|
[attr.fill]="gridFill()"
|
|
181
190
|
[attr.fill-opacity]="gridFillOpacity(levelIndex)"
|
|
182
|
-
stroke-dasharray="2 2"
|
|
191
|
+
stroke-dasharray="2 2"
|
|
192
|
+
/>
|
|
183
193
|
}
|
|
184
194
|
}
|
|
185
195
|
}
|
|
186
196
|
@if (showAxes()) {
|
|
187
197
|
@for (axis of layout().axes; track axis.name) {
|
|
188
|
-
<svg:line
|
|
198
|
+
<svg:line
|
|
199
|
+
class="chart-radar-axis stroke-border"
|
|
200
|
+
x1="0"
|
|
201
|
+
y1="0"
|
|
202
|
+
[attr.x2]="axis.x"
|
|
203
|
+
[attr.y2]="axis.y"
|
|
204
|
+
/>
|
|
189
205
|
@if (showLabels()) {
|
|
190
206
|
<svg:text
|
|
191
207
|
class="chart-radar-axis-label fill-muted-foreground text-2xs"
|
|
192
208
|
text-anchor="middle"
|
|
193
209
|
dominant-baseline="middle"
|
|
194
210
|
[attr.x]="axis.x * 1.12"
|
|
195
|
-
[attr.y]="axis.y * 1.12"
|
|
211
|
+
[attr.y]="axis.y * 1.12"
|
|
212
|
+
>
|
|
196
213
|
{{ axis.name }}
|
|
197
214
|
</svg:text>
|
|
198
215
|
}
|
|
@@ -206,7 +223,8 @@ class RadarChart {
|
|
|
206
223
|
[attr.fill]="linesOnly() ? 'none' : s.color"
|
|
207
224
|
[attr.fill-opacity]="linesOnly() ? null : fillOpacity()"
|
|
208
225
|
[attr.stroke-width]="strokeWidth()"
|
|
209
|
-
stroke-linejoin="round"
|
|
226
|
+
stroke-linejoin="round"
|
|
227
|
+
/>
|
|
210
228
|
@if (showDots()) {
|
|
211
229
|
@for (p of s.points; track p.axis; let i = $index) {
|
|
212
230
|
<svg:circle
|
|
@@ -221,7 +239,8 @@ class RadarChart {
|
|
|
221
239
|
(pointermove)="setActive($event, s.seriesKey, i)"
|
|
222
240
|
(pointerleave)="clearActive()"
|
|
223
241
|
(focus)="setActive($event, s.seriesKey, i)"
|
|
224
|
-
(blur)="clearActive()"
|
|
242
|
+
(blur)="clearActive()"
|
|
243
|
+
/>
|
|
225
244
|
}
|
|
226
245
|
}
|
|
227
246
|
}
|
|
@@ -231,13 +250,12 @@ class RadarChart {
|
|
|
231
250
|
</svg:svg>
|
|
232
251
|
<ng-content select="ChartTooltip" />
|
|
233
252
|
<ng-content select="ChartLegend" />
|
|
234
|
-
`, isInline: true
|
|
253
|
+
`, isInline: true });
|
|
235
254
|
}
|
|
236
255
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RadarChart, decorators: [{
|
|
237
256
|
type: Component,
|
|
238
257
|
args: [{
|
|
239
258
|
selector: 'ChartRadar',
|
|
240
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
241
259
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
242
260
|
template: `
|
|
243
261
|
<svg:svg
|
|
@@ -245,9 +263,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
245
263
|
[attr.viewBox]="viewBox()"
|
|
246
264
|
preserveAspectRatio="xMidYMid meet"
|
|
247
265
|
role="img"
|
|
248
|
-
[attr.aria-label]="ariaSummary()"
|
|
266
|
+
[attr.aria-label]="ariaSummary()"
|
|
267
|
+
>
|
|
249
268
|
<svg:g [attr.transform]="innerTransform()">
|
|
250
|
-
<svg:g
|
|
269
|
+
<svg:g
|
|
270
|
+
class="chart-radar"
|
|
271
|
+
[attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'"
|
|
272
|
+
>
|
|
251
273
|
@if (layout().grid !== 'none') {
|
|
252
274
|
@for (level of layout().levels; track level.value; let levelIndex = $index) {
|
|
253
275
|
@if (layout().grid === 'circle') {
|
|
@@ -258,27 +280,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
258
280
|
stroke-dasharray="2 2"
|
|
259
281
|
cx="0"
|
|
260
282
|
cy="0"
|
|
261
|
-
[attr.r]="level.radius"
|
|
283
|
+
[attr.r]="level.radius"
|
|
284
|
+
/>
|
|
262
285
|
} @else {
|
|
263
286
|
<svg:path
|
|
264
287
|
class="chart-radar-level stroke-border"
|
|
265
288
|
[attr.d]="level.path"
|
|
266
289
|
[attr.fill]="gridFill()"
|
|
267
290
|
[attr.fill-opacity]="gridFillOpacity(levelIndex)"
|
|
268
|
-
stroke-dasharray="2 2"
|
|
291
|
+
stroke-dasharray="2 2"
|
|
292
|
+
/>
|
|
269
293
|
}
|
|
270
294
|
}
|
|
271
295
|
}
|
|
272
296
|
@if (showAxes()) {
|
|
273
297
|
@for (axis of layout().axes; track axis.name) {
|
|
274
|
-
<svg:line
|
|
298
|
+
<svg:line
|
|
299
|
+
class="chart-radar-axis stroke-border"
|
|
300
|
+
x1="0"
|
|
301
|
+
y1="0"
|
|
302
|
+
[attr.x2]="axis.x"
|
|
303
|
+
[attr.y2]="axis.y"
|
|
304
|
+
/>
|
|
275
305
|
@if (showLabels()) {
|
|
276
306
|
<svg:text
|
|
277
307
|
class="chart-radar-axis-label fill-muted-foreground text-2xs"
|
|
278
308
|
text-anchor="middle"
|
|
279
309
|
dominant-baseline="middle"
|
|
280
310
|
[attr.x]="axis.x * 1.12"
|
|
281
|
-
[attr.y]="axis.y * 1.12"
|
|
311
|
+
[attr.y]="axis.y * 1.12"
|
|
312
|
+
>
|
|
282
313
|
{{ axis.name }}
|
|
283
314
|
</svg:text>
|
|
284
315
|
}
|
|
@@ -292,7 +323,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
292
323
|
[attr.fill]="linesOnly() ? 'none' : s.color"
|
|
293
324
|
[attr.fill-opacity]="linesOnly() ? null : fillOpacity()"
|
|
294
325
|
[attr.stroke-width]="strokeWidth()"
|
|
295
|
-
stroke-linejoin="round"
|
|
326
|
+
stroke-linejoin="round"
|
|
327
|
+
/>
|
|
296
328
|
@if (showDots()) {
|
|
297
329
|
@for (p of s.points; track p.axis; let i = $index) {
|
|
298
330
|
<svg:circle
|
|
@@ -307,7 +339,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
307
339
|
(pointermove)="setActive($event, s.seriesKey, i)"
|
|
308
340
|
(pointerleave)="clearActive()"
|
|
309
341
|
(focus)="setActive($event, s.seriesKey, i)"
|
|
310
|
-
(blur)="clearActive()"
|
|
342
|
+
(blur)="clearActive()"
|
|
343
|
+
/>
|
|
311
344
|
}
|
|
312
345
|
}
|
|
313
346
|
}
|
|
@@ -2,7 +2,7 @@ import { arc } from 'd3-shape';
|
|
|
2
2
|
import { max } from 'd3-array';
|
|
3
3
|
import { seriesColorVar, ChartContext, ChartThemeRadius } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { inject, input, output, computed,
|
|
5
|
+
import { inject, input, output, computed, Component } from '@angular/core';
|
|
6
6
|
|
|
7
7
|
function computeRadialLayout(input) {
|
|
8
8
|
const { data, nameKey, valueKey, innerWidth, innerHeight, seriesKeys, trackPadding, startAngle, endAngle, cornerRadius, } = input;
|
|
@@ -132,8 +132,12 @@ class RadialChart {
|
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
134
|
setActive(event, b) {
|
|
135
|
-
const clientX = event instanceof PointerEvent
|
|
136
|
-
|
|
135
|
+
const clientX = event instanceof PointerEvent
|
|
136
|
+
? event.clientX
|
|
137
|
+
: event.target.getBoundingClientRect().left;
|
|
138
|
+
const clientY = event instanceof PointerEvent
|
|
139
|
+
? event.clientY
|
|
140
|
+
: event.target.getBoundingClientRect().top;
|
|
137
141
|
this.root.activePoint.set({
|
|
138
142
|
index: b.datumIndex,
|
|
139
143
|
datumIndex: b.datumIndex,
|
|
@@ -152,7 +156,8 @@ class RadialChart {
|
|
|
152
156
|
[attr.viewBox]="viewBox()"
|
|
153
157
|
preserveAspectRatio="xMidYMid meet"
|
|
154
158
|
role="img"
|
|
155
|
-
[attr.aria-label]="ariaSummary()"
|
|
159
|
+
[attr.aria-label]="ariaSummary()"
|
|
160
|
+
>
|
|
156
161
|
<svg:g [attr.transform]="innerTransform()">
|
|
157
162
|
<svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
|
|
158
163
|
@for (b of layout().bars; track b.seriesKey) {
|
|
@@ -172,14 +177,16 @@ class RadialChart {
|
|
|
172
177
|
(pointermove)="setActive($event, b)"
|
|
173
178
|
(pointerleave)="clearActive()"
|
|
174
179
|
(focus)="setActive($event, b)"
|
|
175
|
-
(blur)="clearActive()"
|
|
180
|
+
(blur)="clearActive()"
|
|
181
|
+
/>
|
|
176
182
|
@if (showValueLabels()) {
|
|
177
183
|
<svg:text
|
|
178
184
|
class="chart-radial-value pointer-events-none fill-muted-foreground text-2xs"
|
|
179
185
|
[attr.x]="barLabelX(b)"
|
|
180
186
|
[attr.y]="barLabelY(b)"
|
|
181
187
|
[attr.text-anchor]="barLabelAnchor(b)"
|
|
182
|
-
dominant-baseline="middle"
|
|
188
|
+
dominant-baseline="middle"
|
|
189
|
+
>
|
|
183
190
|
{{ formatValueLabel(b) }}
|
|
184
191
|
</svg:text>
|
|
185
192
|
}
|
|
@@ -192,13 +199,12 @@ class RadialChart {
|
|
|
192
199
|
</div>
|
|
193
200
|
<ng-content select="ChartTooltip" />
|
|
194
201
|
<ng-content select="ChartLegend" />
|
|
195
|
-
`, isInline: true
|
|
202
|
+
`, isInline: true });
|
|
196
203
|
}
|
|
197
204
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: RadialChart, decorators: [{
|
|
198
205
|
type: Component,
|
|
199
206
|
args: [{
|
|
200
207
|
selector: 'ChartRadial',
|
|
201
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
202
208
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
203
209
|
template: `
|
|
204
210
|
<svg:svg
|
|
@@ -206,7 +212,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
206
212
|
[attr.viewBox]="viewBox()"
|
|
207
213
|
preserveAspectRatio="xMidYMid meet"
|
|
208
214
|
role="img"
|
|
209
|
-
[attr.aria-label]="ariaSummary()"
|
|
215
|
+
[attr.aria-label]="ariaSummary()"
|
|
216
|
+
>
|
|
210
217
|
<svg:g [attr.transform]="innerTransform()">
|
|
211
218
|
<svg:g [attr.transform]="'translate(' + layout().centerX + ',' + layout().centerY + ')'">
|
|
212
219
|
@for (b of layout().bars; track b.seriesKey) {
|
|
@@ -226,14 +233,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
226
233
|
(pointermove)="setActive($event, b)"
|
|
227
234
|
(pointerleave)="clearActive()"
|
|
228
235
|
(focus)="setActive($event, b)"
|
|
229
|
-
(blur)="clearActive()"
|
|
236
|
+
(blur)="clearActive()"
|
|
237
|
+
/>
|
|
230
238
|
@if (showValueLabels()) {
|
|
231
239
|
<svg:text
|
|
232
240
|
class="chart-radial-value pointer-events-none fill-muted-foreground text-2xs"
|
|
233
241
|
[attr.x]="barLabelX(b)"
|
|
234
242
|
[attr.y]="barLabelY(b)"
|
|
235
243
|
[attr.text-anchor]="barLabelAnchor(b)"
|
|
236
|
-
dominant-baseline="middle"
|
|
244
|
+
dominant-baseline="middle"
|
|
245
|
+
>
|
|
237
246
|
{{ formatValueLabel(b) }}
|
|
238
247
|
</svg:text>
|
|
239
248
|
}
|
|
@@ -2,7 +2,7 @@ import { scaleLinear } from 'd3-scale';
|
|
|
2
2
|
import { extent } from 'd3-array';
|
|
3
3
|
import { seriesColorVar, ChartContext, ScatterViewportContext } from '@ojiepermana/angular-chart/core';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { inject, input, output, computed, effect,
|
|
5
|
+
import { inject, input, output, computed, effect, Component } from '@angular/core';
|
|
6
6
|
|
|
7
7
|
function nice(extent) {
|
|
8
8
|
const [lo, hi] = extent;
|
|
@@ -172,7 +172,8 @@ class ScatterChart {
|
|
|
172
172
|
[attr.viewBox]="viewBox()"
|
|
173
173
|
preserveAspectRatio="none"
|
|
174
174
|
role="img"
|
|
175
|
-
[attr.aria-label]="ariaSummary()"
|
|
175
|
+
[attr.aria-label]="ariaSummary()"
|
|
176
|
+
>
|
|
176
177
|
<svg:defs>
|
|
177
178
|
<svg:clipPath [attr.id]="clipPathId()">
|
|
178
179
|
<svg:rect x="0" y="0" [attr.width]="innerWidth()" [attr.height]="innerHeight()" />
|
|
@@ -191,7 +192,8 @@ class ScatterChart {
|
|
|
191
192
|
tabindex="0"
|
|
192
193
|
(click)="emitClick(p)"
|
|
193
194
|
(keydown.enter)="emitClick(p)"
|
|
194
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
195
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
196
|
+
/>
|
|
195
197
|
}
|
|
196
198
|
</svg:g>
|
|
197
199
|
<ng-content select="svg:g[ChartBrush]" />
|
|
@@ -199,13 +201,12 @@ class ScatterChart {
|
|
|
199
201
|
</svg:svg>
|
|
200
202
|
<ng-content select="ChartLegend" />
|
|
201
203
|
<ng-content select="ChartZoomControls" />
|
|
202
|
-
`, isInline: true
|
|
204
|
+
`, isInline: true });
|
|
203
205
|
}
|
|
204
206
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: ScatterChart, decorators: [{
|
|
205
207
|
type: Component,
|
|
206
208
|
args: [{
|
|
207
209
|
selector: 'ChartScatter',
|
|
208
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
209
210
|
providers: [ScatterViewportContext],
|
|
210
211
|
host: { class: 'relative block h-full w-full', '[attr.data-style]': 'styles()' },
|
|
211
212
|
template: `
|
|
@@ -214,7 +215,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
214
215
|
[attr.viewBox]="viewBox()"
|
|
215
216
|
preserveAspectRatio="none"
|
|
216
217
|
role="img"
|
|
217
|
-
[attr.aria-label]="ariaSummary()"
|
|
218
|
+
[attr.aria-label]="ariaSummary()"
|
|
219
|
+
>
|
|
218
220
|
<svg:defs>
|
|
219
221
|
<svg:clipPath [attr.id]="clipPathId()">
|
|
220
222
|
<svg:rect x="0" y="0" [attr.width]="innerWidth()" [attr.height]="innerHeight()" />
|
|
@@ -233,7 +235,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
233
235
|
tabindex="0"
|
|
234
236
|
(click)="emitClick(p)"
|
|
235
237
|
(keydown.enter)="emitClick(p)"
|
|
236
|
-
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
238
|
+
(keydown.space)="emitClick(p); $event.preventDefault()"
|
|
239
|
+
/>
|
|
237
240
|
}
|
|
238
241
|
</svg:g>
|
|
239
242
|
<ng-content select="svg:g[ChartBrush]" />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ojiepermana/angular-chart",
|
|
3
|
-
"version": "22.0.
|
|
3
|
+
"version": "22.0.45",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/edsis/angular.git"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@angular/common": ">=22.0.0",
|
|
14
14
|
"@angular/core": ">=22.0.0",
|
|
15
|
-
"@ojiepermana/angular-component": "^22.0.
|
|
15
|
+
"@ojiepermana/angular-component": "^22.0.45"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"d3-array": "^3.2.4",
|