@skdx/angular-charts 0.1.0 → 0.32.0
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/skdx-angular-charts-area.mjs +32 -14
- package/fesm2022/skdx-angular-charts-area.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-bar.mjs +38 -14
- package/fesm2022/skdx-angular-charts-bar.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-boxplot.mjs +10 -10
- package/fesm2022/skdx-angular-charts-boxplot.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-candlestick.mjs +10 -10
- package/fesm2022/skdx-angular-charts-candlestick.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-chord.mjs +10 -10
- package/fesm2022/skdx-angular-charts-chord.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-funnel.mjs +43 -11
- package/fesm2022/skdx-angular-charts-funnel.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-gantt.mjs +10 -10
- package/fesm2022/skdx-angular-charts-gantt.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-heatmap.mjs +69 -4
- package/fesm2022/skdx-angular-charts-heatmap.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-internal.mjs +411 -235
- package/fesm2022/skdx-angular-charts-internal.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-line.mjs +15 -13
- package/fesm2022/skdx-angular-charts-line.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-map.mjs +8 -2
- package/fesm2022/skdx-angular-charts-map.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-pie.mjs +21 -11
- package/fesm2022/skdx-angular-charts-pie.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-radar.mjs +77 -14
- package/fesm2022/skdx-angular-charts-radar.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-sankey.mjs +10 -10
- package/fesm2022/skdx-angular-charts-sankey.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-scatter.mjs +15 -13
- package/fesm2022/skdx-angular-charts-scatter.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-sparkline.mjs +55 -11
- package/fesm2022/skdx-angular-charts-sparkline.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-sunburst.mjs +10 -10
- package/fesm2022/skdx-angular-charts-sunburst.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-treemap.mjs +10 -2
- package/fesm2022/skdx-angular-charts-treemap.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-waterfall.mjs +10 -10
- package/fesm2022/skdx-angular-charts-waterfall.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts.mjs.map +1 -1
- package/package.json +11 -2
- package/types/skdx-angular-charts-area.d.ts +1 -1
- package/types/skdx-angular-charts-bar.d.ts +1 -1
- package/types/skdx-angular-charts-funnel.d.ts +1 -1
- package/types/skdx-angular-charts-heatmap.d.ts +8 -1
- package/types/skdx-angular-charts-internal.d.ts +200 -26
- package/types/skdx-angular-charts-line.d.ts +1 -1
- package/types/skdx-angular-charts-pie.d.ts +1 -1
- package/types/skdx-angular-charts-radar.d.ts +8 -1
- package/types/skdx-angular-charts-scatter.d.ts +1 -1
- package/types/skdx-angular-charts-sparkline.d.ts +1 -1
- package/types/skdx-angular-charts.d.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, ChangeDetectionStrategy, Component, signal, Directive } from '@angular/core';
|
|
2
|
+
import { input, ChangeDetectionStrategy, Component, signal, computed, Directive } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2026 SkandaDX
|
|
@@ -261,6 +261,19 @@ function buildFrame(input, yExtent) {
|
|
|
261
261
|
categories,
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
|
+
/** Attributes for the `<svg>` root every framework renders. */
|
|
265
|
+
function svgAttrs(frame, kind, label) {
|
|
266
|
+
return {
|
|
267
|
+
viewBox: `0 0 ${frame.width} ${frame.height}`,
|
|
268
|
+
width: frame.width,
|
|
269
|
+
height: frame.height,
|
|
270
|
+
role: 'img',
|
|
271
|
+
'aria-label': label,
|
|
272
|
+
'data-skdx-chart': kind,
|
|
273
|
+
'font-family': CHART_COLORS.fontFamily,
|
|
274
|
+
'font-size': CHART_COLORS.fontSize,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
264
277
|
const values = (input) => input.series.flatMap((s) => s.data);
|
|
265
278
|
/** Tooltip text for a value in a series: `Series, Category: 1,234`. */
|
|
266
279
|
const markTitle = (series, category, value) => `${series}, ${category}: ${formatValue(value)}`;
|
|
@@ -279,75 +292,6 @@ function hoverTooltip(target, svg, clientX, clientY, width, height) {
|
|
|
279
292
|
return tooltipShapes(x, y, title, width, height);
|
|
280
293
|
}
|
|
281
294
|
|
|
282
|
-
/*
|
|
283
|
-
* Copyright (c) 2026 SkandaDX
|
|
284
|
-
* This file is part of the SkandaDX organization.
|
|
285
|
-
* Licensed under the MIT License. See LICENSE in the repository root.
|
|
286
|
-
*/
|
|
287
|
-
/** Grid, axis line and tick labels of an axis frame, as shapes. */
|
|
288
|
-
function frameShapes(frame) {
|
|
289
|
-
const { plot, xTicks, yTicks, baseline } = frame;
|
|
290
|
-
const right = plot.x + plot.width;
|
|
291
|
-
return [
|
|
292
|
-
...yTicks.map((t) => ({
|
|
293
|
-
kind: 'line',
|
|
294
|
-
part: 'grid',
|
|
295
|
-
x1: plot.x,
|
|
296
|
-
x2: right,
|
|
297
|
-
y1: t.pos,
|
|
298
|
-
y2: t.pos,
|
|
299
|
-
stroke: CHART_COLORS.grid,
|
|
300
|
-
})),
|
|
301
|
-
{
|
|
302
|
-
kind: 'line',
|
|
303
|
-
part: 'axis',
|
|
304
|
-
x1: plot.x,
|
|
305
|
-
x2: right,
|
|
306
|
-
y1: baseline,
|
|
307
|
-
y2: baseline,
|
|
308
|
-
stroke: CHART_COLORS.axis,
|
|
309
|
-
},
|
|
310
|
-
...yTicks.map((t) => ({
|
|
311
|
-
kind: 'text',
|
|
312
|
-
part: 'y-label',
|
|
313
|
-
x: plot.x - 8,
|
|
314
|
-
y: t.pos,
|
|
315
|
-
text: t.label,
|
|
316
|
-
anchor: 'end',
|
|
317
|
-
baseline: 'middle',
|
|
318
|
-
fill: CHART_COLORS.label,
|
|
319
|
-
})),
|
|
320
|
-
...xTicks.map((t) => ({
|
|
321
|
-
kind: 'text',
|
|
322
|
-
part: 'x-label',
|
|
323
|
-
x: t.pos,
|
|
324
|
-
y: plot.y + plot.height + 20,
|
|
325
|
-
text: t.label,
|
|
326
|
-
anchor: 'middle',
|
|
327
|
-
fill: CHART_COLORS.label,
|
|
328
|
-
})),
|
|
329
|
-
];
|
|
330
|
-
}
|
|
331
|
-
const label = (x, y, text, extra = {}) => ({
|
|
332
|
-
kind: 'text',
|
|
333
|
-
part: 'label',
|
|
334
|
-
x,
|
|
335
|
-
y,
|
|
336
|
-
text,
|
|
337
|
-
fill: CHART_COLORS.label,
|
|
338
|
-
...extra,
|
|
339
|
-
});
|
|
340
|
-
/** A dot with its native tooltip. */
|
|
341
|
-
const point = (cx, cy, r, fill, title) => ({
|
|
342
|
-
kind: 'circle',
|
|
343
|
-
part: 'point',
|
|
344
|
-
cx,
|
|
345
|
-
cy,
|
|
346
|
-
r,
|
|
347
|
-
fill,
|
|
348
|
-
title,
|
|
349
|
-
});
|
|
350
|
-
|
|
351
295
|
/*
|
|
352
296
|
* Copyright (c) 2026 SkandaDX
|
|
353
297
|
* This file is part of the SkandaDX organization.
|
|
@@ -378,18 +322,19 @@ function layoutBarChart(input) {
|
|
|
378
322
|
const y0 = y(from);
|
|
379
323
|
const y1 = y(to);
|
|
380
324
|
bars.push({
|
|
381
|
-
|
|
382
|
-
|
|
325
|
+
series: s.name,
|
|
326
|
+
category,
|
|
327
|
+
value,
|
|
328
|
+
color,
|
|
329
|
+
title: markTitle(s.name, category, value),
|
|
383
330
|
x: px(x.start(ci) + (input.stacked ? 0 : si * groupWidth)),
|
|
384
331
|
y: px(Math.min(y0, y1)),
|
|
385
332
|
width: px(groupWidth),
|
|
386
333
|
height: px(Math.abs(y1 - y0)),
|
|
387
|
-
fill: color,
|
|
388
|
-
title: markTitle(s.name, category, value),
|
|
389
334
|
});
|
|
390
335
|
});
|
|
391
336
|
});
|
|
392
|
-
return { ...frame,
|
|
337
|
+
return { ...frame, bars };
|
|
393
338
|
}
|
|
394
339
|
function stackedExtent(input) {
|
|
395
340
|
let min = 0;
|
|
@@ -416,52 +361,39 @@ function stackedExtent(input) {
|
|
|
416
361
|
* This file is part of the SkandaDX organization.
|
|
417
362
|
* Licensed under the MIT License. See LICENSE in the repository root.
|
|
418
363
|
*/
|
|
419
|
-
|
|
420
|
-
function polylines(input, { frame, x, y, categories }, area) {
|
|
364
|
+
function polylines(input, { frame, x, y, categories }) {
|
|
421
365
|
const points = [];
|
|
422
366
|
const lines = [];
|
|
423
|
-
const
|
|
367
|
+
const ends = [];
|
|
424
368
|
input.series.forEach((s, si) => {
|
|
425
369
|
const color = seriesColor(si, s.color);
|
|
426
370
|
const coords = s.data.map((value, ci) => {
|
|
427
|
-
const p = {
|
|
428
|
-
|
|
371
|
+
const p = {
|
|
372
|
+
series: s.name,
|
|
373
|
+
color,
|
|
374
|
+
title: markTitle(s.name, categories[ci], value),
|
|
375
|
+
x: px(x.center(ci)),
|
|
376
|
+
y: px(y(value)),
|
|
377
|
+
};
|
|
378
|
+
points.push(p);
|
|
429
379
|
return p;
|
|
430
380
|
});
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
kind: 'path',
|
|
434
|
-
part: 'line',
|
|
435
|
-
d,
|
|
436
|
-
stroke: color,
|
|
437
|
-
strokeWidth: 2,
|
|
438
|
-
strokeLinecap: 'round',
|
|
439
|
-
strokeLinejoin: 'round',
|
|
440
|
-
});
|
|
441
|
-
if (area) {
|
|
442
|
-
const first = coords[0];
|
|
443
|
-
const last = coords[coords.length - 1];
|
|
444
|
-
areas.push({
|
|
445
|
-
kind: 'path',
|
|
446
|
-
part: 'area',
|
|
447
|
-
d: d && first && last
|
|
448
|
-
? `${d}L${last.x} ${frame.baseline}L${first.x} ${frame.baseline}Z`
|
|
449
|
-
: '',
|
|
450
|
-
fill: color,
|
|
451
|
-
fillOpacity: 0.25,
|
|
452
|
-
});
|
|
453
|
-
}
|
|
381
|
+
lines.push({ series: s.name, color, d: pathThrough(coords, input.curve) });
|
|
382
|
+
ends.push({ first: px(x.center(0)), last: px(x.center(Math.max(0, s.data.length - 1))) });
|
|
454
383
|
});
|
|
455
|
-
return {
|
|
456
|
-
...frame,
|
|
457
|
-
shapes: [...frameShapes(frame), ...areas, ...lines, ...points, ...frame.shapes],
|
|
458
|
-
};
|
|
384
|
+
return { frame, lines, points, ends };
|
|
459
385
|
}
|
|
460
386
|
function layoutLineChart(input) {
|
|
461
|
-
|
|
387
|
+
const { frame, lines, points } = polylines(input, buildFrame(input, extent(values(input), false)));
|
|
388
|
+
return { ...frame, lines, points };
|
|
462
389
|
}
|
|
463
390
|
function layoutAreaChart(input) {
|
|
464
|
-
|
|
391
|
+
const { frame, lines, points, ends } = polylines(input, buildFrame(input, extent(values(input), true)));
|
|
392
|
+
const areas = lines.map((l, i) => {
|
|
393
|
+
const { first, last } = ends[i];
|
|
394
|
+
return { ...l, d: l.d ? `${l.d}L${last} ${frame.baseline}L${first} ${frame.baseline}Z` : '' };
|
|
395
|
+
});
|
|
396
|
+
return { ...frame, lines, points, areas };
|
|
465
397
|
}
|
|
466
398
|
|
|
467
399
|
/*
|
|
@@ -475,14 +407,25 @@ function layoutScatterChart(input) {
|
|
|
475
407
|
const pairs = input.series.flatMap((s) => s.data);
|
|
476
408
|
const x = axis(extent(pairs.map((p) => p[0]), false), [plot.x, plot.x + plot.width]);
|
|
477
409
|
const y = axis(extent(pairs.map((p) => p[1]), false), [plot.y + plot.height, plot.y]);
|
|
478
|
-
const legend = input.series.map((s, i) => ({ name: s.name, color: seriesColor(i, s.color) }));
|
|
479
|
-
const c = canvas(input, width, height, legend);
|
|
480
410
|
const points = input.series.flatMap((s, si) => {
|
|
481
411
|
const color = seriesColor(si, s.color);
|
|
482
|
-
return s.data.map(([vx, vy]) =>
|
|
412
|
+
return s.data.map(([vx, vy]) => ({
|
|
413
|
+
series: s.name,
|
|
414
|
+
color,
|
|
415
|
+
title: `${s.name}: ${formatValue(vx)}, ${formatValue(vy)}`,
|
|
416
|
+
x: px(x.scale(vx)),
|
|
417
|
+
y: px(y.scale(vy)),
|
|
418
|
+
}));
|
|
483
419
|
});
|
|
484
|
-
const
|
|
485
|
-
return {
|
|
420
|
+
const legend = input.series.map((s, i) => ({ name: s.name, color: seriesColor(i, s.color) }));
|
|
421
|
+
return {
|
|
422
|
+
...canvas(input, width, height, legend),
|
|
423
|
+
plot,
|
|
424
|
+
xTicks: x.ticks,
|
|
425
|
+
yTicks: y.ticks,
|
|
426
|
+
baseline: y.zero,
|
|
427
|
+
points,
|
|
428
|
+
};
|
|
486
429
|
}
|
|
487
430
|
|
|
488
431
|
/*
|
|
@@ -522,23 +465,29 @@ function layoutPieChart(input) {
|
|
|
522
465
|
if (input.labels && percent > 0.03) {
|
|
523
466
|
const mid = (a0 + angle) / 2;
|
|
524
467
|
const lr = (r + r0) / 2;
|
|
525
|
-
labels.push(
|
|
468
|
+
labels.push({
|
|
469
|
+
kind: 'text',
|
|
526
470
|
part: 'slice-label',
|
|
471
|
+
x: px(cx + lr * Math.sin(mid)),
|
|
472
|
+
y: px(cy - lr * Math.cos(mid)),
|
|
473
|
+
text: `${d.name} ${Math.round(percent * 100)}%`,
|
|
527
474
|
anchor: 'middle',
|
|
528
475
|
baseline: 'middle',
|
|
529
476
|
fill: 'var(--skdx-color-text-on-accent)',
|
|
530
|
-
})
|
|
477
|
+
});
|
|
531
478
|
}
|
|
532
479
|
return {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
480
|
+
name: d.name,
|
|
481
|
+
value: d.value,
|
|
482
|
+
percent,
|
|
483
|
+
series: d.name,
|
|
484
|
+
color: seriesColor(i, d.color),
|
|
537
485
|
title: `${d.name}: ${formatValue(d.value)} (${Math.round(percent * 100)}%)`,
|
|
486
|
+
d: percent > 0 ? arc(cx, cy, r, r0, a0, angle) : '',
|
|
538
487
|
};
|
|
539
488
|
});
|
|
540
|
-
const c = canvas(input, width, height,
|
|
541
|
-
return { ...c, shapes: [...
|
|
489
|
+
const c = canvas(input, width, height, slices.map((s) => ({ name: s.name, color: s.color })));
|
|
490
|
+
return { ...c, shapes: [...c.shapes, ...labels], slices };
|
|
542
491
|
}
|
|
543
492
|
|
|
544
493
|
/*
|
|
@@ -556,25 +505,15 @@ function layoutSparkline(input) {
|
|
|
556
505
|
const line = pathThrough(coords, input.curve);
|
|
557
506
|
const last = coords[coords.length - 1];
|
|
558
507
|
const first = coords[0];
|
|
559
|
-
const color = seriesColor(0, input.color);
|
|
560
508
|
return {
|
|
561
509
|
width,
|
|
562
510
|
height,
|
|
511
|
+
shapes: [],
|
|
563
512
|
tooltip: input.tooltip ?? true,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
d: line && first && last
|
|
569
|
-
? `${line}L${last.x} ${height - PAD$3}L${first.x} ${height - PAD$3}Z`
|
|
570
|
-
: '',
|
|
571
|
-
fill: color,
|
|
572
|
-
fillOpacity: 0.15,
|
|
573
|
-
},
|
|
574
|
-
{ kind: 'path', part: 'line', d: line, stroke: color, strokeWidth: 1.5 },
|
|
575
|
-
// The most recent point, drawn as a dot.
|
|
576
|
-
...(last ? [point(last.x, last.y, 2, color)] : []),
|
|
577
|
-
],
|
|
513
|
+
color: seriesColor(0, input.color),
|
|
514
|
+
line,
|
|
515
|
+
area: line && first && last ? `${line}L${last.x} ${height - PAD$3}L${first.x} ${height - PAD$3}Z` : '',
|
|
516
|
+
last,
|
|
578
517
|
};
|
|
579
518
|
}
|
|
580
519
|
|
|
@@ -614,62 +553,44 @@ function layoutRadarChart(input) {
|
|
|
614
553
|
return `${p.x} ${p.y}`;
|
|
615
554
|
})
|
|
616
555
|
.join('L')}Z`;
|
|
617
|
-
// Concentric grid polygons, one per tick, innermost first, then a spoke per category.
|
|
618
|
-
const rings = ticks.filter((t) => t > 0);
|
|
619
|
-
const grid = [
|
|
620
|
-
...rings.map((t) => ({
|
|
621
|
-
kind: 'path',
|
|
622
|
-
part: 'grid',
|
|
623
|
-
d: polygon(() => t),
|
|
624
|
-
stroke: CHART_COLORS.grid,
|
|
625
|
-
})),
|
|
626
|
-
...input.categories.map((_, i) => {
|
|
627
|
-
const p = at(i, max);
|
|
628
|
-
return {
|
|
629
|
-
kind: 'line',
|
|
630
|
-
part: 'grid',
|
|
631
|
-
x1: px(cx),
|
|
632
|
-
y1: px(cy),
|
|
633
|
-
x2: p.x,
|
|
634
|
-
y2: p.y,
|
|
635
|
-
stroke: CHART_COLORS.grid,
|
|
636
|
-
};
|
|
637
|
-
}),
|
|
638
|
-
...rings.map((t) => label(px(cx + 4), at(0, t).y, input.normalize ? `${t}%` : formatValue(t), {
|
|
639
|
-
part: 'y-label',
|
|
640
|
-
baseline: 'middle',
|
|
641
|
-
})),
|
|
642
|
-
...input.categories.map((text, i) => {
|
|
643
|
-
const cos = Math.cos(angle(i));
|
|
644
|
-
const r = radius + 14;
|
|
645
|
-
return label(px(cx + r * cos), px(cy + r * Math.sin(angle(i))), text, {
|
|
646
|
-
part: 'x-label',
|
|
647
|
-
anchor: cos > 0.1 ? 'start' : cos < -0.1 ? 'end' : 'middle',
|
|
648
|
-
baseline: 'middle',
|
|
649
|
-
});
|
|
650
|
-
}),
|
|
651
|
-
];
|
|
652
556
|
const points = [];
|
|
653
557
|
const polygons = input.series.map((s, si) => {
|
|
654
558
|
const color = seriesColor(si, s.color);
|
|
655
559
|
input.categories.forEach((category, i) => {
|
|
656
560
|
const value = s.data[i] ?? 0;
|
|
657
|
-
|
|
658
|
-
|
|
561
|
+
points.push({
|
|
562
|
+
series: s.name,
|
|
563
|
+
color,
|
|
564
|
+
title: markTitle(s.name, category, value),
|
|
565
|
+
...at(i, norm(si, value)),
|
|
566
|
+
});
|
|
659
567
|
});
|
|
660
|
-
return {
|
|
661
|
-
kind: 'path',
|
|
662
|
-
part: 'area',
|
|
663
|
-
d: polygon((i) => norm(si, s.data[i] ?? 0)),
|
|
664
|
-
fill: color,
|
|
665
|
-
fillOpacity: 0.25,
|
|
666
|
-
stroke: color,
|
|
667
|
-
strokeWidth: 2,
|
|
668
|
-
};
|
|
568
|
+
return { series: s.name, color, d: polygon((i) => norm(si, s.data[i] ?? 0)) };
|
|
669
569
|
});
|
|
670
|
-
|
|
671
|
-
|
|
570
|
+
return {
|
|
571
|
+
...canvas(input, width, height, polygons.map((p) => ({ name: p.series, color: p.color }))),
|
|
572
|
+
rings: ticks
|
|
573
|
+
.filter((t) => t > 0)
|
|
574
|
+
.map((t) => ({
|
|
575
|
+
d: polygon(() => t),
|
|
576
|
+
label: { x: px(cx + 4), y: at(0, t).y, label: input.normalize ? `${t}%` : formatValue(t) },
|
|
577
|
+
})),
|
|
578
|
+
spokes: input.categories.map((_, i) => ({ x1: px(cx), y1: px(cy), ...toXY(at(i, max)) })),
|
|
579
|
+
axisLabels: input.categories.map((label, i) => {
|
|
580
|
+
const cos = Math.cos(angle(i));
|
|
581
|
+
const r = radius + 14;
|
|
582
|
+
return {
|
|
583
|
+
x: px(cx + r * cos),
|
|
584
|
+
y: px(cy + r * Math.sin(angle(i))),
|
|
585
|
+
label,
|
|
586
|
+
anchor: cos > 0.1 ? 'start' : cos < -0.1 ? 'end' : 'middle',
|
|
587
|
+
};
|
|
588
|
+
}),
|
|
589
|
+
polygons,
|
|
590
|
+
points,
|
|
591
|
+
};
|
|
672
592
|
}
|
|
593
|
+
const toXY = (p) => ({ x2: p.x, y2: p.y });
|
|
673
594
|
|
|
674
595
|
/*
|
|
675
596
|
* Copyright (c) 2026 SkandaDX
|
|
@@ -689,7 +610,6 @@ function layoutHeatmap(input) {
|
|
|
689
610
|
const negative = input.negativeColor ?? 'var(--skdx-color-danger-500)';
|
|
690
611
|
const span = Math.max(Math.abs(min), Math.abs(max));
|
|
691
612
|
// Diverging: opacity is the distance from zero, color the sign.
|
|
692
|
-
// Otherwise 0.15..1, the value's place between the smallest and largest cell.
|
|
693
613
|
const opacity = (v) => input.diverging
|
|
694
614
|
? span === 0
|
|
695
615
|
? 1
|
|
@@ -704,34 +624,34 @@ function layoutHeatmap(input) {
|
|
|
704
624
|
if (value === undefined)
|
|
705
625
|
return;
|
|
706
626
|
cells.push({
|
|
707
|
-
|
|
708
|
-
|
|
627
|
+
series: row,
|
|
628
|
+
row,
|
|
629
|
+
column,
|
|
630
|
+
value,
|
|
631
|
+
color: input.diverging && value < 0 ? negative : color,
|
|
632
|
+
opacity: opacity(value),
|
|
633
|
+
title: `${row}, ${column}: ${formatValue(value)}`,
|
|
709
634
|
x: px(plot.x + ci * cellW),
|
|
710
635
|
y: px(plot.y + ri * cellH),
|
|
711
636
|
width: px(cellW),
|
|
712
637
|
height: px(cellH),
|
|
713
|
-
fill: input.diverging && value < 0 ? negative : color,
|
|
714
|
-
opacity: opacity(value),
|
|
715
|
-
title: `${row}, ${column}: ${formatValue(value)}`,
|
|
716
638
|
});
|
|
717
639
|
});
|
|
718
640
|
});
|
|
719
|
-
const c = canvas(input, width, height);
|
|
720
641
|
return {
|
|
721
|
-
...
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
],
|
|
642
|
+
...canvas(input, width, height),
|
|
643
|
+
plot,
|
|
644
|
+
cells,
|
|
645
|
+
rowLabels: input.rows.map((label, i) => ({
|
|
646
|
+
x: plot.x - 8,
|
|
647
|
+
y: px(plot.y + (i + 0.5) * cellH),
|
|
648
|
+
label,
|
|
649
|
+
})),
|
|
650
|
+
columnLabels: input.columns.map((label, i) => ({
|
|
651
|
+
x: px(plot.x + (i + 0.5) * cellW),
|
|
652
|
+
y: plot.y - 8,
|
|
653
|
+
label,
|
|
654
|
+
})),
|
|
735
655
|
};
|
|
736
656
|
}
|
|
737
657
|
|
|
@@ -751,34 +671,90 @@ function layoutFunnelChart(input) {
|
|
|
751
671
|
const offset = legendTop(input);
|
|
752
672
|
const stageH = n === 0 ? 0 : (height - offset - 2 * PAD$2) / n;
|
|
753
673
|
const widthOf = (value) => (max > 0 ? (Math.max(0, value) / max) * full : 0);
|
|
754
|
-
const
|
|
755
|
-
const stages = input.data.flatMap((d, i) => {
|
|
674
|
+
const stages = input.data.map((d, i) => {
|
|
756
675
|
const top = widthOf(d.value);
|
|
757
676
|
const bottom = widthOf(input.data[i + 1]?.value ?? d.value);
|
|
758
677
|
const y0 = offset + PAD$2 + i * stageH;
|
|
759
678
|
const y1 = y0 + stageH - GAP;
|
|
760
679
|
const cx = width / 2;
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
baseline: 'middle',
|
|
774
|
-
fill: 'var(--skdx-color-text-on-accent)',
|
|
775
|
-
}),
|
|
776
|
-
];
|
|
680
|
+
return {
|
|
681
|
+
name: d.name,
|
|
682
|
+
value: d.value,
|
|
683
|
+
percent: first > 0 ? Math.max(0, d.value) / first : 0,
|
|
684
|
+
series: d.name,
|
|
685
|
+
color: seriesColor(i, d.color),
|
|
686
|
+
title: `${d.name}: ${formatValue(d.value)} (${Math.round((first > 0 ? d.value / first : 0) * 100)}%)`,
|
|
687
|
+
d: `M${px(cx - top / 2)} ${px(y0)}L${px(cx + top / 2)} ${px(y0)}L${px(cx + bottom / 2)} ${px(y1)}L${px(cx - bottom / 2)} ${px(y1)}Z`,
|
|
688
|
+
x: px(cx),
|
|
689
|
+
y: px((y0 + y1) / 2),
|
|
690
|
+
label: `${d.name} · ${formatValue(d.value)}`,
|
|
691
|
+
};
|
|
777
692
|
});
|
|
778
|
-
|
|
779
|
-
|
|
693
|
+
return {
|
|
694
|
+
...canvas(input, width, height, stages.map((s) => ({ name: s.name, color: s.color }))),
|
|
695
|
+
stages,
|
|
696
|
+
};
|
|
780
697
|
}
|
|
781
698
|
|
|
699
|
+
/*
|
|
700
|
+
* Copyright (c) 2026 SkandaDX
|
|
701
|
+
* This file is part of the SkandaDX organization.
|
|
702
|
+
* Licensed under the MIT License. See LICENSE in the repository root.
|
|
703
|
+
*/
|
|
704
|
+
/** Grid, axis line and tick labels of an axis frame, as shapes. */
|
|
705
|
+
function frameShapes(frame) {
|
|
706
|
+
const { plot, xTicks, yTicks, baseline } = frame;
|
|
707
|
+
const right = plot.x + plot.width;
|
|
708
|
+
return [
|
|
709
|
+
...yTicks.map((t) => ({
|
|
710
|
+
kind: 'line',
|
|
711
|
+
part: 'grid',
|
|
712
|
+
x1: plot.x,
|
|
713
|
+
x2: right,
|
|
714
|
+
y1: t.pos,
|
|
715
|
+
y2: t.pos,
|
|
716
|
+
stroke: CHART_COLORS.grid,
|
|
717
|
+
})),
|
|
718
|
+
{
|
|
719
|
+
kind: 'line',
|
|
720
|
+
part: 'axis',
|
|
721
|
+
x1: plot.x,
|
|
722
|
+
x2: right,
|
|
723
|
+
y1: baseline,
|
|
724
|
+
y2: baseline,
|
|
725
|
+
stroke: CHART_COLORS.axis,
|
|
726
|
+
},
|
|
727
|
+
...yTicks.map((t) => ({
|
|
728
|
+
kind: 'text',
|
|
729
|
+
part: 'y-label',
|
|
730
|
+
x: plot.x - 8,
|
|
731
|
+
y: t.pos,
|
|
732
|
+
text: t.label,
|
|
733
|
+
anchor: 'end',
|
|
734
|
+
baseline: 'middle',
|
|
735
|
+
fill: CHART_COLORS.label,
|
|
736
|
+
})),
|
|
737
|
+
...xTicks.map((t) => ({
|
|
738
|
+
kind: 'text',
|
|
739
|
+
part: 'x-label',
|
|
740
|
+
x: t.pos,
|
|
741
|
+
y: plot.y + plot.height + 20,
|
|
742
|
+
text: t.label,
|
|
743
|
+
anchor: 'middle',
|
|
744
|
+
fill: CHART_COLORS.label,
|
|
745
|
+
})),
|
|
746
|
+
];
|
|
747
|
+
}
|
|
748
|
+
const label = (x, y, text, extra = {}) => ({
|
|
749
|
+
kind: 'text',
|
|
750
|
+
part: 'label',
|
|
751
|
+
x,
|
|
752
|
+
y,
|
|
753
|
+
text,
|
|
754
|
+
fill: CHART_COLORS.label,
|
|
755
|
+
...extra,
|
|
756
|
+
});
|
|
757
|
+
|
|
782
758
|
/*
|
|
783
759
|
* Copyright (c) 2026 SkandaDX
|
|
784
760
|
* This file is part of the SkandaDX organization.
|
|
@@ -1003,8 +979,10 @@ function layoutTreemap(input) {
|
|
|
1003
979
|
});
|
|
1004
980
|
};
|
|
1005
981
|
tile(input.data, 0, top, width, height - top, undefined);
|
|
1006
|
-
|
|
1007
|
-
|
|
982
|
+
return {
|
|
983
|
+
...canvas(input, width, height, legend),
|
|
984
|
+
shapes: [...shapes, ...canvas(input, width, height, legend).shapes],
|
|
985
|
+
};
|
|
1008
986
|
}
|
|
1009
987
|
|
|
1010
988
|
/*
|
|
@@ -1479,10 +1457,7 @@ class SkdxChartShapesComponent {
|
|
|
1479
1457
|
[attr.fill]="s.fill ?? 'none'"
|
|
1480
1458
|
[attr.stroke]="s.stroke"
|
|
1481
1459
|
[attr.stroke-width]="s.strokeWidth"
|
|
1482
|
-
[attr.stroke-linecap]="s.strokeLinecap"
|
|
1483
|
-
[attr.stroke-linejoin]="s.strokeLinejoin"
|
|
1484
1460
|
[attr.opacity]="s.opacity"
|
|
1485
|
-
[attr.fill-opacity]="s.fillOpacity"
|
|
1486
1461
|
>
|
|
1487
1462
|
@if (s.title) {
|
|
1488
1463
|
<svg:title>{{ s.title }}</svg:title>
|
|
@@ -1565,10 +1540,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1565
1540
|
[attr.fill]="s.fill ?? 'none'"
|
|
1566
1541
|
[attr.stroke]="s.stroke"
|
|
1567
1542
|
[attr.stroke-width]="s.strokeWidth"
|
|
1568
|
-
[attr.stroke-linecap]="s.strokeLinecap"
|
|
1569
|
-
[attr.stroke-linejoin]="s.strokeLinejoin"
|
|
1570
1543
|
[attr.opacity]="s.opacity"
|
|
1571
|
-
[attr.fill-opacity]="s.fillOpacity"
|
|
1572
1544
|
>
|
|
1573
1545
|
@if (s.title) {
|
|
1574
1546
|
<svg:title>{{ s.title }}</svg:title>
|
|
@@ -1680,6 +1652,7 @@ class SkdxChartRootComponent {
|
|
|
1680
1652
|
(pointerleave)="tip.set([])"
|
|
1681
1653
|
>
|
|
1682
1654
|
<title>{{ label() }}</title>
|
|
1655
|
+
<ng-content></ng-content>
|
|
1683
1656
|
<svg:g skdxChartShapes [shapes]="layout().shapes"></svg:g>
|
|
1684
1657
|
<svg:g skdxChartShapes [shapes]="tip()"></svg:g>
|
|
1685
1658
|
</svg>
|
|
@@ -1709,6 +1682,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1709
1682
|
(pointerleave)="tip.set([])"
|
|
1710
1683
|
>
|
|
1711
1684
|
<title>{{ label() }}</title>
|
|
1685
|
+
<ng-content></ng-content>
|
|
1712
1686
|
<svg:g skdxChartShapes [shapes]="layout().shapes"></svg:g>
|
|
1713
1687
|
<svg:g skdxChartShapes [shapes]="tip()"></svg:g>
|
|
1714
1688
|
</svg>
|
|
@@ -1716,6 +1690,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1716
1690
|
}]
|
|
1717
1691
|
}], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }] } });
|
|
1718
1692
|
/** The `<svg>` root, grid, axis and tick labels every axis chart shares; marks are projected. */
|
|
1693
|
+
class SkdxChartFrameComponent {
|
|
1694
|
+
constructor() {
|
|
1695
|
+
this.layout = input.required(/* @ts-ignore */
|
|
1696
|
+
...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
1697
|
+
this.kind = input.required(/* @ts-ignore */
|
|
1698
|
+
...(ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []));
|
|
1699
|
+
this.label = input.required(/* @ts-ignore */
|
|
1700
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1701
|
+
this.colors = CHART_COLORS;
|
|
1702
|
+
this.plot = computed(() => this.layout().plot, /* @ts-ignore */
|
|
1703
|
+
...(ngDevMode ? [{ debugName: "plot" }] : /* istanbul ignore next */ []));
|
|
1704
|
+
this.right = computed(() => this.plot().x + this.plot().width, /* @ts-ignore */
|
|
1705
|
+
...(ngDevMode ? [{ debugName: "right" }] : /* istanbul ignore next */ []));
|
|
1706
|
+
}
|
|
1707
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1708
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: SkdxChartFrameComponent, isStandalone: true, selector: "skdx-chart-frame", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, kind: { classPropertyName: "kind", publicName: "kind", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, host: { styleAttribute: "display: inline-block" }, ngImport: i0, template: `
|
|
1709
|
+
<skdx-chart-root [layout]="layout()" [kind]="kind()" [label]="label()">
|
|
1710
|
+
<svg:g data-skdx-part="grid" [attr.stroke]="colors.grid">
|
|
1711
|
+
@for (t of layout().yTicks; track t.pos) {
|
|
1712
|
+
<svg:line
|
|
1713
|
+
[attr.x1]="plot().x"
|
|
1714
|
+
[attr.x2]="right()"
|
|
1715
|
+
[attr.y1]="t.pos"
|
|
1716
|
+
[attr.y2]="t.pos"
|
|
1717
|
+
></svg:line>
|
|
1718
|
+
}
|
|
1719
|
+
</svg:g>
|
|
1720
|
+
<svg:line
|
|
1721
|
+
data-skdx-part="axis"
|
|
1722
|
+
[attr.x1]="plot().x"
|
|
1723
|
+
[attr.x2]="right()"
|
|
1724
|
+
[attr.y1]="layout().baseline"
|
|
1725
|
+
[attr.y2]="layout().baseline"
|
|
1726
|
+
[attr.stroke]="colors.axis"
|
|
1727
|
+
></svg:line>
|
|
1728
|
+
<svg:g
|
|
1729
|
+
data-skdx-part="y-labels"
|
|
1730
|
+
[attr.fill]="colors.label"
|
|
1731
|
+
text-anchor="end"
|
|
1732
|
+
dominant-baseline="middle"
|
|
1733
|
+
>
|
|
1734
|
+
@for (t of layout().yTicks; track t.pos) {
|
|
1735
|
+
<svg:text [attr.x]="plot().x - 8" [attr.y]="t.pos">{{ t.label }}</svg:text>
|
|
1736
|
+
}
|
|
1737
|
+
</svg:g>
|
|
1738
|
+
<svg:g data-skdx-part="x-labels" [attr.fill]="colors.label" text-anchor="middle">
|
|
1739
|
+
@for (t of layout().xTicks; track $index) {
|
|
1740
|
+
<svg:text [attr.x]="t.pos" [attr.y]="plot().y + plot().height + 20">
|
|
1741
|
+
{{ t.label }}
|
|
1742
|
+
</svg:text>
|
|
1743
|
+
}
|
|
1744
|
+
</svg:g>
|
|
1745
|
+
<ng-content></ng-content>
|
|
1746
|
+
</skdx-chart-root>
|
|
1747
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SkdxChartRootComponent, selector: "skdx-chart-root", inputs: ["layout", "kind", "label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1748
|
+
}
|
|
1749
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartFrameComponent, decorators: [{
|
|
1750
|
+
type: Component,
|
|
1751
|
+
args: [{
|
|
1752
|
+
selector: 'skdx-chart-frame',
|
|
1753
|
+
standalone: true,
|
|
1754
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1755
|
+
host: { style: 'display: inline-block' },
|
|
1756
|
+
imports: [SkdxChartRootComponent],
|
|
1757
|
+
template: `
|
|
1758
|
+
<skdx-chart-root [layout]="layout()" [kind]="kind()" [label]="label()">
|
|
1759
|
+
<svg:g data-skdx-part="grid" [attr.stroke]="colors.grid">
|
|
1760
|
+
@for (t of layout().yTicks; track t.pos) {
|
|
1761
|
+
<svg:line
|
|
1762
|
+
[attr.x1]="plot().x"
|
|
1763
|
+
[attr.x2]="right()"
|
|
1764
|
+
[attr.y1]="t.pos"
|
|
1765
|
+
[attr.y2]="t.pos"
|
|
1766
|
+
></svg:line>
|
|
1767
|
+
}
|
|
1768
|
+
</svg:g>
|
|
1769
|
+
<svg:line
|
|
1770
|
+
data-skdx-part="axis"
|
|
1771
|
+
[attr.x1]="plot().x"
|
|
1772
|
+
[attr.x2]="right()"
|
|
1773
|
+
[attr.y1]="layout().baseline"
|
|
1774
|
+
[attr.y2]="layout().baseline"
|
|
1775
|
+
[attr.stroke]="colors.axis"
|
|
1776
|
+
></svg:line>
|
|
1777
|
+
<svg:g
|
|
1778
|
+
data-skdx-part="y-labels"
|
|
1779
|
+
[attr.fill]="colors.label"
|
|
1780
|
+
text-anchor="end"
|
|
1781
|
+
dominant-baseline="middle"
|
|
1782
|
+
>
|
|
1783
|
+
@for (t of layout().yTicks; track t.pos) {
|
|
1784
|
+
<svg:text [attr.x]="plot().x - 8" [attr.y]="t.pos">{{ t.label }}</svg:text>
|
|
1785
|
+
}
|
|
1786
|
+
</svg:g>
|
|
1787
|
+
<svg:g data-skdx-part="x-labels" [attr.fill]="colors.label" text-anchor="middle">
|
|
1788
|
+
@for (t of layout().xTicks; track $index) {
|
|
1789
|
+
<svg:text [attr.x]="t.pos" [attr.y]="plot().y + plot().height + 20">
|
|
1790
|
+
{{ t.label }}
|
|
1791
|
+
</svg:text>
|
|
1792
|
+
}
|
|
1793
|
+
</svg:g>
|
|
1794
|
+
<ng-content></ng-content>
|
|
1795
|
+
</skdx-chart-root>
|
|
1796
|
+
`,
|
|
1797
|
+
}]
|
|
1798
|
+
}], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], kind: [{ type: i0.Input, args: [{ isSignal: true, alias: "kind", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }] } });
|
|
1799
|
+
/** A dot per value with its native tooltip. */
|
|
1800
|
+
class SkdxChartPointsComponent {
|
|
1801
|
+
constructor() {
|
|
1802
|
+
this.points = input.required(/* @ts-ignore */
|
|
1803
|
+
...(ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []));
|
|
1804
|
+
}
|
|
1805
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartPointsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1806
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: SkdxChartPointsComponent, isStandalone: true, selector: "g[skdxChartPoints]", inputs: { points: { classPropertyName: "points", publicName: "points", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
1807
|
+
@for (p of points(); track $index) {
|
|
1808
|
+
<svg:circle
|
|
1809
|
+
data-skdx-part="point"
|
|
1810
|
+
[attr.cx]="p.x"
|
|
1811
|
+
[attr.cy]="p.y"
|
|
1812
|
+
r="3"
|
|
1813
|
+
[attr.fill]="p.color"
|
|
1814
|
+
>
|
|
1815
|
+
<svg:title>{{ p.title }}</svg:title>
|
|
1816
|
+
</svg:circle>
|
|
1817
|
+
}
|
|
1818
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1819
|
+
}
|
|
1820
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartPointsComponent, decorators: [{
|
|
1821
|
+
type: Component,
|
|
1822
|
+
args: [{
|
|
1823
|
+
selector: 'g[skdxChartPoints]',
|
|
1824
|
+
standalone: true,
|
|
1825
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1826
|
+
template: `
|
|
1827
|
+
@for (p of points(); track $index) {
|
|
1828
|
+
<svg:circle
|
|
1829
|
+
data-skdx-part="point"
|
|
1830
|
+
[attr.cx]="p.x"
|
|
1831
|
+
[attr.cy]="p.y"
|
|
1832
|
+
r="3"
|
|
1833
|
+
[attr.fill]="p.color"
|
|
1834
|
+
>
|
|
1835
|
+
<svg:title>{{ p.title }}</svg:title>
|
|
1836
|
+
</svg:circle>
|
|
1837
|
+
}
|
|
1838
|
+
`,
|
|
1839
|
+
}]
|
|
1840
|
+
}], propDecorators: { points: [{ type: i0.Input, args: [{ isSignal: true, alias: "points", required: true }] }] } });
|
|
1841
|
+
/** Size and label inputs every chart takes. */
|
|
1719
1842
|
class SkdxSizedBase {
|
|
1720
1843
|
constructor() {
|
|
1721
1844
|
this.width = input(/* @ts-ignore */
|
|
@@ -1765,6 +1888,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1765
1888
|
type: Directive
|
|
1766
1889
|
}], propDecorators: { series: [{ type: i0.Input, args: [{ isSignal: true, alias: "series", required: true }] }], categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: false }] }] } });
|
|
1767
1890
|
|
|
1891
|
+
/*
|
|
1892
|
+
* Copyright (c) 2026 SkandaDX
|
|
1893
|
+
* This file is part of the SkandaDX organization.
|
|
1894
|
+
* Licensed under the MIT License. See LICENSE in the repository root.
|
|
1895
|
+
*/
|
|
1896
|
+
/** Line strokes plus a dot per value, shared by the line and area charts. */
|
|
1897
|
+
class SkdxChartLinesComponent {
|
|
1898
|
+
constructor() {
|
|
1899
|
+
this.lines = input.required(/* @ts-ignore */
|
|
1900
|
+
...(ngDevMode ? [{ debugName: "lines" }] : /* istanbul ignore next */ []));
|
|
1901
|
+
this.points = input.required(/* @ts-ignore */
|
|
1902
|
+
...(ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []));
|
|
1903
|
+
}
|
|
1904
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartLinesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1905
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: SkdxChartLinesComponent, isStandalone: true, selector: "g[skdxChartLines]", inputs: { lines: { classPropertyName: "lines", publicName: "lines", isSignal: true, isRequired: true, transformFunction: null }, points: { classPropertyName: "points", publicName: "points", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
1906
|
+
@for (l of lines(); track l.series) {
|
|
1907
|
+
<svg:path
|
|
1908
|
+
data-skdx-part="line"
|
|
1909
|
+
[attr.d]="l.d"
|
|
1910
|
+
fill="none"
|
|
1911
|
+
[attr.stroke]="l.color"
|
|
1912
|
+
stroke-width="2"
|
|
1913
|
+
stroke-linejoin="round"
|
|
1914
|
+
stroke-linecap="round"
|
|
1915
|
+
></svg:path>
|
|
1916
|
+
}
|
|
1917
|
+
<svg:g skdxChartPoints [points]="points()"></svg:g>
|
|
1918
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SkdxChartPointsComponent, selector: "g[skdxChartPoints]", inputs: ["points"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1919
|
+
}
|
|
1920
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: SkdxChartLinesComponent, decorators: [{
|
|
1921
|
+
type: Component,
|
|
1922
|
+
args: [{
|
|
1923
|
+
selector: 'g[skdxChartLines]',
|
|
1924
|
+
standalone: true,
|
|
1925
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1926
|
+
imports: [SkdxChartPointsComponent],
|
|
1927
|
+
template: `
|
|
1928
|
+
@for (l of lines(); track l.series) {
|
|
1929
|
+
<svg:path
|
|
1930
|
+
data-skdx-part="line"
|
|
1931
|
+
[attr.d]="l.d"
|
|
1932
|
+
fill="none"
|
|
1933
|
+
[attr.stroke]="l.color"
|
|
1934
|
+
stroke-width="2"
|
|
1935
|
+
stroke-linejoin="round"
|
|
1936
|
+
stroke-linecap="round"
|
|
1937
|
+
></svg:path>
|
|
1938
|
+
}
|
|
1939
|
+
<svg:g skdxChartPoints [points]="points()"></svg:g>
|
|
1940
|
+
`,
|
|
1941
|
+
}]
|
|
1942
|
+
}], propDecorators: { lines: [{ type: i0.Input, args: [{ isSignal: true, alias: "lines", required: true }] }], points: [{ type: i0.Input, args: [{ isSignal: true, alias: "points", required: true }] }] } });
|
|
1943
|
+
|
|
1768
1944
|
/*
|
|
1769
1945
|
* Copyright (c) 2026 SkandaDX
|
|
1770
1946
|
* This file is part of the SkandaDX organization.
|
|
@@ -1775,5 +1951,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1775
1951
|
* Generated bundle index. Do not edit.
|
|
1776
1952
|
*/
|
|
1777
1953
|
|
|
1778
|
-
export { CHART_COLORS, SkdxChartBase, SkdxChartRootComponent, SkdxChartShapesComponent, SkdxSizedBase, hoverTooltip, layoutAreaChart, layoutBarChart, layoutBoxplot, layoutCandlestick, layoutChord, layoutFunnelChart, layoutGantt, layoutHeatmap, layoutLineChart, layoutMap, layoutPieChart, layoutRadarChart, layoutSankey, layoutScatterChart, layoutSparkline, layoutSunburst, layoutTreemap, layoutWaterfall };
|
|
1954
|
+
export { CHART_COLORS, SERIES_COLORS, SkdxChartBase, SkdxChartFrameComponent, SkdxChartLinesComponent, SkdxChartPointsComponent, SkdxChartRootComponent, SkdxChartShapesComponent, SkdxSizedBase, boxStats, formatValue, hoverTooltip, layoutAreaChart, layoutBarChart, layoutBoxplot, layoutCandlestick, layoutChord, layoutFunnelChart, layoutGantt, layoutHeatmap, layoutLineChart, layoutMap, layoutPieChart, layoutRadarChart, layoutSankey, layoutScatterChart, layoutSparkline, layoutSunburst, layoutTreemap, layoutWaterfall, linearScale, logTicks, niceTicks, pathThrough, seriesColor, svgAttrs, tooltipShapes };
|
|
1779
1955
|
//# sourceMappingURL=skdx-angular-charts-internal.mjs.map
|