@skdx/angular-charts 0.32.0 → 0.33.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 +14 -32
- package/fesm2022/skdx-angular-charts-area.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-bar.mjs +14 -38
- 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 +11 -43
- 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 +4 -69
- package/fesm2022/skdx-angular-charts-heatmap.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-internal.mjs +235 -411
- package/fesm2022/skdx-angular-charts-internal.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-line.mjs +13 -15
- package/fesm2022/skdx-angular-charts-line.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-map.mjs +2 -8
- package/fesm2022/skdx-angular-charts-map.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-pie.mjs +11 -21
- package/fesm2022/skdx-angular-charts-pie.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-radar.mjs +14 -77
- 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 +13 -15
- package/fesm2022/skdx-angular-charts-scatter.mjs.map +1 -1
- package/fesm2022/skdx-angular-charts-sparkline.mjs +11 -55
- 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 +2 -10
- 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 +2 -11
- 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 +1 -8
- package/types/skdx-angular-charts-internal.d.ts +26 -200
- 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 +1 -8
- 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,
|
|
2
|
+
import { input, ChangeDetectionStrategy, Component, signal, Directive } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2026 SkandaDX
|
|
@@ -261,19 +261,6 @@ 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
|
-
}
|
|
277
264
|
const values = (input) => input.series.flatMap((s) => s.data);
|
|
278
265
|
/** Tooltip text for a value in a series: `Series, Category: 1,234`. */
|
|
279
266
|
const markTitle = (series, category, value) => `${series}, ${category}: ${formatValue(value)}`;
|
|
@@ -292,6 +279,75 @@ function hoverTooltip(target, svg, clientX, clientY, width, height) {
|
|
|
292
279
|
return tooltipShapes(x, y, title, width, height);
|
|
293
280
|
}
|
|
294
281
|
|
|
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
|
+
|
|
295
351
|
/*
|
|
296
352
|
* Copyright (c) 2026 SkandaDX
|
|
297
353
|
* This file is part of the SkandaDX organization.
|
|
@@ -322,19 +378,18 @@ function layoutBarChart(input) {
|
|
|
322
378
|
const y0 = y(from);
|
|
323
379
|
const y1 = y(to);
|
|
324
380
|
bars.push({
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
value,
|
|
328
|
-
color,
|
|
329
|
-
title: markTitle(s.name, category, value),
|
|
381
|
+
kind: 'rect',
|
|
382
|
+
part: 'bar',
|
|
330
383
|
x: px(x.start(ci) + (input.stacked ? 0 : si * groupWidth)),
|
|
331
384
|
y: px(Math.min(y0, y1)),
|
|
332
385
|
width: px(groupWidth),
|
|
333
386
|
height: px(Math.abs(y1 - y0)),
|
|
387
|
+
fill: color,
|
|
388
|
+
title: markTitle(s.name, category, value),
|
|
334
389
|
});
|
|
335
390
|
});
|
|
336
391
|
});
|
|
337
|
-
return { ...frame, bars };
|
|
392
|
+
return { ...frame, shapes: [...frameShapes(frame), ...bars, ...frame.shapes] };
|
|
338
393
|
}
|
|
339
394
|
function stackedExtent(input) {
|
|
340
395
|
let min = 0;
|
|
@@ -361,39 +416,52 @@ function stackedExtent(input) {
|
|
|
361
416
|
* This file is part of the SkandaDX organization.
|
|
362
417
|
* Licensed under the MIT License. See LICENSE in the repository root.
|
|
363
418
|
*/
|
|
364
|
-
|
|
419
|
+
/** A stroke per series and a dot per value; `close` turns a stroke into a filled area. */
|
|
420
|
+
function polylines(input, { frame, x, y, categories }, area) {
|
|
365
421
|
const points = [];
|
|
366
422
|
const lines = [];
|
|
367
|
-
const
|
|
423
|
+
const areas = [];
|
|
368
424
|
input.series.forEach((s, si) => {
|
|
369
425
|
const color = seriesColor(si, s.color);
|
|
370
426
|
const coords = s.data.map((value, ci) => {
|
|
371
|
-
const p = {
|
|
372
|
-
|
|
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);
|
|
427
|
+
const p = { x: px(x.center(ci)), y: px(y(value)) };
|
|
428
|
+
points.push(point(p.x, p.y, 3, color, markTitle(s.name, categories[ci], value)));
|
|
379
429
|
return p;
|
|
380
430
|
});
|
|
381
|
-
|
|
382
|
-
|
|
431
|
+
const d = pathThrough(coords, input.curve);
|
|
432
|
+
lines.push({
|
|
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
|
+
}
|
|
383
454
|
});
|
|
384
|
-
return {
|
|
455
|
+
return {
|
|
456
|
+
...frame,
|
|
457
|
+
shapes: [...frameShapes(frame), ...areas, ...lines, ...points, ...frame.shapes],
|
|
458
|
+
};
|
|
385
459
|
}
|
|
386
460
|
function layoutLineChart(input) {
|
|
387
|
-
|
|
388
|
-
return { ...frame, lines, points };
|
|
461
|
+
return polylines(input, buildFrame(input, extent(values(input), false)), false);
|
|
389
462
|
}
|
|
390
463
|
function layoutAreaChart(input) {
|
|
391
|
-
|
|
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 };
|
|
464
|
+
return polylines(input, buildFrame(input, extent(values(input), true)), true);
|
|
397
465
|
}
|
|
398
466
|
|
|
399
467
|
/*
|
|
@@ -407,25 +475,14 @@ function layoutScatterChart(input) {
|
|
|
407
475
|
const pairs = input.series.flatMap((s) => s.data);
|
|
408
476
|
const x = axis(extent(pairs.map((p) => p[0]), false), [plot.x, plot.x + plot.width]);
|
|
409
477
|
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);
|
|
410
480
|
const points = input.series.flatMap((s, si) => {
|
|
411
481
|
const color = seriesColor(si, s.color);
|
|
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
|
-
}));
|
|
482
|
+
return s.data.map(([vx, vy]) => point(px(x.scale(vx)), px(y.scale(vy)), 3, color, `${s.name}: ${formatValue(vx)}, ${formatValue(vy)}`));
|
|
419
483
|
});
|
|
420
|
-
const
|
|
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
|
-
};
|
|
484
|
+
const frame = { ...c, plot, xTicks: x.ticks, yTicks: y.ticks, baseline: y.zero };
|
|
485
|
+
return { ...c, shapes: [...frameShapes(frame), ...points, ...c.shapes] };
|
|
429
486
|
}
|
|
430
487
|
|
|
431
488
|
/*
|
|
@@ -465,29 +522,23 @@ function layoutPieChart(input) {
|
|
|
465
522
|
if (input.labels && percent > 0.03) {
|
|
466
523
|
const mid = (a0 + angle) / 2;
|
|
467
524
|
const lr = (r + r0) / 2;
|
|
468
|
-
labels.push({
|
|
469
|
-
kind: 'text',
|
|
525
|
+
labels.push(label(px(cx + lr * Math.sin(mid)), px(cy - lr * Math.cos(mid)), `${d.name} ${Math.round(percent * 100)}%`, {
|
|
470
526
|
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)}%`,
|
|
474
527
|
anchor: 'middle',
|
|
475
528
|
baseline: 'middle',
|
|
476
529
|
fill: 'var(--skdx-color-text-on-accent)',
|
|
477
|
-
});
|
|
530
|
+
}));
|
|
478
531
|
}
|
|
479
532
|
return {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
percent,
|
|
483
|
-
series: d.name,
|
|
484
|
-
color: seriesColor(i, d.color),
|
|
485
|
-
title: `${d.name}: ${formatValue(d.value)} (${Math.round(percent * 100)}%)`,
|
|
533
|
+
kind: 'path',
|
|
534
|
+
part: 'slice',
|
|
486
535
|
d: percent > 0 ? arc(cx, cy, r, r0, a0, angle) : '',
|
|
536
|
+
fill: seriesColor(i, d.color),
|
|
537
|
+
title: `${d.name}: ${formatValue(d.value)} (${Math.round(percent * 100)}%)`,
|
|
487
538
|
};
|
|
488
539
|
});
|
|
489
|
-
const c = canvas(input, width, height,
|
|
490
|
-
return { ...c, shapes: [...c.shapes, ...labels]
|
|
540
|
+
const c = canvas(input, width, height, input.data.map((d, i) => ({ name: d.name, color: seriesColor(i, d.color) })));
|
|
541
|
+
return { ...c, shapes: [...slices, ...c.shapes, ...labels] };
|
|
491
542
|
}
|
|
492
543
|
|
|
493
544
|
/*
|
|
@@ -505,15 +556,25 @@ function layoutSparkline(input) {
|
|
|
505
556
|
const line = pathThrough(coords, input.curve);
|
|
506
557
|
const last = coords[coords.length - 1];
|
|
507
558
|
const first = coords[0];
|
|
559
|
+
const color = seriesColor(0, input.color);
|
|
508
560
|
return {
|
|
509
561
|
width,
|
|
510
562
|
height,
|
|
511
|
-
shapes: [],
|
|
512
563
|
tooltip: input.tooltip ?? true,
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
564
|
+
shapes: [
|
|
565
|
+
{
|
|
566
|
+
kind: 'path',
|
|
567
|
+
part: 'area',
|
|
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
|
+
],
|
|
517
578
|
};
|
|
518
579
|
}
|
|
519
580
|
|
|
@@ -553,44 +614,62 @@ function layoutRadarChart(input) {
|
|
|
553
614
|
return `${p.x} ${p.y}`;
|
|
554
615
|
})
|
|
555
616
|
.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
|
+
];
|
|
556
652
|
const points = [];
|
|
557
653
|
const polygons = input.series.map((s, si) => {
|
|
558
654
|
const color = seriesColor(si, s.color);
|
|
559
655
|
input.categories.forEach((category, i) => {
|
|
560
656
|
const value = s.data[i] ?? 0;
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
color,
|
|
564
|
-
title: markTitle(s.name, category, value),
|
|
565
|
-
...at(i, norm(si, value)),
|
|
566
|
-
});
|
|
657
|
+
const p = at(i, norm(si, value));
|
|
658
|
+
points.push(point(p.x, p.y, 3, color, markTitle(s.name, category, value)));
|
|
567
659
|
});
|
|
568
|
-
return {
|
|
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
|
+
};
|
|
569
669
|
});
|
|
570
|
-
|
|
571
|
-
|
|
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
|
-
};
|
|
670
|
+
const c = canvas(input, width, height, input.series.map((s, i) => ({ name: s.name, color: seriesColor(i, s.color) })));
|
|
671
|
+
return { ...c, shapes: [...grid, ...polygons, ...points, ...c.shapes] };
|
|
592
672
|
}
|
|
593
|
-
const toXY = (p) => ({ x2: p.x, y2: p.y });
|
|
594
673
|
|
|
595
674
|
/*
|
|
596
675
|
* Copyright (c) 2026 SkandaDX
|
|
@@ -610,6 +689,7 @@ function layoutHeatmap(input) {
|
|
|
610
689
|
const negative = input.negativeColor ?? 'var(--skdx-color-danger-500)';
|
|
611
690
|
const span = Math.max(Math.abs(min), Math.abs(max));
|
|
612
691
|
// 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.
|
|
613
693
|
const opacity = (v) => input.diverging
|
|
614
694
|
? span === 0
|
|
615
695
|
? 1
|
|
@@ -624,34 +704,34 @@ function layoutHeatmap(input) {
|
|
|
624
704
|
if (value === undefined)
|
|
625
705
|
return;
|
|
626
706
|
cells.push({
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
column,
|
|
630
|
-
value,
|
|
631
|
-
color: input.diverging && value < 0 ? negative : color,
|
|
632
|
-
opacity: opacity(value),
|
|
633
|
-
title: `${row}, ${column}: ${formatValue(value)}`,
|
|
707
|
+
kind: 'rect',
|
|
708
|
+
part: 'cell',
|
|
634
709
|
x: px(plot.x + ci * cellW),
|
|
635
710
|
y: px(plot.y + ri * cellH),
|
|
636
711
|
width: px(cellW),
|
|
637
712
|
height: px(cellH),
|
|
713
|
+
fill: input.diverging && value < 0 ? negative : color,
|
|
714
|
+
opacity: opacity(value),
|
|
715
|
+
title: `${row}, ${column}: ${formatValue(value)}`,
|
|
638
716
|
});
|
|
639
717
|
});
|
|
640
718
|
});
|
|
719
|
+
const c = canvas(input, width, height);
|
|
641
720
|
return {
|
|
642
|
-
...
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
721
|
+
...c,
|
|
722
|
+
shapes: [
|
|
723
|
+
...input.rows.map((text, i) => label(plot.x - 8, px(plot.y + (i + 0.5) * cellH), text, {
|
|
724
|
+
part: 'y-label',
|
|
725
|
+
anchor: 'end',
|
|
726
|
+
baseline: 'middle',
|
|
727
|
+
})),
|
|
728
|
+
...input.columns.map((text, i) => label(px(plot.x + (i + 0.5) * cellW), plot.y - 8, text, {
|
|
729
|
+
part: 'x-label',
|
|
730
|
+
anchor: 'middle',
|
|
731
|
+
})),
|
|
732
|
+
...cells,
|
|
733
|
+
...c.shapes,
|
|
734
|
+
],
|
|
655
735
|
};
|
|
656
736
|
}
|
|
657
737
|
|
|
@@ -671,90 +751,34 @@ function layoutFunnelChart(input) {
|
|
|
671
751
|
const offset = legendTop(input);
|
|
672
752
|
const stageH = n === 0 ? 0 : (height - offset - 2 * PAD$2) / n;
|
|
673
753
|
const widthOf = (value) => (max > 0 ? (Math.max(0, value) / max) * full : 0);
|
|
674
|
-
const
|
|
754
|
+
const legend = input.data.map((d, i) => ({ name: d.name, color: seriesColor(i, d.color) }));
|
|
755
|
+
const stages = input.data.flatMap((d, i) => {
|
|
675
756
|
const top = widthOf(d.value);
|
|
676
757
|
const bottom = widthOf(input.data[i + 1]?.value ?? d.value);
|
|
677
758
|
const y0 = offset + PAD$2 + i * stageH;
|
|
678
759
|
const y1 = y0 + stageH - GAP;
|
|
679
760
|
const cx = width / 2;
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
761
|
+
const percent = first > 0 ? d.value / first : 0;
|
|
762
|
+
return [
|
|
763
|
+
{
|
|
764
|
+
kind: 'path',
|
|
765
|
+
part: 'stage',
|
|
766
|
+
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`,
|
|
767
|
+
fill: seriesColor(i, d.color),
|
|
768
|
+
title: `${d.name}: ${formatValue(d.value)} (${Math.round(percent * 100)}%)`,
|
|
769
|
+
},
|
|
770
|
+
label(px(cx), px((y0 + y1) / 2), `${d.name} · ${formatValue(d.value)}`, {
|
|
771
|
+
part: 'stage-label',
|
|
772
|
+
anchor: 'middle',
|
|
773
|
+
baseline: 'middle',
|
|
774
|
+
fill: 'var(--skdx-color-text-on-accent)',
|
|
775
|
+
}),
|
|
776
|
+
];
|
|
692
777
|
});
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
stages,
|
|
696
|
-
};
|
|
778
|
+
const c = canvas(input, width, height, legend);
|
|
779
|
+
return { ...c, shapes: [...stages, ...c.shapes] };
|
|
697
780
|
}
|
|
698
781
|
|
|
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
|
-
|
|
758
782
|
/*
|
|
759
783
|
* Copyright (c) 2026 SkandaDX
|
|
760
784
|
* This file is part of the SkandaDX organization.
|
|
@@ -979,10 +1003,8 @@ function layoutTreemap(input) {
|
|
|
979
1003
|
});
|
|
980
1004
|
};
|
|
981
1005
|
tile(input.data, 0, top, width, height - top, undefined);
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
shapes: [...shapes, ...canvas(input, width, height, legend).shapes],
|
|
985
|
-
};
|
|
1006
|
+
const c = canvas(input, width, height, legend);
|
|
1007
|
+
return { ...c, shapes: [...shapes, ...c.shapes] };
|
|
986
1008
|
}
|
|
987
1009
|
|
|
988
1010
|
/*
|
|
@@ -1457,7 +1479,10 @@ class SkdxChartShapesComponent {
|
|
|
1457
1479
|
[attr.fill]="s.fill ?? 'none'"
|
|
1458
1480
|
[attr.stroke]="s.stroke"
|
|
1459
1481
|
[attr.stroke-width]="s.strokeWidth"
|
|
1482
|
+
[attr.stroke-linecap]="s.strokeLinecap"
|
|
1483
|
+
[attr.stroke-linejoin]="s.strokeLinejoin"
|
|
1460
1484
|
[attr.opacity]="s.opacity"
|
|
1485
|
+
[attr.fill-opacity]="s.fillOpacity"
|
|
1461
1486
|
>
|
|
1462
1487
|
@if (s.title) {
|
|
1463
1488
|
<svg:title>{{ s.title }}</svg:title>
|
|
@@ -1540,7 +1565,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1540
1565
|
[attr.fill]="s.fill ?? 'none'"
|
|
1541
1566
|
[attr.stroke]="s.stroke"
|
|
1542
1567
|
[attr.stroke-width]="s.strokeWidth"
|
|
1568
|
+
[attr.stroke-linecap]="s.strokeLinecap"
|
|
1569
|
+
[attr.stroke-linejoin]="s.strokeLinejoin"
|
|
1543
1570
|
[attr.opacity]="s.opacity"
|
|
1571
|
+
[attr.fill-opacity]="s.fillOpacity"
|
|
1544
1572
|
>
|
|
1545
1573
|
@if (s.title) {
|
|
1546
1574
|
<svg:title>{{ s.title }}</svg:title>
|
|
@@ -1652,7 +1680,6 @@ class SkdxChartRootComponent {
|
|
|
1652
1680
|
(pointerleave)="tip.set([])"
|
|
1653
1681
|
>
|
|
1654
1682
|
<title>{{ label() }}</title>
|
|
1655
|
-
<ng-content></ng-content>
|
|
1656
1683
|
<svg:g skdxChartShapes [shapes]="layout().shapes"></svg:g>
|
|
1657
1684
|
<svg:g skdxChartShapes [shapes]="tip()"></svg:g>
|
|
1658
1685
|
</svg>
|
|
@@ -1682,7 +1709,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1682
1709
|
(pointerleave)="tip.set([])"
|
|
1683
1710
|
>
|
|
1684
1711
|
<title>{{ label() }}</title>
|
|
1685
|
-
<ng-content></ng-content>
|
|
1686
1712
|
<svg:g skdxChartShapes [shapes]="layout().shapes"></svg:g>
|
|
1687
1713
|
<svg:g skdxChartShapes [shapes]="tip()"></svg:g>
|
|
1688
1714
|
</svg>
|
|
@@ -1690,155 +1716,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1690
1716
|
}]
|
|
1691
1717
|
}], 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 }] }] } });
|
|
1692
1718
|
/** 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. */
|
|
1842
1719
|
class SkdxSizedBase {
|
|
1843
1720
|
constructor() {
|
|
1844
1721
|
this.width = input(/* @ts-ignore */
|
|
@@ -1888,59 +1765,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1888
1765
|
type: Directive
|
|
1889
1766
|
}], propDecorators: { series: [{ type: i0.Input, args: [{ isSignal: true, alias: "series", required: true }] }], categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: false }] }] } });
|
|
1890
1767
|
|
|
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
|
-
|
|
1944
1768
|
/*
|
|
1945
1769
|
* Copyright (c) 2026 SkandaDX
|
|
1946
1770
|
* This file is part of the SkandaDX organization.
|
|
@@ -1951,5 +1775,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1951
1775
|
* Generated bundle index. Do not edit.
|
|
1952
1776
|
*/
|
|
1953
1777
|
|
|
1954
|
-
export { CHART_COLORS,
|
|
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 };
|
|
1955
1779
|
//# sourceMappingURL=skdx-angular-charts-internal.mjs.map
|