@vadem/ui 0.0.3 → 0.1.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/vadem-ui-chart.mjs +25 -25
- package/fesm2022/vadem-ui-chart.mjs.map +1 -1
- package/fesm2022/vadem-ui-field.mjs +7 -3
- package/fesm2022/vadem-ui-field.mjs.map +1 -1
- package/fesm2022/vadem-ui.mjs +1 -1
- package/fesm2022/vadem-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/components/slider.css +6 -0
- package/types/vadem-ui-chart.d.ts +9 -9
- package/types/vadem-ui-field.d.ts +3 -0
- package/types/vadem-ui.d.ts +1 -1
|
@@ -3,7 +3,7 @@ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ViewEncapsul
|
|
|
3
3
|
import { VD_LOCALE, vdTexts } from "@vadem/ui/locale";
|
|
4
4
|
import { VdButton } from "@vadem/ui/button";
|
|
5
5
|
import { vdUniqueId } from "@vadem/ui/field";
|
|
6
|
-
function
|
|
6
|
+
function vdLinearScale(domain, range) {
|
|
7
7
|
const [d0, d1] = domain;
|
|
8
8
|
const [r0, r1] = range;
|
|
9
9
|
const span = d1 - d0 || 1;
|
|
@@ -13,7 +13,7 @@ function linearScale(domain, range) {
|
|
|
13
13
|
range
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
-
function
|
|
16
|
+
function vdNiceTicks(min, max, target = 5) {
|
|
17
17
|
const lo = Math.min(0, min);
|
|
18
18
|
const hi = Math.max(0, max);
|
|
19
19
|
if (lo === hi) return [0, 1];
|
|
@@ -32,7 +32,7 @@ function niceTicks(min, max, target = 5) {
|
|
|
32
32
|
for (let v = start; v <= end + step / 2; v += step) ticks.push(Number(v.toFixed(10)));
|
|
33
33
|
return ticks;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
35
|
+
function vdBands(count, range) {
|
|
36
36
|
const [r0, r1] = range;
|
|
37
37
|
const step = count > 0 ? (r1 - r0) / count : 0;
|
|
38
38
|
return Array.from({ length: count }, (_, i) => ({
|
|
@@ -41,13 +41,13 @@ function bands(count, range) {
|
|
|
41
41
|
step
|
|
42
42
|
}));
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function vdNearestIndex(position, count, range) {
|
|
45
45
|
if (count <= 0) return -1;
|
|
46
46
|
const [r0, r1] = range;
|
|
47
47
|
const t = (position - r0) / (r1 - r0 || 1);
|
|
48
48
|
return Math.min(count - 1, Math.max(0, Math.floor(t * count)));
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function vdStack(series, count) {
|
|
51
51
|
const up = new Array(count).fill(0);
|
|
52
52
|
const down = new Array(count).fill(0);
|
|
53
53
|
return series.map((s) => Array.from({ length: count }, (_, i) => {
|
|
@@ -68,10 +68,10 @@ function stack(series, count) {
|
|
|
68
68
|
return seg;
|
|
69
69
|
}));
|
|
70
70
|
}
|
|
71
|
-
function
|
|
71
|
+
function vdExtent(series, count, stacked) {
|
|
72
72
|
let min = 0;
|
|
73
73
|
let max = 0;
|
|
74
|
-
if (stacked) for (const segments of
|
|
74
|
+
if (stacked) for (const segments of vdStack(series, count)) for (const seg of segments) {
|
|
75
75
|
min = Math.min(min, seg.to);
|
|
76
76
|
max = Math.max(max, seg.to);
|
|
77
77
|
}
|
|
@@ -83,7 +83,7 @@ function extent(series, count, stacked) {
|
|
|
83
83
|
return [min, max];
|
|
84
84
|
}
|
|
85
85
|
const r = (n) => Math.round(n * 100) / 100;
|
|
86
|
-
function
|
|
86
|
+
function vdBarPath(center, thickness, base, end, radius, orientation) {
|
|
87
87
|
const length = Math.abs(end - base);
|
|
88
88
|
if (length < .5) return "";
|
|
89
89
|
const rad = Math.min(radius, thickness / 2, length);
|
|
@@ -109,7 +109,7 @@ function barPath(center, thickness, base, end, radius, orientation) {
|
|
|
109
109
|
"Z"
|
|
110
110
|
].join(" ");
|
|
111
111
|
}
|
|
112
|
-
function
|
|
112
|
+
function vdLinePath(points) {
|
|
113
113
|
let d = "";
|
|
114
114
|
let pen = false;
|
|
115
115
|
for (const p of points) {
|
|
@@ -122,7 +122,7 @@ function linePath(points) {
|
|
|
122
122
|
}
|
|
123
123
|
return d;
|
|
124
124
|
}
|
|
125
|
-
function
|
|
125
|
+
function vdAreaPath(points, baseline) {
|
|
126
126
|
const runs = [[]];
|
|
127
127
|
for (const p of points) if (p) runs[runs.length - 1].push(p);
|
|
128
128
|
else if (runs[runs.length - 1].length) runs.push([]);
|
|
@@ -662,7 +662,7 @@ var VdChartBase = class VdChartBase {
|
|
|
662
662
|
width = computed(() => this.frame().width(), ...ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []);
|
|
663
663
|
ticks = computed(() => {
|
|
664
664
|
const [min, max] = this.extentOf();
|
|
665
|
-
return
|
|
665
|
+
return vdNiceTicks(min, max, Math.max(2, Math.round(this.height() / 60)));
|
|
666
666
|
}, ...ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []);
|
|
667
667
|
compact = computed(() => new Intl.NumberFormat(this.localeCode(), {
|
|
668
668
|
notation: "compact",
|
|
@@ -679,7 +679,7 @@ var VdChartBase = class VdChartBase {
|
|
|
679
679
|
categoryWidth = computed(() => Math.max(...this.categories().map((c) => c.length), 1) * CHAR_PX + AXIS_FONT_GAP, ...ngDevMode ? [{ debugName: "categoryWidth" }] : /* istanbul ignore next */ []);
|
|
680
680
|
valueScale(range) {
|
|
681
681
|
const ticks = this.ticks();
|
|
682
|
-
return
|
|
682
|
+
return vdLinearScale([ticks[0], ticks[ticks.length - 1]], range);
|
|
683
683
|
}
|
|
684
684
|
slot(index) {
|
|
685
685
|
return seriesSlot(index, this.series().length);
|
|
@@ -694,7 +694,7 @@ var VdChartBase = class VdChartBase {
|
|
|
694
694
|
return Math.max(1, Math.ceil(this.count() / fit));
|
|
695
695
|
}
|
|
696
696
|
pointerAt(position, range) {
|
|
697
|
-
this.active.set(
|
|
697
|
+
this.active.set(vdNearestIndex(position, this.count(), range));
|
|
698
698
|
}
|
|
699
699
|
onKeydown(event, index) {
|
|
700
700
|
const last = this.count() - 1;
|
|
@@ -917,7 +917,7 @@ var VdBarChart = class VdBarChart extends VdChartBase {
|
|
|
917
917
|
}, ...ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []);
|
|
918
918
|
stackedValues = () => this.stacked();
|
|
919
919
|
extentOf() {
|
|
920
|
-
return
|
|
920
|
+
return vdExtent(this.series(), this.count(), this.stacked());
|
|
921
921
|
}
|
|
922
922
|
vertical = computed(() => this.orientation() === "vertical", ...ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []);
|
|
923
923
|
box = computed(() => {
|
|
@@ -944,7 +944,7 @@ var VdBarChart = class VdBarChart extends VdChartBase {
|
|
|
944
944
|
const b = this.box();
|
|
945
945
|
return this.vertical() ? [b.x0, b.x1] : [b.y0, b.y1];
|
|
946
946
|
}, ...ngDevMode ? [{ debugName: "categoryRange" }] : /* istanbul ignore next */ []);
|
|
947
|
-
bandList = computed(() =>
|
|
947
|
+
bandList = computed(() => vdBands(this.count(), this.categoryRange()), ...ngDevMode ? [{ debugName: "bandList" }] : /* istanbul ignore next */ []);
|
|
948
948
|
marks = computed(() => {
|
|
949
949
|
const series = this.series();
|
|
950
950
|
const n = series.length;
|
|
@@ -954,7 +954,7 @@ var VdBarChart = class VdBarChart extends VdChartBase {
|
|
|
954
954
|
const orient = this.orientation();
|
|
955
955
|
const marks = [];
|
|
956
956
|
if (this.stacked()) {
|
|
957
|
-
const segments =
|
|
957
|
+
const segments = vdStack(series, this.count());
|
|
958
958
|
const outer = this.bandList().map((_, c) => {
|
|
959
959
|
let top = -1;
|
|
960
960
|
let bottom = -1;
|
|
@@ -978,7 +978,7 @@ var VdBarChart = class VdBarChart extends VdChartBase {
|
|
|
978
978
|
const dir = Math.sign(to - from);
|
|
979
979
|
const end = rounded ? to : to - dir * GAP;
|
|
980
980
|
marks.push({
|
|
981
|
-
d:
|
|
981
|
+
d: vdBarPath(band.center, thickness, from, end, rounded ? RADIUS : 0, orient),
|
|
982
982
|
series: i,
|
|
983
983
|
category: c
|
|
984
984
|
});
|
|
@@ -994,7 +994,7 @@ var VdBarChart = class VdBarChart extends VdChartBase {
|
|
|
994
994
|
if (v === null || v === void 0 || !Number.isFinite(v)) return;
|
|
995
995
|
const center = band.center - group / 2 + thickness / 2 + i * (thickness + GAP);
|
|
996
996
|
marks.push({
|
|
997
|
-
d:
|
|
997
|
+
d: vdBarPath(center, thickness, zero, scale(v), RADIUS, orient),
|
|
998
998
|
series: i,
|
|
999
999
|
category: c
|
|
1000
1000
|
});
|
|
@@ -1422,7 +1422,7 @@ var VdLineChart = class VdLineChart extends VdChartBase {
|
|
|
1422
1422
|
});
|
|
1423
1423
|
stackedValues = () => false;
|
|
1424
1424
|
extentOf() {
|
|
1425
|
-
return
|
|
1425
|
+
return vdExtent(this.series(), this.count(), false);
|
|
1426
1426
|
}
|
|
1427
1427
|
showArea = computed(() => this.area() && this.series().length === 1, ...ngDevMode ? [{ debugName: "showArea" }] : /* istanbul ignore next */ []);
|
|
1428
1428
|
labelled = computed(() => this.series().length > 1 && this.series().length <= MAX_END_LABELS, ...ngDevMode ? [{ debugName: "labelled" }] : /* istanbul ignore next */ []);
|
|
@@ -1451,8 +1451,8 @@ var VdLineChart = class VdLineChart extends VdChartBase {
|
|
|
1451
1451
|
const v = s.values[i];
|
|
1452
1452
|
return v === null || v === void 0 || !Number.isFinite(v) ? null : [x, this.scale()(v)];
|
|
1453
1453
|
})), ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
|
|
1454
|
-
lines = computed(() => this.points().map((p) =>
|
|
1455
|
-
areaD = computed(() =>
|
|
1454
|
+
lines = computed(() => this.points().map((p) => vdLinePath(p)), ...ngDevMode ? [{ debugName: "lines" }] : /* istanbul ignore next */ []);
|
|
1455
|
+
areaD = computed(() => vdAreaPath(this.points()[0] ?? [], this.scale()(0)), ...ngDevMode ? [{ debugName: "areaD" }] : /* istanbul ignore next */ []);
|
|
1456
1456
|
tickMarks = computed(() => this.ticks().map((value) => ({
|
|
1457
1457
|
value,
|
|
1458
1458
|
y: this.scale()(value)
|
|
@@ -1825,12 +1825,12 @@ var VdSparkline = class VdSparkline {
|
|
|
1825
1825
|
if (!nums.length) return [];
|
|
1826
1826
|
const min = Math.min(...nums);
|
|
1827
1827
|
const max = Math.max(...nums);
|
|
1828
|
-
const y =
|
|
1828
|
+
const y = vdLinearScale(min === max ? [min - 1, max + 1] : [min, max], [28, INSET]);
|
|
1829
1829
|
const n = values.length;
|
|
1830
1830
|
return values.map((v, i) => v === null || !Number.isFinite(v) ? null : [n > 1 ? i * W / (n - 1) : W / 2, y(v)]);
|
|
1831
1831
|
}, ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
|
|
1832
|
-
line = computed(() =>
|
|
1833
|
-
area = computed(() =>
|
|
1832
|
+
line = computed(() => vdLinePath(this.points()), ...ngDevMode ? [{ debugName: "line" }] : /* istanbul ignore next */ []);
|
|
1833
|
+
area = computed(() => vdAreaPath(this.points(), H), ...ngDevMode ? [{ debugName: "area" }] : /* istanbul ignore next */ []);
|
|
1834
1834
|
last = computed(() => [...this.points()].reverse().find((p) => p) ?? null, ...ngDevMode ? [{ debugName: "last" }] : /* istanbul ignore next */ []);
|
|
1835
1835
|
summary = computed(() => {
|
|
1836
1836
|
const nums = this.numbers();
|
|
@@ -1979,6 +1979,6 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
1979
1979
|
}]
|
|
1980
1980
|
}
|
|
1981
1981
|
});
|
|
1982
|
-
export { VdBarChart, VdChartFrame, VdLineChart, VdSparkline,
|
|
1982
|
+
export { VdBarChart, VdChartFrame, VdLineChart, VdSparkline, vdAreaPath, vdBands, vdBarPath, vdExtent, vdLinePath, vdLinearScale, vdNearestIndex, vdNiceTicks, vdStack };
|
|
1983
1983
|
|
|
1984
1984
|
//# sourceMappingURL=vadem-ui-chart.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui-chart.mjs","names":[],"sources":["../../../projects/ui/chart/src/core/chart-math.ts","../../../projects/ui/chart/src/chart-frame.ts","../../../projects/ui/chart/src/chart-base.ts","../../../projects/ui/chart/src/bar-chart.ts","../../../projects/ui/chart/src/line-chart.ts","../../../projects/ui/chart/src/sparkline.ts"],"sourcesContent":["/**\n * Framework-agnostic chart geometry: scales, ticks, stacking and SVG paths.\n * No DOM access; every function is pure and unit-tested.\n */\n\nexport interface VdChartSeries {\n name: string;\n /** One value per category; `null` = missing (a gap, never zero). */\n values: readonly (number | null)[];\n}\n\nexport interface VdLinearScale {\n domain: readonly [number, number];\n range: readonly [number, number];\n (value: number): number;\n}\n\nexport function linearScale(\n domain: readonly [number, number],\n range: readonly [number, number],\n): VdLinearScale {\n const [d0, d1] = domain;\n const [r0, r1] = range;\n const span = d1 - d0 || 1;\n const scale = ((value: number) => r0 + ((value - d0) / span) * (r1 - r0)) as VdLinearScale;\n return Object.assign(scale, { domain, range });\n}\n\n/** Round numbers for an axis: 1, 2, 2.5 or 5 times a power of ten. Always includes zero. */\nexport function niceTicks(min: number, max: number, target = 5): number[] {\n const lo = Math.min(0, min);\n const hi = Math.max(0, max);\n if (lo === hi) return [0, 1];\n const raw = (hi - lo) / Math.max(1, target);\n const power = 10 ** Math.floor(Math.log10(raw));\n const step = [1, 2, 2.5, 5, 10].map((m) => m * power).find((s) => s >= raw) ?? 10 * power;\n const start = Math.floor(lo / step) * step;\n const end = Math.ceil(hi / step) * step;\n const ticks: number[] = [];\n for (let v = start; v <= end + step / 2; v += step) ticks.push(Number(v.toFixed(10)));\n return ticks;\n}\n\nexport interface VdBand {\n /** Start of each band. */\n start: number;\n /** Centre of each band. */\n center: number;\n /** Band width including its share of padding. */\n step: number;\n}\n\n/** Evenly spaced bands across `range` for `count` categories. */\nexport function bands(count: number, range: readonly [number, number]): VdBand[] {\n const [r0, r1] = range;\n const step = count > 0 ? (r1 - r0) / count : 0;\n return Array.from({ length: count }, (_, i) => ({\n start: r0 + i * step,\n center: r0 + (i + 0.5) * step,\n step,\n }));\n}\n\n/** Index of the band nearest to `position` (pointer or keyboard), clamped. */\nexport function nearestIndex(position: number, count: number, range: readonly [number, number]) {\n if (count <= 0) return -1;\n const [r0, r1] = range;\n const t = (position - r0) / (r1 - r0 || 1);\n return Math.min(count - 1, Math.max(0, Math.floor(t * count)));\n}\n\nexport interface VdStackSegment {\n from: number;\n to: number;\n}\n\n/** Stacks positive values upward and negative values downward from zero, per category. */\nexport function stack(series: readonly VdChartSeries[], count: number): VdStackSegment[][] {\n const up = new Array<number>(count).fill(0);\n const down = new Array<number>(count).fill(0);\n return series.map((s) =>\n Array.from({ length: count }, (_, i) => {\n const v = s.values[i] ?? 0;\n if (v >= 0) {\n const seg = { from: up[i], to: up[i] + v };\n up[i] += v;\n return seg;\n }\n const seg = { from: down[i], to: down[i] + v };\n down[i] += v;\n return seg;\n }),\n );\n}\n\n/** [min, max] over all values (stacked totals when `stacked`). */\nexport function extent(series: readonly VdChartSeries[], count: number, stacked: boolean) {\n let min = 0;\n let max = 0;\n if (stacked) {\n for (const segments of stack(series, count))\n for (const seg of segments) {\n min = Math.min(min, seg.to);\n max = Math.max(max, seg.to);\n }\n } else {\n for (const s of series)\n for (const v of s.values) {\n if (v === null || !Number.isFinite(v)) continue;\n min = Math.min(min, v);\n max = Math.max(max, v);\n }\n }\n return [min, max] as const;\n}\n\nconst r = (n: number) => Math.round(n * 100) / 100;\n\n/**\n * A bar from `base` to `end` along the value axis, `thickness` wide, centred at `center` on the\n * category axis. The data end is rounded (`radius`), the baseline end square.\n */\nexport function barPath(\n center: number,\n thickness: number,\n base: number,\n end: number,\n radius: number,\n orientation: 'vertical' | 'horizontal',\n): string {\n const length = Math.abs(end - base);\n if (length < 0.5) return '';\n const rad = Math.min(radius, thickness / 2, length);\n const a = center - thickness / 2;\n const b = center + thickness / 2;\n const dir = end < base ? -1 : 1;\n const tip = end - dir * rad;\n if (orientation === 'vertical') {\n // Value axis is y; `dir` -1 means the bar grows upward on screen.\n return [\n `M${r(a)},${r(base)}`,\n `L${r(a)},${r(tip)}`,\n `Q${r(a)},${r(end)} ${r(a + rad)},${r(end)}`,\n `L${r(b - rad)},${r(end)}`,\n `Q${r(b)},${r(end)} ${r(b)},${r(tip)}`,\n `L${r(b)},${r(base)}`,\n 'Z',\n ].join(' ');\n }\n return [\n `M${r(base)},${r(a)}`,\n `L${r(tip)},${r(a)}`,\n `Q${r(end)},${r(a)} ${r(end)},${r(a + rad)}`,\n `L${r(end)},${r(b - rad)}`,\n `Q${r(end)},${r(b)} ${r(tip)},${r(b)}`,\n `L${r(base)},${r(b)}`,\n 'Z',\n ].join(' ');\n}\n\nexport type VdPoint = readonly [x: number, y: number] | null;\n\n/** Polyline through points; a `null` starts a new segment (missing data is a gap). */\nexport function linePath(points: readonly VdPoint[]): string {\n let d = '';\n let pen = false;\n for (const p of points) {\n if (!p) {\n pen = false;\n continue;\n }\n d += `${pen ? 'L' : 'M'}${r(p[0])},${r(p[1])}`;\n pen = true;\n }\n return d;\n}\n\n/** Closed area between each continuous run of points and the baseline. */\nexport function areaPath(points: readonly VdPoint[], baseline: number): string {\n const runs: (readonly [number, number])[][] = [[]];\n for (const p of points) {\n if (p) runs[runs.length - 1].push(p);\n else if (runs[runs.length - 1].length) runs.push([]);\n }\n return runs\n .filter((run) => run.length > 1)\n .map(\n (run) =>\n `M${r(run[0][0])},${r(baseline)}` +\n run.map(([x, y]) => `L${r(x)},${r(y)}`).join('') +\n `L${r(run[run.length - 1][0])},${r(baseline)}Z`,\n )\n .join('');\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { VdButton } from '@vadem/ui/button';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VD_LOCALE, vdTexts } from '@vadem/ui/locale';\nimport type { VdChartSeries } from './core/chart-math';\n\nexport type VdChartKind = 'bar' | 'line';\n\n/** Formats a value for tooltips and the table (full precision, locale-aware). */\nexport type VdChartFormat = (value: number) => string;\n\n/** Series identity: slot 1..8 for categorical, \"accent\" for a single series. */\nexport function seriesSlot(index: number, count: number): string {\n return count === 1 ? 'accent' : String((index % 8) + 1);\n}\n\n/**\n * Shared chart chrome: figure with title, legend (2+ series), data-table toggle, tooltip and\n * plot measurement. Charts project their SVG into it. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-chart-frame',\n imports: [VdButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'vd-chart' },\n template: `\n <figure\n class=\"vd-chart__figure\"\n [attr.aria-labelledby]=\"titleId\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-loading]=\"loading() ? '' : null\"\n >\n <figcaption class=\"vd-chart__head\">\n <span class=\"vd-chart__title\" [id]=\"titleId\">{{ title() }}</span>\n @if (description()) {\n <span class=\"vd-chart__description\">{{ description() }}</span>\n }\n </figcaption>\n <div class=\"vd-chart__toolbar\">\n @if (series().length > 1) {\n <ul class=\"vd-chart__legend\" role=\"list\">\n @for (s of series(); track $index) {\n <li class=\"vd-chart__legend-item\">\n <span\n class=\"vd-chart__key\"\n aria-hidden=\"true\"\n [attr.data-series]=\"slot($index)\"\n [attr.data-kind]=\"kind()\"\n ></span>\n {{ s.name }}\n </li>\n }\n </ul>\n }\n <button\n vdButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n class=\"vd-chart__table-toggle\"\n [attr.aria-pressed]=\"tableShown()\"\n [attr.aria-controls]=\"tableId\"\n (click)=\"tableShown.set(!tableShown())\"\n >\n {{ t().tableLabel }}\n </button>\n </div>\n\n <div #plot class=\"vd-chart__plot\" [hidden]=\"tableShown()\" (pointerleave)=\"leave()\">\n <ng-content />\n @if (active() >= 0 && tooltipX() !== null) {\n <div\n class=\"vd-chart__tooltip\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [attr.data-side]=\"tooltipSide()\"\n [style.--vd-chart-tip-x.px]=\"tooltipX()\"\n [style.--vd-chart-tip-y.px]=\"tooltipY()\"\n >\n <span class=\"vd-chart__tooltip-category\" dir=\"auto\">{{ categories()[active()] }}</span>\n @for (s of series(); track $index) {\n <span class=\"vd-chart__tooltip-row\">\n <span\n class=\"vd-chart__key\"\n [attr.data-series]=\"slot($index)\"\n data-kind=\"line\"\n ></span>\n <strong class=\"vd-chart__tooltip-value\">{{ valueText(s.values[active()]) }}</strong>\n <span class=\"vd-chart__tooltip-name\" dir=\"auto\">{{ s.name }}</span>\n </span>\n }\n </div>\n }\n </div>\n\n <div\n class=\"vd-chart__table-wrap\"\n role=\"region\"\n tabindex=\"0\"\n [id]=\"tableId\"\n [attr.aria-labelledby]=\"titleId\"\n [hidden]=\"!tableShown()\"\n >\n @if (tableShown()) {\n <table class=\"vd-chart__table\">\n <thead>\n <tr>\n <th scope=\"col\">{{ t().categoryLabel }}</th>\n @for (s of series(); track $index) {\n <th scope=\"col\">{{ s.name }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (c of categories(); track $index; let i = $index) {\n <tr>\n <th scope=\"row\">{{ c }}</th>\n @for (s of series(); track $index) {\n <td>{{ valueText(s.values[i]) }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </figure>\n `,\n})\nexport class VdChartFrame {\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly categories = input<readonly string[]>([]);\n readonly series = input<readonly VdChartSeries[]>([]);\n readonly kind = input<VdChartKind>('bar');\n readonly format = input<VdChartFormat>();\n readonly categoryLabel = input<string>();\n /** Highlighted category, driven by the chart (pointer or keyboard). */\n readonly active = input(-1);\n /** Tooltip anchor in plot pixels; null hides it. */\n readonly tooltipX = input<number | null>(null);\n readonly tooltipY = input(0);\n readonly tableLabel = input<string>();\n readonly loading = input(false);\n\n protected readonly t = vdTexts('chart', {\n tableLabel: this.tableLabel,\n categoryLabel: this.categoryLabel,\n });\n private readonly locale = inject(VD_LOCALE);\n readonly titleId = vdUniqueId('vd-chart-title');\n readonly tableId = vdUniqueId('vd-chart-table');\n readonly tableShown = signal(false);\n /** Measured plot width in CSS pixels (0 until the browser lays it out). */\n readonly width = signal(0);\n /** Fired when the pointer leaves the plot; charts clear their highlight. */\n readonly pointerLeave = output<void>();\n\n private readonly plot = viewChild.required<ElementRef<HTMLElement>>('plot');\n private readonly numberFormat = computed(() => new Intl.NumberFormat(this.locale.code));\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n afterNextRender(() => {\n const el = this.plot().nativeElement;\n const view = el.ownerDocument.defaultView;\n const measure = () => this.width.set(el.clientWidth);\n measure();\n if (!view?.ResizeObserver) return;\n const observer = new view.ResizeObserver(measure);\n observer.observe(el);\n destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n protected slot(index: number): string {\n return seriesSlot(index, this.series().length);\n }\n\n valueText(value: number | null | undefined): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return (this.format() ?? ((v: number) => this.numberFormat().format(v)))(value);\n }\n\n protected leave(): void {\n this.pointerLeave.emit();\n }\n\n /** The tooltip sits on the roomier side of its anchor. */\n protected readonly tooltipSide = computed(() =>\n (this.tooltipX() ?? 0) > this.width() / 2 ? 'start' : 'end',\n );\n}\n","import {\n Directive,\n booleanAttribute,\n computed,\n inject,\n input,\n numberAttribute,\n signal,\n viewChild,\n} from '@angular/core';\nimport { VD_LOCALE } from '@vadem/ui/locale';\nimport { linearScale, niceTicks, nearestIndex, type VdChartSeries } from './core/chart-math';\nimport { VdChartFrame, type VdChartFormat, seriesSlot } from './chart-frame';\n\n/** Average glyph width of 12px UI text, used to reserve room for axis labels. */\nconst CHAR_PX = 6.8;\nconst AXIS_FONT_GAP = 8;\n\n/**\n * Inputs, value scale and keyboard/pointer exploration shared by bar and line charts.\n * Rendering stays in each chart's template.\n */\n@Directive()\nexport abstract class VdChartBase {\n readonly title = input.required<string>();\n readonly description = input<string>();\n /** Category labels (x for columns and lines, y for horizontal bars). */\n readonly categories = input<readonly string[]>([]);\n readonly series = input<readonly VdChartSeries[]>([]);\n /** Plot height in pixels, including the category axis band. */\n readonly height = input(240, { transform: numberAttribute });\n /** Full value text for tooltips, labels and the table. Defaults to Intl in the locale. */\n readonly format = input<VdChartFormat>();\n /** Short value text for axis ticks. Defaults to compact Intl notation. */\n readonly axisFormat = input<VdChartFormat>();\n readonly categoryLabel = input<string>();\n /**\n * Refetching: keep the previous render, muted and `aria-busy`, so the table view, focus and\n * layout survive (dataviz: refetch keeps the frame, no skeleton).\n */\n readonly loading = input(false, { transform: booleanAttribute });\n\n protected readonly frame = viewChild.required(VdChartFrame);\n /** Highlighted category (pointer or keyboard), -1 when none. */\n protected readonly active = signal(-1);\n /** Roving tab stop among category hit targets. */\n protected readonly focusIndex = signal(0);\n\n protected readonly count = computed(() => this.categories().length);\n protected readonly width = computed(() => this.frame().width());\n\n protected abstract readonly stackedValues: () => boolean;\n protected abstract extentOf(): readonly [number, number];\n\n protected readonly ticks = computed(() => {\n const [min, max] = this.extentOf();\n return niceTicks(min, max, Math.max(2, Math.round(this.height() / 60)));\n });\n\n private readonly compact = computed(\n () =>\n new Intl.NumberFormat(this.localeCode(), { notation: 'compact', maximumFractionDigits: 1 }),\n );\n private readonly locale = inject(VD_LOCALE);\n protected localeCode(): string {\n return this.locale.code;\n }\n\n protected tickText(value: number): string {\n return (this.axisFormat() ?? ((v: number) => this.compact().format(v)))(value);\n }\n\n /** Room for the widest tick label. */\n protected readonly tickWidth = computed(\n () =>\n Math.max(...this.ticks().map((t) => this.tickText(t).length), 1) * CHAR_PX + AXIS_FONT_GAP,\n );\n protected readonly categoryWidth = computed(\n () => Math.max(...this.categories().map((c) => c.length), 1) * CHAR_PX + AXIS_FONT_GAP,\n );\n\n protected valueScale(range: readonly [number, number]) {\n const ticks = this.ticks();\n return linearScale([ticks[0], ticks[ticks.length - 1]], range);\n }\n\n protected slot(index: number): string {\n return seriesSlot(index, this.series().length);\n }\n\n /** \"Пн: Запити 4 200, Помилки 12\" - the accessible name of one category. */\n protected pointLabel(index: number): string {\n const values = this.series()\n .map((s) => `${s.name} ${this.frame().valueText(s.values[index])}`)\n .join(', ');\n return `${this.categories()[index]}: ${values}`;\n }\n\n /** Every `k`-th category label so labels never overlap. */\n protected labelEvery(available: number): number {\n const per = this.categoryWidth();\n const fit = Math.max(1, Math.floor(available / per));\n return Math.max(1, Math.ceil(this.count() / fit));\n }\n\n protected pointerAt(position: number, range: readonly [number, number]): void {\n this.active.set(nearestIndex(position, this.count(), range));\n }\n\n protected onKeydown(event: KeyboardEvent, index: number): void {\n const last = this.count() - 1;\n const next =\n {\n ArrowRight: index + 1,\n ArrowDown: index + 1,\n ArrowLeft: index - 1,\n ArrowUp: index - 1,\n Home: 0,\n End: last,\n }[event.key] ?? null;\n if (next === null) return;\n event.preventDefault();\n const target = Math.min(last, Math.max(0, next));\n this.focusIndex.set(target);\n const hits = (event.currentTarget as Element).parentElement;\n (hits?.querySelector(`[data-index=\"${target}\"]`) as SVGElement | null)?.focus();\n }\n\n protected onFocus(index: number): void {\n this.focusIndex.set(index);\n this.active.set(index);\n }\n\n protected onBlur(event: FocusEvent): void {\n const next = event.relatedTarget as Element | null;\n if (!next?.closest('.vd-chart__hits')) this.active.set(-1);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n input,\n} from '@angular/core';\nimport { bands, barPath, extent, stack } from './core/chart-math';\nimport { VdChartBase } from './chart-base';\nimport { VdChartFrame } from './chart-frame';\n\nexport type VdBarOrientation = 'vertical' | 'horizontal';\n\n/** Mark specs (dataviz): bars at most 24px thick, 4px rounded data end, 2px surface gap. */\nconst MAX_THICKNESS = 24;\nconst RADIUS = 4;\nconst GAP = 2;\nconst PAD = 8;\nconst AXIS_BAND = 22;\n\ninterface Mark {\n d: string;\n series: number;\n category: number;\n}\n\n/**\n * Bar / column chart: one series in the accent, several grouped or stacked in the categorical\n * palette. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-bar-chart',\n imports: [VdChartFrame],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n // The `title` input would otherwise also stay as a native tooltip on the host.\n '[attr.title]': 'null',\n class: 'vd-bar-chart',\n '[attr.data-orientation]': 'orientation()',\n },\n template: `\n <vd-chart-frame\n kind=\"bar\"\n [title]=\"title()\"\n [description]=\"description()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [format]=\"format()\"\n [categoryLabel]=\"categoryLabel()\"\n [loading]=\"loading()\"\n [active]=\"active()\"\n [tooltipX]=\"tooltip()?.x ?? null\"\n [tooltipY]=\"tooltip()?.y ?? 0\"\n (pointerLeave)=\"active.set(-1)\"\n >\n @if (width() > 0) {\n <svg\n class=\"vd-chart__svg\"\n [attr.width]=\"width()\"\n [attr.height]=\"height()\"\n [attr.viewBox]=\"'0 0 ' + width() + ' ' + height()\"\n role=\"group\"\n [attr.aria-labelledby]=\"frame().titleId\"\n (pointermove)=\"onPointer($event)\"\n >\n <g class=\"vd-chart__grid\" aria-hidden=\"true\">\n @for (t of tickMarks(); track t.value) {\n <line\n [attr.x1]=\"t.x1\"\n [attr.x2]=\"t.x2\"\n [attr.y1]=\"t.y1\"\n [attr.y2]=\"t.y2\"\n [attr.data-zero]=\"t.value === 0 ? '' : null\"\n />\n <text\n [attr.x]=\"t.tx\"\n [attr.y]=\"t.ty\"\n [attr.text-anchor]=\"t.anchor\"\n dominant-baseline=\"middle\"\n >\n {{ tickText(t.value) }}\n </text>\n }\n </g>\n @if (active() >= 0) {\n <rect\n class=\"vd-chart__band\"\n aria-hidden=\"true\"\n [attr.x]=\"bandRect().x\"\n [attr.y]=\"bandRect().y\"\n [attr.width]=\"bandRect().w\"\n [attr.height]=\"bandRect().h\"\n rx=\"4\"\n />\n }\n <g class=\"vd-chart__marks\" aria-hidden=\"true\">\n @for (m of marks(); track $index) {\n <path\n class=\"vd-chart__bar\"\n [attr.d]=\"m.d\"\n [attr.data-series]=\"slot(m.series)\"\n [attr.data-muted]=\"highlighted() >= 0 && m.category !== highlighted() ? '' : null\"\n />\n }\n </g>\n <g class=\"vd-chart__axis\" aria-hidden=\"true\">\n @for (c of categoryTicks(); track c.index) {\n <text\n [attr.x]=\"c.x\"\n [attr.y]=\"c.y\"\n [attr.text-anchor]=\"c.anchor\"\n dominant-baseline=\"middle\"\n >\n {{ categories()[c.index] }}\n </text>\n }\n </g>\n <g class=\"vd-chart__hits\">\n @for (h of hits(); track h.index) {\n <rect\n class=\"vd-chart__hit\"\n rx=\"6\"\n role=\"img\"\n [attr.data-index]=\"h.index\"\n [attr.tabindex]=\"h.index === focusIndex() ? 0 : -1\"\n [attr.aria-label]=\"pointLabel(h.index)\"\n [attr.x]=\"h.x\"\n [attr.y]=\"h.y\"\n [attr.width]=\"h.w\"\n [attr.height]=\"h.h\"\n (focus)=\"onFocus(h.index)\"\n (blur)=\"onBlur($event)\"\n (keydown)=\"onKeydown($event, h.index)\"\n />\n }\n </g>\n </svg>\n }\n </vd-chart-frame>\n `,\n})\nexport class VdBarChart extends VdChartBase {\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n /** Stack series (part-to-whole) instead of grouping them side by side. */\n readonly stacked = input(false, { transform: booleanAttribute });\n /**\n * Emphasis form for a single series: keep one category in full colour and mute the rest.\n * `'max'` picks the largest value.\n */\n readonly highlight = input<number | 'max' | null>(null);\n\n protected readonly highlighted = computed(() => {\n const h = this.highlight();\n const values = this.series()[0]?.values ?? [];\n if (h === null || this.series().length !== 1) return -1;\n if (h !== 'max') return h;\n let best = -1;\n values.forEach((v, i) => {\n if (v !== null && Number.isFinite(v) && (best < 0 || v > (values[best] ?? -Infinity)))\n best = i;\n });\n return best;\n });\n\n protected readonly stackedValues = () => this.stacked();\n protected extentOf() {\n return extent(this.series(), this.count(), this.stacked());\n }\n\n private readonly vertical = computed(() => this.orientation() === 'vertical');\n\n /** Plot box inside the SVG: [start, end] on each axis. */\n protected readonly box = computed(() => {\n const w = this.width();\n const h = this.height();\n if (this.vertical()) {\n return { x0: this.tickWidth(), x1: w - PAD, y0: PAD, y1: h - AXIS_BAND };\n }\n const labels = Math.min(this.categoryWidth(), w * 0.4);\n return { x0: labels, x1: w - PAD - this.tickWidth() / 2, y0: PAD, y1: h - AXIS_BAND };\n });\n\n private readonly scale = computed(() => {\n const b = this.box();\n return this.vertical() ? this.valueScale([b.y1, b.y0]) : this.valueScale([b.x0, b.x1]);\n });\n\n private readonly categoryRange = computed<[number, number]>(() => {\n const b = this.box();\n return this.vertical() ? [b.x0, b.x1] : [b.y0, b.y1];\n });\n\n private readonly bandList = computed(() => bands(this.count(), this.categoryRange()));\n\n protected readonly marks = computed<Mark[]>(() => {\n const series = this.series();\n const n = series.length;\n if (!n || !this.count()) return [];\n const scale = this.scale();\n const zero = scale(0);\n const orient = this.orientation();\n const marks: Mark[] = [];\n if (this.stacked()) {\n const segments = stack(series, this.count());\n // Rounded only on the outermost segment of each direction.\n const outer = this.bandList().map((_, c) => {\n let top = -1;\n let bottom = -1;\n segments.forEach((s, i) => {\n if (s[c].to > s[c].from) top = i;\n if (s[c].to < s[c].from) bottom = i;\n });\n return { top, bottom };\n });\n this.bandList().forEach((band, c) => {\n const thickness = Math.min(MAX_THICKNESS, band.step * 0.6);\n segments.forEach((s, i) => {\n const seg = s[c];\n if (seg.to === seg.from) return;\n const rounded = i === outer[c].top || i === outer[c].bottom;\n const from = scale(seg.from);\n const to = scale(seg.to);\n // 2px surface gap between stacked segments, taken from the far end.\n const dir = Math.sign(to - from);\n const end = rounded ? to : to - dir * GAP;\n marks.push({\n d: barPath(band.center, thickness, from, end, rounded ? RADIUS : 0, orient),\n series: i,\n category: c,\n });\n });\n });\n return marks;\n }\n this.bandList().forEach((band, c) => {\n const thickness = Math.min(MAX_THICKNESS, (band.step * 0.7 - GAP * (n - 1)) / n);\n const group = thickness * n + GAP * (n - 1);\n series.forEach((s, i) => {\n const v = s.values[c];\n if (v === null || v === undefined || !Number.isFinite(v)) return;\n const center = band.center - group / 2 + thickness / 2 + i * (thickness + GAP);\n marks.push({\n d: barPath(center, thickness, zero, scale(v), RADIUS, orient),\n series: i,\n category: c,\n });\n });\n });\n return marks;\n });\n\n protected readonly tickMarks = computed(() => {\n const b = this.box();\n const scale = this.scale();\n return this.ticks().map((value) =>\n this.vertical()\n ? {\n value,\n x1: b.x0,\n x2: b.x1,\n y1: scale(value),\n y2: scale(value),\n tx: b.x0 - 6,\n ty: scale(value),\n anchor: 'end',\n }\n : {\n value,\n x1: scale(value),\n x2: scale(value),\n y1: b.y0,\n y2: b.y1,\n tx: scale(value),\n ty: b.y1 + AXIS_BAND / 2 + 2,\n anchor: 'middle',\n },\n );\n });\n\n protected readonly categoryTicks = computed(() => {\n const b = this.box();\n const list = this.bandList();\n if (this.vertical()) {\n const every = this.labelEvery(b.x1 - b.x0);\n return list\n .map((band, index) => ({\n index,\n x: band.center,\n y: b.y1 + AXIS_BAND / 2 + 2,\n anchor: 'middle',\n }))\n .filter((c) => c.index % every === 0);\n }\n return list.map((band, index) => ({ index, x: b.x0 - 8, y: band.center, anchor: 'end' }));\n });\n\n /** Hit targets cover the whole band, bigger than the marks. */\n protected readonly hits = computed(() => {\n const b = this.box();\n return this.bandList().map((band, index) =>\n this.vertical()\n ? { index, x: band.start, y: b.y0, w: band.step, h: b.y1 - b.y0 }\n : { index, x: b.x0, y: band.start, w: b.x1 - b.x0, h: band.step },\n );\n });\n\n protected readonly bandRect = computed(() => {\n const hit = this.hits()[this.active()];\n if (!hit) return { x: 0, y: 0, w: 0, h: 0 };\n const inset = 2;\n return {\n x: hit.x + inset,\n y: hit.y + inset,\n w: Math.max(0, hit.w - inset * 2),\n h: Math.max(0, hit.h - inset * 2),\n };\n });\n\n protected readonly tooltip = computed(() => {\n const i = this.active();\n const band = this.bandList()[i];\n if (!band) return null;\n const b = this.box();\n return this.vertical()\n ? { x: band.center, y: b.y0 }\n : { x: b.x0 + (b.x1 - b.x0) / 2, y: band.center };\n });\n\n protected onPointer(event: PointerEvent): void {\n const svg = event.currentTarget as SVGSVGElement;\n const rect = svg.getBoundingClientRect();\n const pos = this.vertical() ? event.clientX - rect.left : event.clientY - rect.top;\n this.pointerAt(pos, this.categoryRange());\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n input,\n} from '@angular/core';\nimport { areaPath, extent, linePath, type VdPoint } from './core/chart-math';\nimport { VdChartBase } from './chart-base';\nimport { VdChartFrame } from './chart-frame';\n\nconst PAD = 12;\nconst AXIS_BAND = 22;\n/** Direct end labels only while they stay sparing (dataviz: <= 4 series). */\nconst MAX_END_LABELS = 4;\nconst END_LABEL_GAP = 14;\n\n/**\n * Line chart for trends over ordered categories. One series gets a soft area wash; several use\n * the categorical palette with a legend and direct end labels. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-line-chart',\n imports: [VdChartFrame],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n // The `title` input would otherwise also stay as a native tooltip on the host.\n '[attr.title]': 'null',\n class: 'vd-line-chart',\n },\n template: `\n <vd-chart-frame\n kind=\"line\"\n [title]=\"title()\"\n [description]=\"description()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [format]=\"format()\"\n [categoryLabel]=\"categoryLabel()\"\n [loading]=\"loading()\"\n [active]=\"active()\"\n [tooltipX]=\"tooltip()?.x ?? null\"\n [tooltipY]=\"tooltip()?.y ?? 0\"\n (pointerLeave)=\"active.set(-1)\"\n >\n @if (width() > 0) {\n <svg\n class=\"vd-chart__svg\"\n [attr.width]=\"width()\"\n [attr.height]=\"height()\"\n [attr.viewBox]=\"'0 0 ' + width() + ' ' + height()\"\n role=\"group\"\n [attr.aria-labelledby]=\"frame().titleId\"\n (pointermove)=\"onPointer($event)\"\n >\n <g class=\"vd-chart__grid\" aria-hidden=\"true\">\n @for (t of tickMarks(); track t.value) {\n <line\n [attr.x1]=\"box().x0\"\n [attr.x2]=\"box().x1\"\n [attr.y1]=\"t.y\"\n [attr.y2]=\"t.y\"\n [attr.data-zero]=\"t.value === 0 ? '' : null\"\n />\n <text\n [attr.x]=\"box().x0 - 6\"\n [attr.y]=\"t.y\"\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {{ tickText(t.value) }}\n </text>\n }\n </g>\n <g class=\"vd-chart__marks\" aria-hidden=\"true\">\n @if (showArea()) {\n <path class=\"vd-chart__area\" [attr.d]=\"areaD()\" [attr.data-series]=\"slot(0)\" />\n }\n @for (l of lines(); track $index) {\n <path class=\"vd-chart__line\" [attr.d]=\"l\" [attr.data-series]=\"slot($index)\" />\n }\n @if (active() >= 0) {\n <line\n class=\"vd-chart__crosshair\"\n [attr.x1]=\"xs()[active()]\"\n [attr.x2]=\"xs()[active()]\"\n [attr.y1]=\"box().y0\"\n [attr.y2]=\"box().y1\"\n />\n }\n @for (d of dots(); track $index) {\n <circle\n class=\"vd-chart__dot\"\n [attr.cx]=\"d.x\"\n [attr.cy]=\"d.y\"\n r=\"4\"\n [attr.data-series]=\"slot(d.series)\"\n />\n }\n </g>\n <g class=\"vd-chart__end-labels\" aria-hidden=\"true\">\n @for (e of endLabels(); track e.series) {\n <text [attr.x]=\"e.x\" [attr.y]=\"e.y\" dominant-baseline=\"middle\">\n {{ series()[e.series].name }}\n </text>\n }\n </g>\n <g class=\"vd-chart__axis\" aria-hidden=\"true\">\n @for (c of categoryTicks(); track c.index) {\n <text\n [attr.x]=\"c.x\"\n [attr.y]=\"box().y1 + 13\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n >\n {{ categories()[c.index] }}\n </text>\n }\n </g>\n <g class=\"vd-chart__hits\">\n @for (x of xs(); track $index; let i = $index) {\n <rect\n class=\"vd-chart__hit\"\n rx=\"6\"\n role=\"img\"\n [attr.data-index]=\"i\"\n [attr.tabindex]=\"i === focusIndex() ? 0 : -1\"\n [attr.aria-label]=\"pointLabel(i)\"\n [attr.x]=\"x - step() / 2\"\n [attr.y]=\"box().y0\"\n [attr.width]=\"step()\"\n [attr.height]=\"box().y1 - box().y0\"\n (focus)=\"onFocus(i)\"\n (blur)=\"onBlur($event)\"\n (keydown)=\"onKeydown($event, i)\"\n />\n }\n </g>\n </svg>\n }\n </vd-chart-frame>\n `,\n})\nexport class VdLineChart extends VdChartBase {\n /** Soft area under a single series; ignored with several series. */\n readonly area = input(true, { transform: booleanAttribute });\n\n protected readonly stackedValues = () => false;\n protected extentOf() {\n return extent(this.series(), this.count(), false);\n }\n\n protected readonly showArea = computed(() => this.area() && this.series().length === 1);\n private readonly labelled = computed(\n () => this.series().length > 1 && this.series().length <= MAX_END_LABELS,\n );\n\n protected readonly box = computed(() => {\n const longest = Math.max(...this.series().map((s) => s.name.length), 0);\n const end = this.labelled() ? Math.min(longest * 6.8 + END_LABEL_GAP, this.width() * 0.3) : PAD;\n return { x0: this.tickWidth(), x1: this.width() - end, y0: PAD, y1: this.height() - AXIS_BAND };\n });\n\n private readonly scale = computed(() => this.valueScale([this.box().y1, this.box().y0]));\n\n /** Point positions: first and last categories sit on the plot edges. */\n protected readonly xs = computed(() => {\n const { x0, x1 } = this.box();\n const n = this.count();\n if (n <= 1) return [(x0 + x1) / 2];\n return Array.from({ length: n }, (_, i) => x0 + (i * (x1 - x0)) / (n - 1));\n });\n protected readonly step = computed(() => {\n const xs = this.xs();\n return xs.length > 1 ? xs[1] - xs[0] : this.box().x1 - this.box().x0;\n });\n\n private readonly points = computed(() =>\n this.series().map((s) =>\n this.xs().map((x, i): VdPoint => {\n const v = s.values[i];\n return v === null || v === undefined || !Number.isFinite(v) ? null : [x, this.scale()(v)];\n }),\n ),\n );\n\n protected readonly lines = computed(() => this.points().map((p) => linePath(p)));\n protected readonly areaD = computed(() => areaPath(this.points()[0] ?? [], this.scale()(0)));\n\n protected readonly tickMarks = computed(() =>\n this.ticks().map((value) => ({ value, y: this.scale()(value) })),\n );\n\n protected readonly categoryTicks = computed(() => {\n const every = this.labelEvery(this.box().x1 - this.box().x0);\n return this.xs()\n .map((x, index) => ({ index, x }))\n .filter((c) => c.index % every === 0 || c.index === this.count() - 1)\n .filter((c, i, all) => i === all.length - 1 || all[all.length - 1].index - c.index >= every);\n });\n\n /** Active point of every series, else the last point (current period). */\n protected readonly dots = computed(() => {\n const at = this.active() >= 0 ? this.active() : this.count() - 1;\n return this.points().flatMap((p, series) => {\n const point = p[at];\n return point ? [{ x: point[0], y: point[1], series }] : [];\n });\n });\n\n /** Names at line ends; labels that would collide fall back to the legend. */\n protected readonly endLabels = computed(() => {\n if (!this.labelled()) return [];\n const x = this.box().x1 + 8;\n const placed: { series: number; x: number; y: number }[] = [];\n this.points()\n .map((p, series) => ({ series, y: [...p].reverse().find((q) => q)?.[1] }))\n .filter((e): e is { series: number; y: number } => e.y !== undefined)\n .sort((a, b) => a.y - b.y)\n .forEach((e) => {\n if (placed.every((p) => Math.abs(p.y - e.y) >= 14)) placed.push({ ...e, x });\n });\n return placed;\n });\n\n protected readonly tooltip = computed(() => {\n const x = this.xs()[this.active()];\n return x === undefined ? null : { x, y: this.box().y0 };\n });\n\n protected onPointer(event: PointerEvent): void {\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const { x0, x1 } = this.box();\n const half = this.step() / 2;\n this.pointerAt(event.clientX - rect.left, [x0 - half, x1 + half]);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { VD_LOCALE, vdTexts } from '@vadem/ui/locale';\nimport { areaPath, linePath, linearScale, type VdPoint } from './core/chart-math';\nimport type { VdChartFormat } from './chart-frame';\n\n/** Fixed drawing box; the SVG scales to its container without distorting strokes. */\nconst W = 120;\nconst H = 32;\nconst INSET = 4;\n\n/**\n * Word-sized trend: line in the de-emphasis ink, current (last) point in the accent.\n * A single image with a spoken summary. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-sparkline',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'vd-sparkline' },\n template: `\n <svg\n class=\"vd-sparkline__svg\"\n [attr.viewBox]=\"'0 0 ' + W + ' ' + H\"\n preserveAspectRatio=\"none\"\n role=\"img\"\n [attr.aria-label]=\"summary()\"\n >\n <path class=\"vd-sparkline__area\" [attr.d]=\"area()\" />\n <path class=\"vd-sparkline__line\" [attr.d]=\"line()\" vector-effect=\"non-scaling-stroke\" />\n </svg>\n @if (last(); as p) {\n <span\n class=\"vd-sparkline__dot\"\n aria-hidden=\"true\"\n [style.--vd-sparkline-x.%]=\"(p[0] / W) * 100\"\n [style.--vd-sparkline-y.%]=\"(p[1] / H) * 100\"\n ></span>\n }\n `,\n})\nexport class VdSparkline {\n readonly values = input<readonly (number | null)[]>([]);\n /** What the trend shows, e.g. \"Дохід за 12 тижнів\". */\n readonly label = input.required<string>();\n readonly format = input<VdChartFormat>();\n readonly trendSummary =\n input<(first: string, last: string, min: string, max: string) => string>();\n\n protected readonly W = W;\n protected readonly H = H;\n protected readonly t = vdTexts('chart', { trendSummary: this.trendSummary });\n private readonly locale = inject(VD_LOCALE);\n\n private readonly numbers = computed(() =>\n this.values().filter((v): v is number => v !== null && Number.isFinite(v)),\n );\n\n private readonly points = computed<VdPoint[]>(() => {\n const values = this.values();\n const nums = this.numbers();\n if (!nums.length) return [];\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const y = linearScale(min === max ? [min - 1, max + 1] : [min, max], [H - INSET, INSET]);\n const n = values.length;\n return values.map((v, i) =>\n v === null || !Number.isFinite(v) ? null : [n > 1 ? (i * W) / (n - 1) : W / 2, y(v)],\n );\n });\n\n protected readonly line = computed(() => linePath(this.points()));\n protected readonly area = computed(() => areaPath(this.points(), H));\n protected readonly last = computed(() => [...this.points()].reverse().find((p) => p) ?? null);\n\n protected readonly summary = computed(() => {\n const nums = this.numbers();\n if (!nums.length) return this.label();\n const fmt = this.format() ?? ((v: number) => new Intl.NumberFormat(this.locale.code).format(v));\n const text = this.t().trendSummary(\n fmt(nums[0]),\n fmt(nums[nums.length - 1]),\n fmt(Math.min(...nums)),\n fmt(Math.max(...nums)),\n );\n return `${this.label()}: ${text}`;\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vadem-ui-chart.mjs","names":[],"sources":["../../../projects/ui/chart/src/core/chart-math.ts","../../../projects/ui/chart/src/chart-frame.ts","../../../projects/ui/chart/src/chart-base.ts","../../../projects/ui/chart/src/bar-chart.ts","../../../projects/ui/chart/src/line-chart.ts","../../../projects/ui/chart/src/sparkline.ts"],"sourcesContent":["/**\n * Framework-agnostic chart geometry: scales, ticks, stacking and SVG paths.\n * No DOM access; every function is pure and unit-tested.\n */\n\nexport interface VdChartSeries {\n name: string;\n /** One value per category; `null` = missing (a gap, never zero). */\n values: readonly (number | null)[];\n}\n\nexport interface VdLinearScale {\n domain: readonly [number, number];\n range: readonly [number, number];\n (value: number): number;\n}\n\nexport function vdLinearScale(\n domain: readonly [number, number],\n range: readonly [number, number],\n): VdLinearScale {\n const [d0, d1] = domain;\n const [r0, r1] = range;\n const span = d1 - d0 || 1;\n const scale = ((value: number) => r0 + ((value - d0) / span) * (r1 - r0)) as VdLinearScale;\n return Object.assign(scale, { domain, range });\n}\n\n/** Round numbers for an axis: 1, 2, 2.5 or 5 times a power of ten. Always includes zero. */\nexport function vdNiceTicks(min: number, max: number, target = 5): number[] {\n const lo = Math.min(0, min);\n const hi = Math.max(0, max);\n if (lo === hi) return [0, 1];\n const raw = (hi - lo) / Math.max(1, target);\n const power = 10 ** Math.floor(Math.log10(raw));\n const step = [1, 2, 2.5, 5, 10].map((m) => m * power).find((s) => s >= raw) ?? 10 * power;\n const start = Math.floor(lo / step) * step;\n const end = Math.ceil(hi / step) * step;\n const ticks: number[] = [];\n for (let v = start; v <= end + step / 2; v += step) ticks.push(Number(v.toFixed(10)));\n return ticks;\n}\n\nexport interface VdBand {\n /** Start of each band. */\n start: number;\n /** Centre of each band. */\n center: number;\n /** Band width including its share of padding. */\n step: number;\n}\n\n/** Evenly spaced bands across `range` for `count` categories. */\nexport function vdBands(count: number, range: readonly [number, number]): VdBand[] {\n const [r0, r1] = range;\n const step = count > 0 ? (r1 - r0) / count : 0;\n return Array.from({ length: count }, (_, i) => ({\n start: r0 + i * step,\n center: r0 + (i + 0.5) * step,\n step,\n }));\n}\n\n/** Index of the band nearest to `position` (pointer or keyboard), clamped. */\nexport function vdNearestIndex(position: number, count: number, range: readonly [number, number]) {\n if (count <= 0) return -1;\n const [r0, r1] = range;\n const t = (position - r0) / (r1 - r0 || 1);\n return Math.min(count - 1, Math.max(0, Math.floor(t * count)));\n}\n\nexport interface VdStackSegment {\n from: number;\n to: number;\n}\n\n/** Stacks positive values upward and negative values downward from zero, per category. */\nexport function vdStack(series: readonly VdChartSeries[], count: number): VdStackSegment[][] {\n const up = new Array<number>(count).fill(0);\n const down = new Array<number>(count).fill(0);\n return series.map((s) =>\n Array.from({ length: count }, (_, i) => {\n const v = s.values[i] ?? 0;\n if (v >= 0) {\n const seg = { from: up[i], to: up[i] + v };\n up[i] += v;\n return seg;\n }\n const seg = { from: down[i], to: down[i] + v };\n down[i] += v;\n return seg;\n }),\n );\n}\n\n/** [min, max] over all values (stacked totals when `stacked`). */\nexport function vdExtent(series: readonly VdChartSeries[], count: number, stacked: boolean) {\n let min = 0;\n let max = 0;\n if (stacked) {\n for (const segments of vdStack(series, count))\n for (const seg of segments) {\n min = Math.min(min, seg.to);\n max = Math.max(max, seg.to);\n }\n } else {\n for (const s of series)\n for (const v of s.values) {\n if (v === null || !Number.isFinite(v)) continue;\n min = Math.min(min, v);\n max = Math.max(max, v);\n }\n }\n return [min, max] as const;\n}\n\nconst r = (n: number) => Math.round(n * 100) / 100;\n\n/**\n * A bar from `base` to `end` along the value axis, `thickness` wide, centred at `center` on the\n * category axis. The data end is rounded (`radius`), the baseline end square.\n */\nexport function vdBarPath(\n center: number,\n thickness: number,\n base: number,\n end: number,\n radius: number,\n orientation: 'vertical' | 'horizontal',\n): string {\n const length = Math.abs(end - base);\n if (length < 0.5) return '';\n const rad = Math.min(radius, thickness / 2, length);\n const a = center - thickness / 2;\n const b = center + thickness / 2;\n const dir = end < base ? -1 : 1;\n const tip = end - dir * rad;\n if (orientation === 'vertical') {\n // Value axis is y; `dir` -1 means the bar grows upward on screen.\n return [\n `M${r(a)},${r(base)}`,\n `L${r(a)},${r(tip)}`,\n `Q${r(a)},${r(end)} ${r(a + rad)},${r(end)}`,\n `L${r(b - rad)},${r(end)}`,\n `Q${r(b)},${r(end)} ${r(b)},${r(tip)}`,\n `L${r(b)},${r(base)}`,\n 'Z',\n ].join(' ');\n }\n return [\n `M${r(base)},${r(a)}`,\n `L${r(tip)},${r(a)}`,\n `Q${r(end)},${r(a)} ${r(end)},${r(a + rad)}`,\n `L${r(end)},${r(b - rad)}`,\n `Q${r(end)},${r(b)} ${r(tip)},${r(b)}`,\n `L${r(base)},${r(b)}`,\n 'Z',\n ].join(' ');\n}\n\nexport type VdPoint = readonly [x: number, y: number] | null;\n\n/** Polyline through points; a `null` starts a new segment (missing data is a gap). */\nexport function vdLinePath(points: readonly VdPoint[]): string {\n let d = '';\n let pen = false;\n for (const p of points) {\n if (!p) {\n pen = false;\n continue;\n }\n d += `${pen ? 'L' : 'M'}${r(p[0])},${r(p[1])}`;\n pen = true;\n }\n return d;\n}\n\n/** Closed area between each continuous run of points and the baseline. */\nexport function vdAreaPath(points: readonly VdPoint[], baseline: number): string {\n const runs: (readonly [number, number])[][] = [[]];\n for (const p of points) {\n if (p) runs[runs.length - 1].push(p);\n else if (runs[runs.length - 1].length) runs.push([]);\n }\n return runs\n .filter((run) => run.length > 1)\n .map(\n (run) =>\n `M${r(run[0][0])},${r(baseline)}` +\n run.map(([x, y]) => `L${r(x)},${r(y)}`).join('') +\n `L${r(run[run.length - 1][0])},${r(baseline)}Z`,\n )\n .join('');\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { VdButton } from '@vadem/ui/button';\nimport { vdUniqueId } from '@vadem/ui/field';\nimport { VD_LOCALE, vdTexts } from '@vadem/ui/locale';\nimport type { VdChartSeries } from './core/chart-math';\n\nexport type VdChartKind = 'bar' | 'line';\n\n/** Formats a value for tooltips and the table (full precision, locale-aware). */\nexport type VdChartFormat = (value: number) => string;\n\n/** Series identity: slot 1..8 for categorical, \"accent\" for a single series. */\nexport function seriesSlot(index: number, count: number): string {\n return count === 1 ? 'accent' : String((index % 8) + 1);\n}\n\n/**\n * Shared chart chrome: figure with title, legend (2+ series), data-table toggle, tooltip and\n * plot measurement. Charts project their SVG into it. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-chart-frame',\n imports: [VdButton],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'vd-chart' },\n template: `\n <figure\n class=\"vd-chart__figure\"\n [attr.aria-labelledby]=\"titleId\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-loading]=\"loading() ? '' : null\"\n >\n <figcaption class=\"vd-chart__head\">\n <span class=\"vd-chart__title\" [id]=\"titleId\">{{ title() }}</span>\n @if (description()) {\n <span class=\"vd-chart__description\">{{ description() }}</span>\n }\n </figcaption>\n <div class=\"vd-chart__toolbar\">\n @if (series().length > 1) {\n <ul class=\"vd-chart__legend\" role=\"list\">\n @for (s of series(); track $index) {\n <li class=\"vd-chart__legend-item\">\n <span\n class=\"vd-chart__key\"\n aria-hidden=\"true\"\n [attr.data-series]=\"slot($index)\"\n [attr.data-kind]=\"kind()\"\n ></span>\n {{ s.name }}\n </li>\n }\n </ul>\n }\n <button\n vdButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n class=\"vd-chart__table-toggle\"\n [attr.aria-pressed]=\"tableShown()\"\n [attr.aria-controls]=\"tableId\"\n (click)=\"tableShown.set(!tableShown())\"\n >\n {{ t().tableLabel }}\n </button>\n </div>\n\n <div #plot class=\"vd-chart__plot\" [hidden]=\"tableShown()\" (pointerleave)=\"leave()\">\n <ng-content />\n @if (active() >= 0 && tooltipX() !== null) {\n <div\n class=\"vd-chart__tooltip\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [attr.data-side]=\"tooltipSide()\"\n [style.--vd-chart-tip-x.px]=\"tooltipX()\"\n [style.--vd-chart-tip-y.px]=\"tooltipY()\"\n >\n <span class=\"vd-chart__tooltip-category\" dir=\"auto\">{{ categories()[active()] }}</span>\n @for (s of series(); track $index) {\n <span class=\"vd-chart__tooltip-row\">\n <span\n class=\"vd-chart__key\"\n [attr.data-series]=\"slot($index)\"\n data-kind=\"line\"\n ></span>\n <strong class=\"vd-chart__tooltip-value\">{{ valueText(s.values[active()]) }}</strong>\n <span class=\"vd-chart__tooltip-name\" dir=\"auto\">{{ s.name }}</span>\n </span>\n }\n </div>\n }\n </div>\n\n <div\n class=\"vd-chart__table-wrap\"\n role=\"region\"\n tabindex=\"0\"\n [id]=\"tableId\"\n [attr.aria-labelledby]=\"titleId\"\n [hidden]=\"!tableShown()\"\n >\n @if (tableShown()) {\n <table class=\"vd-chart__table\">\n <thead>\n <tr>\n <th scope=\"col\">{{ t().categoryLabel }}</th>\n @for (s of series(); track $index) {\n <th scope=\"col\">{{ s.name }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (c of categories(); track $index; let i = $index) {\n <tr>\n <th scope=\"row\">{{ c }}</th>\n @for (s of series(); track $index) {\n <td>{{ valueText(s.values[i]) }}</td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </figure>\n `,\n})\nexport class VdChartFrame {\n readonly title = input.required<string>();\n readonly description = input<string>();\n readonly categories = input<readonly string[]>([]);\n readonly series = input<readonly VdChartSeries[]>([]);\n readonly kind = input<VdChartKind>('bar');\n readonly format = input<VdChartFormat>();\n readonly categoryLabel = input<string>();\n /** Highlighted category, driven by the chart (pointer or keyboard). */\n readonly active = input(-1);\n /** Tooltip anchor in plot pixels; null hides it. */\n readonly tooltipX = input<number | null>(null);\n readonly tooltipY = input(0);\n readonly tableLabel = input<string>();\n readonly loading = input(false);\n\n protected readonly t = vdTexts('chart', {\n tableLabel: this.tableLabel,\n categoryLabel: this.categoryLabel,\n });\n private readonly locale = inject(VD_LOCALE);\n readonly titleId = vdUniqueId('vd-chart-title');\n readonly tableId = vdUniqueId('vd-chart-table');\n readonly tableShown = signal(false);\n /** Measured plot width in CSS pixels (0 until the browser lays it out). */\n readonly width = signal(0);\n /** Fired when the pointer leaves the plot; charts clear their highlight. */\n readonly pointerLeave = output<void>();\n\n private readonly plot = viewChild.required<ElementRef<HTMLElement>>('plot');\n private readonly numberFormat = computed(() => new Intl.NumberFormat(this.locale.code));\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n afterNextRender(() => {\n const el = this.plot().nativeElement;\n const view = el.ownerDocument.defaultView;\n const measure = () => this.width.set(el.clientWidth);\n measure();\n if (!view?.ResizeObserver) return;\n const observer = new view.ResizeObserver(measure);\n observer.observe(el);\n destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n protected slot(index: number): string {\n return seriesSlot(index, this.series().length);\n }\n\n valueText(value: number | null | undefined): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '—';\n return (this.format() ?? ((v: number) => this.numberFormat().format(v)))(value);\n }\n\n protected leave(): void {\n this.pointerLeave.emit();\n }\n\n /** The tooltip sits on the roomier side of its anchor. */\n protected readonly tooltipSide = computed(() =>\n (this.tooltipX() ?? 0) > this.width() / 2 ? 'start' : 'end',\n );\n}\n","import {\n Directive,\n booleanAttribute,\n computed,\n inject,\n input,\n numberAttribute,\n signal,\n viewChild,\n} from '@angular/core';\nimport { VD_LOCALE } from '@vadem/ui/locale';\nimport { vdLinearScale, vdNiceTicks, vdNearestIndex, type VdChartSeries } from './core/chart-math';\nimport { VdChartFrame, type VdChartFormat, seriesSlot } from './chart-frame';\n\n/** Average glyph width of 12px UI text, used to reserve room for axis labels. */\nconst CHAR_PX = 6.8;\nconst AXIS_FONT_GAP = 8;\n\n/**\n * Inputs, value scale and keyboard/pointer exploration shared by bar and line charts.\n * Rendering stays in each chart's template.\n */\n@Directive()\nexport abstract class VdChartBase {\n readonly title = input.required<string>();\n readonly description = input<string>();\n /** Category labels (x for columns and lines, y for horizontal bars). */\n readonly categories = input<readonly string[]>([]);\n readonly series = input<readonly VdChartSeries[]>([]);\n /** Plot height in pixels, including the category axis band. */\n readonly height = input(240, { transform: numberAttribute });\n /** Full value text for tooltips, labels and the table. Defaults to Intl in the locale. */\n readonly format = input<VdChartFormat>();\n /** Short value text for axis ticks. Defaults to compact Intl notation. */\n readonly axisFormat = input<VdChartFormat>();\n readonly categoryLabel = input<string>();\n /**\n * Refetching: keep the previous render, muted and `aria-busy`, so the table view, focus and\n * layout survive (dataviz: refetch keeps the frame, no skeleton).\n */\n readonly loading = input(false, { transform: booleanAttribute });\n\n protected readonly frame = viewChild.required(VdChartFrame);\n /** Highlighted category (pointer or keyboard), -1 when none. */\n protected readonly active = signal(-1);\n /** Roving tab stop among category hit targets. */\n protected readonly focusIndex = signal(0);\n\n protected readonly count = computed(() => this.categories().length);\n protected readonly width = computed(() => this.frame().width());\n\n protected abstract readonly stackedValues: () => boolean;\n protected abstract extentOf(): readonly [number, number];\n\n protected readonly ticks = computed(() => {\n const [min, max] = this.extentOf();\n return vdNiceTicks(min, max, Math.max(2, Math.round(this.height() / 60)));\n });\n\n private readonly compact = computed(\n () =>\n new Intl.NumberFormat(this.localeCode(), { notation: 'compact', maximumFractionDigits: 1 }),\n );\n private readonly locale = inject(VD_LOCALE);\n protected localeCode(): string {\n return this.locale.code;\n }\n\n protected tickText(value: number): string {\n return (this.axisFormat() ?? ((v: number) => this.compact().format(v)))(value);\n }\n\n /** Room for the widest tick label. */\n protected readonly tickWidth = computed(\n () =>\n Math.max(...this.ticks().map((t) => this.tickText(t).length), 1) * CHAR_PX + AXIS_FONT_GAP,\n );\n protected readonly categoryWidth = computed(\n () => Math.max(...this.categories().map((c) => c.length), 1) * CHAR_PX + AXIS_FONT_GAP,\n );\n\n protected valueScale(range: readonly [number, number]) {\n const ticks = this.ticks();\n return vdLinearScale([ticks[0], ticks[ticks.length - 1]], range);\n }\n\n protected slot(index: number): string {\n return seriesSlot(index, this.series().length);\n }\n\n /** \"Пн: Запити 4 200, Помилки 12\" - the accessible name of one category. */\n protected pointLabel(index: number): string {\n const values = this.series()\n .map((s) => `${s.name} ${this.frame().valueText(s.values[index])}`)\n .join(', ');\n return `${this.categories()[index]}: ${values}`;\n }\n\n /** Every `k`-th category label so labels never overlap. */\n protected labelEvery(available: number): number {\n const per = this.categoryWidth();\n const fit = Math.max(1, Math.floor(available / per));\n return Math.max(1, Math.ceil(this.count() / fit));\n }\n\n protected pointerAt(position: number, range: readonly [number, number]): void {\n this.active.set(vdNearestIndex(position, this.count(), range));\n }\n\n protected onKeydown(event: KeyboardEvent, index: number): void {\n const last = this.count() - 1;\n const next =\n {\n ArrowRight: index + 1,\n ArrowDown: index + 1,\n ArrowLeft: index - 1,\n ArrowUp: index - 1,\n Home: 0,\n End: last,\n }[event.key] ?? null;\n if (next === null) return;\n event.preventDefault();\n const target = Math.min(last, Math.max(0, next));\n this.focusIndex.set(target);\n const hits = (event.currentTarget as Element).parentElement;\n (hits?.querySelector(`[data-index=\"${target}\"]`) as SVGElement | null)?.focus();\n }\n\n protected onFocus(index: number): void {\n this.focusIndex.set(index);\n this.active.set(index);\n }\n\n protected onBlur(event: FocusEvent): void {\n const next = event.relatedTarget as Element | null;\n if (!next?.closest('.vd-chart__hits')) this.active.set(-1);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n input,\n} from '@angular/core';\nimport { vdBands, vdBarPath, vdExtent, vdStack } from './core/chart-math';\nimport { VdChartBase } from './chart-base';\nimport { VdChartFrame } from './chart-frame';\n\nexport type VdBarOrientation = 'vertical' | 'horizontal';\n\n/** Mark specs (dataviz): bars at most 24px thick, 4px rounded data end, 2px surface gap. */\nconst MAX_THICKNESS = 24;\nconst RADIUS = 4;\nconst GAP = 2;\nconst PAD = 8;\nconst AXIS_BAND = 22;\n\ninterface Mark {\n d: string;\n series: number;\n category: number;\n}\n\n/**\n * Bar / column chart: one series in the accent, several grouped or stacked in the categorical\n * palette. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-bar-chart',\n imports: [VdChartFrame],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n // The `title` input would otherwise also stay as a native tooltip on the host.\n '[attr.title]': 'null',\n class: 'vd-bar-chart',\n '[attr.data-orientation]': 'orientation()',\n },\n template: `\n <vd-chart-frame\n kind=\"bar\"\n [title]=\"title()\"\n [description]=\"description()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [format]=\"format()\"\n [categoryLabel]=\"categoryLabel()\"\n [loading]=\"loading()\"\n [active]=\"active()\"\n [tooltipX]=\"tooltip()?.x ?? null\"\n [tooltipY]=\"tooltip()?.y ?? 0\"\n (pointerLeave)=\"active.set(-1)\"\n >\n @if (width() > 0) {\n <svg\n class=\"vd-chart__svg\"\n [attr.width]=\"width()\"\n [attr.height]=\"height()\"\n [attr.viewBox]=\"'0 0 ' + width() + ' ' + height()\"\n role=\"group\"\n [attr.aria-labelledby]=\"frame().titleId\"\n (pointermove)=\"onPointer($event)\"\n >\n <g class=\"vd-chart__grid\" aria-hidden=\"true\">\n @for (t of tickMarks(); track t.value) {\n <line\n [attr.x1]=\"t.x1\"\n [attr.x2]=\"t.x2\"\n [attr.y1]=\"t.y1\"\n [attr.y2]=\"t.y2\"\n [attr.data-zero]=\"t.value === 0 ? '' : null\"\n />\n <text\n [attr.x]=\"t.tx\"\n [attr.y]=\"t.ty\"\n [attr.text-anchor]=\"t.anchor\"\n dominant-baseline=\"middle\"\n >\n {{ tickText(t.value) }}\n </text>\n }\n </g>\n @if (active() >= 0) {\n <rect\n class=\"vd-chart__band\"\n aria-hidden=\"true\"\n [attr.x]=\"bandRect().x\"\n [attr.y]=\"bandRect().y\"\n [attr.width]=\"bandRect().w\"\n [attr.height]=\"bandRect().h\"\n rx=\"4\"\n />\n }\n <g class=\"vd-chart__marks\" aria-hidden=\"true\">\n @for (m of marks(); track $index) {\n <path\n class=\"vd-chart__bar\"\n [attr.d]=\"m.d\"\n [attr.data-series]=\"slot(m.series)\"\n [attr.data-muted]=\"highlighted() >= 0 && m.category !== highlighted() ? '' : null\"\n />\n }\n </g>\n <g class=\"vd-chart__axis\" aria-hidden=\"true\">\n @for (c of categoryTicks(); track c.index) {\n <text\n [attr.x]=\"c.x\"\n [attr.y]=\"c.y\"\n [attr.text-anchor]=\"c.anchor\"\n dominant-baseline=\"middle\"\n >\n {{ categories()[c.index] }}\n </text>\n }\n </g>\n <g class=\"vd-chart__hits\">\n @for (h of hits(); track h.index) {\n <rect\n class=\"vd-chart__hit\"\n rx=\"6\"\n role=\"img\"\n [attr.data-index]=\"h.index\"\n [attr.tabindex]=\"h.index === focusIndex() ? 0 : -1\"\n [attr.aria-label]=\"pointLabel(h.index)\"\n [attr.x]=\"h.x\"\n [attr.y]=\"h.y\"\n [attr.width]=\"h.w\"\n [attr.height]=\"h.h\"\n (focus)=\"onFocus(h.index)\"\n (blur)=\"onBlur($event)\"\n (keydown)=\"onKeydown($event, h.index)\"\n />\n }\n </g>\n </svg>\n }\n </vd-chart-frame>\n `,\n})\nexport class VdBarChart extends VdChartBase {\n readonly orientation = input<'vertical' | 'horizontal'>('vertical');\n /** Stack series (part-to-whole) instead of grouping them side by side. */\n readonly stacked = input(false, { transform: booleanAttribute });\n /**\n * Emphasis form for a single series: keep one category in full colour and mute the rest.\n * `'max'` picks the largest value.\n */\n readonly highlight = input<number | 'max' | null>(null);\n\n protected readonly highlighted = computed(() => {\n const h = this.highlight();\n const values = this.series()[0]?.values ?? [];\n if (h === null || this.series().length !== 1) return -1;\n if (h !== 'max') return h;\n let best = -1;\n values.forEach((v, i) => {\n if (v !== null && Number.isFinite(v) && (best < 0 || v > (values[best] ?? -Infinity)))\n best = i;\n });\n return best;\n });\n\n protected readonly stackedValues = () => this.stacked();\n protected extentOf() {\n return vdExtent(this.series(), this.count(), this.stacked());\n }\n\n private readonly vertical = computed(() => this.orientation() === 'vertical');\n\n /** Plot box inside the SVG: [start, end] on each axis. */\n protected readonly box = computed(() => {\n const w = this.width();\n const h = this.height();\n if (this.vertical()) {\n return { x0: this.tickWidth(), x1: w - PAD, y0: PAD, y1: h - AXIS_BAND };\n }\n const labels = Math.min(this.categoryWidth(), w * 0.4);\n return { x0: labels, x1: w - PAD - this.tickWidth() / 2, y0: PAD, y1: h - AXIS_BAND };\n });\n\n private readonly scale = computed(() => {\n const b = this.box();\n return this.vertical() ? this.valueScale([b.y1, b.y0]) : this.valueScale([b.x0, b.x1]);\n });\n\n private readonly categoryRange = computed<[number, number]>(() => {\n const b = this.box();\n return this.vertical() ? [b.x0, b.x1] : [b.y0, b.y1];\n });\n\n private readonly bandList = computed(() => vdBands(this.count(), this.categoryRange()));\n\n protected readonly marks = computed<Mark[]>(() => {\n const series = this.series();\n const n = series.length;\n if (!n || !this.count()) return [];\n const scale = this.scale();\n const zero = scale(0);\n const orient = this.orientation();\n const marks: Mark[] = [];\n if (this.stacked()) {\n const segments = vdStack(series, this.count());\n // Rounded only on the outermost segment of each direction.\n const outer = this.bandList().map((_, c) => {\n let top = -1;\n let bottom = -1;\n segments.forEach((s, i) => {\n if (s[c].to > s[c].from) top = i;\n if (s[c].to < s[c].from) bottom = i;\n });\n return { top, bottom };\n });\n this.bandList().forEach((band, c) => {\n const thickness = Math.min(MAX_THICKNESS, band.step * 0.6);\n segments.forEach((s, i) => {\n const seg = s[c];\n if (seg.to === seg.from) return;\n const rounded = i === outer[c].top || i === outer[c].bottom;\n const from = scale(seg.from);\n const to = scale(seg.to);\n // 2px surface gap between stacked segments, taken from the far end.\n const dir = Math.sign(to - from);\n const end = rounded ? to : to - dir * GAP;\n marks.push({\n d: vdBarPath(band.center, thickness, from, end, rounded ? RADIUS : 0, orient),\n series: i,\n category: c,\n });\n });\n });\n return marks;\n }\n this.bandList().forEach((band, c) => {\n const thickness = Math.min(MAX_THICKNESS, (band.step * 0.7 - GAP * (n - 1)) / n);\n const group = thickness * n + GAP * (n - 1);\n series.forEach((s, i) => {\n const v = s.values[c];\n if (v === null || v === undefined || !Number.isFinite(v)) return;\n const center = band.center - group / 2 + thickness / 2 + i * (thickness + GAP);\n marks.push({\n d: vdBarPath(center, thickness, zero, scale(v), RADIUS, orient),\n series: i,\n category: c,\n });\n });\n });\n return marks;\n });\n\n protected readonly tickMarks = computed(() => {\n const b = this.box();\n const scale = this.scale();\n return this.ticks().map((value) =>\n this.vertical()\n ? {\n value,\n x1: b.x0,\n x2: b.x1,\n y1: scale(value),\n y2: scale(value),\n tx: b.x0 - 6,\n ty: scale(value),\n anchor: 'end',\n }\n : {\n value,\n x1: scale(value),\n x2: scale(value),\n y1: b.y0,\n y2: b.y1,\n tx: scale(value),\n ty: b.y1 + AXIS_BAND / 2 + 2,\n anchor: 'middle',\n },\n );\n });\n\n protected readonly categoryTicks = computed(() => {\n const b = this.box();\n const list = this.bandList();\n if (this.vertical()) {\n const every = this.labelEvery(b.x1 - b.x0);\n return list\n .map((band, index) => ({\n index,\n x: band.center,\n y: b.y1 + AXIS_BAND / 2 + 2,\n anchor: 'middle',\n }))\n .filter((c) => c.index % every === 0);\n }\n return list.map((band, index) => ({ index, x: b.x0 - 8, y: band.center, anchor: 'end' }));\n });\n\n /** Hit targets cover the whole band, bigger than the marks. */\n protected readonly hits = computed(() => {\n const b = this.box();\n return this.bandList().map((band, index) =>\n this.vertical()\n ? { index, x: band.start, y: b.y0, w: band.step, h: b.y1 - b.y0 }\n : { index, x: b.x0, y: band.start, w: b.x1 - b.x0, h: band.step },\n );\n });\n\n protected readonly bandRect = computed(() => {\n const hit = this.hits()[this.active()];\n if (!hit) return { x: 0, y: 0, w: 0, h: 0 };\n const inset = 2;\n return {\n x: hit.x + inset,\n y: hit.y + inset,\n w: Math.max(0, hit.w - inset * 2),\n h: Math.max(0, hit.h - inset * 2),\n };\n });\n\n protected readonly tooltip = computed(() => {\n const i = this.active();\n const band = this.bandList()[i];\n if (!band) return null;\n const b = this.box();\n return this.vertical()\n ? { x: band.center, y: b.y0 }\n : { x: b.x0 + (b.x1 - b.x0) / 2, y: band.center };\n });\n\n protected onPointer(event: PointerEvent): void {\n const svg = event.currentTarget as SVGSVGElement;\n const rect = svg.getBoundingClientRect();\n const pos = this.vertical() ? event.clientX - rect.left : event.clientY - rect.top;\n this.pointerAt(pos, this.categoryRange());\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n booleanAttribute,\n computed,\n input,\n} from '@angular/core';\nimport { vdAreaPath, vdExtent, vdLinePath, type VdPoint } from './core/chart-math';\nimport { VdChartBase } from './chart-base';\nimport { VdChartFrame } from './chart-frame';\n\nconst PAD = 12;\nconst AXIS_BAND = 22;\n/** Direct end labels only while they stay sparing (dataviz: <= 4 series). */\nconst MAX_END_LABELS = 4;\nconst END_LABEL_GAP = 14;\n\n/**\n * Line chart for trends over ordered categories. One series gets a soft area wash; several use\n * the categorical palette with a legend and direct end labels. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-line-chart',\n imports: [VdChartFrame],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n // The `title` input would otherwise also stay as a native tooltip on the host.\n '[attr.title]': 'null',\n class: 'vd-line-chart',\n },\n template: `\n <vd-chart-frame\n kind=\"line\"\n [title]=\"title()\"\n [description]=\"description()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [format]=\"format()\"\n [categoryLabel]=\"categoryLabel()\"\n [loading]=\"loading()\"\n [active]=\"active()\"\n [tooltipX]=\"tooltip()?.x ?? null\"\n [tooltipY]=\"tooltip()?.y ?? 0\"\n (pointerLeave)=\"active.set(-1)\"\n >\n @if (width() > 0) {\n <svg\n class=\"vd-chart__svg\"\n [attr.width]=\"width()\"\n [attr.height]=\"height()\"\n [attr.viewBox]=\"'0 0 ' + width() + ' ' + height()\"\n role=\"group\"\n [attr.aria-labelledby]=\"frame().titleId\"\n (pointermove)=\"onPointer($event)\"\n >\n <g class=\"vd-chart__grid\" aria-hidden=\"true\">\n @for (t of tickMarks(); track t.value) {\n <line\n [attr.x1]=\"box().x0\"\n [attr.x2]=\"box().x1\"\n [attr.y1]=\"t.y\"\n [attr.y2]=\"t.y\"\n [attr.data-zero]=\"t.value === 0 ? '' : null\"\n />\n <text\n [attr.x]=\"box().x0 - 6\"\n [attr.y]=\"t.y\"\n text-anchor=\"end\"\n dominant-baseline=\"middle\"\n >\n {{ tickText(t.value) }}\n </text>\n }\n </g>\n <g class=\"vd-chart__marks\" aria-hidden=\"true\">\n @if (showArea()) {\n <path class=\"vd-chart__area\" [attr.d]=\"areaD()\" [attr.data-series]=\"slot(0)\" />\n }\n @for (l of lines(); track $index) {\n <path class=\"vd-chart__line\" [attr.d]=\"l\" [attr.data-series]=\"slot($index)\" />\n }\n @if (active() >= 0) {\n <line\n class=\"vd-chart__crosshair\"\n [attr.x1]=\"xs()[active()]\"\n [attr.x2]=\"xs()[active()]\"\n [attr.y1]=\"box().y0\"\n [attr.y2]=\"box().y1\"\n />\n }\n @for (d of dots(); track $index) {\n <circle\n class=\"vd-chart__dot\"\n [attr.cx]=\"d.x\"\n [attr.cy]=\"d.y\"\n r=\"4\"\n [attr.data-series]=\"slot(d.series)\"\n />\n }\n </g>\n <g class=\"vd-chart__end-labels\" aria-hidden=\"true\">\n @for (e of endLabels(); track e.series) {\n <text [attr.x]=\"e.x\" [attr.y]=\"e.y\" dominant-baseline=\"middle\">\n {{ series()[e.series].name }}\n </text>\n }\n </g>\n <g class=\"vd-chart__axis\" aria-hidden=\"true\">\n @for (c of categoryTicks(); track c.index) {\n <text\n [attr.x]=\"c.x\"\n [attr.y]=\"box().y1 + 13\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n >\n {{ categories()[c.index] }}\n </text>\n }\n </g>\n <g class=\"vd-chart__hits\">\n @for (x of xs(); track $index; let i = $index) {\n <rect\n class=\"vd-chart__hit\"\n rx=\"6\"\n role=\"img\"\n [attr.data-index]=\"i\"\n [attr.tabindex]=\"i === focusIndex() ? 0 : -1\"\n [attr.aria-label]=\"pointLabel(i)\"\n [attr.x]=\"x - step() / 2\"\n [attr.y]=\"box().y0\"\n [attr.width]=\"step()\"\n [attr.height]=\"box().y1 - box().y0\"\n (focus)=\"onFocus(i)\"\n (blur)=\"onBlur($event)\"\n (keydown)=\"onKeydown($event, i)\"\n />\n }\n </g>\n </svg>\n }\n </vd-chart-frame>\n `,\n})\nexport class VdLineChart extends VdChartBase {\n /** Soft area under a single series; ignored with several series. */\n readonly area = input(true, { transform: booleanAttribute });\n\n protected readonly stackedValues = () => false;\n protected extentOf() {\n return vdExtent(this.series(), this.count(), false);\n }\n\n protected readonly showArea = computed(() => this.area() && this.series().length === 1);\n private readonly labelled = computed(\n () => this.series().length > 1 && this.series().length <= MAX_END_LABELS,\n );\n\n protected readonly box = computed(() => {\n const longest = Math.max(...this.series().map((s) => s.name.length), 0);\n const end = this.labelled() ? Math.min(longest * 6.8 + END_LABEL_GAP, this.width() * 0.3) : PAD;\n return { x0: this.tickWidth(), x1: this.width() - end, y0: PAD, y1: this.height() - AXIS_BAND };\n });\n\n private readonly scale = computed(() => this.valueScale([this.box().y1, this.box().y0]));\n\n /** Point positions: first and last categories sit on the plot edges. */\n protected readonly xs = computed(() => {\n const { x0, x1 } = this.box();\n const n = this.count();\n if (n <= 1) return [(x0 + x1) / 2];\n return Array.from({ length: n }, (_, i) => x0 + (i * (x1 - x0)) / (n - 1));\n });\n protected readonly step = computed(() => {\n const xs = this.xs();\n return xs.length > 1 ? xs[1] - xs[0] : this.box().x1 - this.box().x0;\n });\n\n private readonly points = computed(() =>\n this.series().map((s) =>\n this.xs().map((x, i): VdPoint => {\n const v = s.values[i];\n return v === null || v === undefined || !Number.isFinite(v) ? null : [x, this.scale()(v)];\n }),\n ),\n );\n\n protected readonly lines = computed(() => this.points().map((p) => vdLinePath(p)));\n protected readonly areaD = computed(() => vdAreaPath(this.points()[0] ?? [], this.scale()(0)));\n\n protected readonly tickMarks = computed(() =>\n this.ticks().map((value) => ({ value, y: this.scale()(value) })),\n );\n\n protected readonly categoryTicks = computed(() => {\n const every = this.labelEvery(this.box().x1 - this.box().x0);\n return this.xs()\n .map((x, index) => ({ index, x }))\n .filter((c) => c.index % every === 0 || c.index === this.count() - 1)\n .filter((c, i, all) => i === all.length - 1 || all[all.length - 1].index - c.index >= every);\n });\n\n /** Active point of every series, else the last point (current period). */\n protected readonly dots = computed(() => {\n const at = this.active() >= 0 ? this.active() : this.count() - 1;\n return this.points().flatMap((p, series) => {\n const point = p[at];\n return point ? [{ x: point[0], y: point[1], series }] : [];\n });\n });\n\n /** Names at line ends; labels that would collide fall back to the legend. */\n protected readonly endLabels = computed(() => {\n if (!this.labelled()) return [];\n const x = this.box().x1 + 8;\n const placed: { series: number; x: number; y: number }[] = [];\n this.points()\n .map((p, series) => ({ series, y: [...p].reverse().find((q) => q)?.[1] }))\n .filter((e): e is { series: number; y: number } => e.y !== undefined)\n .sort((a, b) => a.y - b.y)\n .forEach((e) => {\n if (placed.every((p) => Math.abs(p.y - e.y) >= 14)) placed.push({ ...e, x });\n });\n return placed;\n });\n\n protected readonly tooltip = computed(() => {\n const x = this.xs()[this.active()];\n return x === undefined ? null : { x, y: this.box().y0 };\n });\n\n protected onPointer(event: PointerEvent): void {\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const { x0, x1 } = this.box();\n const half = this.step() / 2;\n this.pointerAt(event.clientX - rect.left, [x0 - half, x1 + half]);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { VD_LOCALE, vdTexts } from '@vadem/ui/locale';\nimport { vdAreaPath, vdLinePath, vdLinearScale, type VdPoint } from './core/chart-math';\nimport type { VdChartFormat } from './chart-frame';\n\n/** Fixed drawing box; the SVG scales to its container without distorting strokes. */\nconst W = 120;\nconst H = 32;\nconst INSET = 4;\n\n/**\n * Word-sized trend: line in the de-emphasis ink, current (last) point in the accent.\n * A single image with a spoken summary. Spec: specs/chart.md\n */\n@Component({\n selector: 'vd-sparkline',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: { class: 'vd-sparkline' },\n template: `\n <svg\n class=\"vd-sparkline__svg\"\n [attr.viewBox]=\"'0 0 ' + W + ' ' + H\"\n preserveAspectRatio=\"none\"\n role=\"img\"\n [attr.aria-label]=\"summary()\"\n >\n <path class=\"vd-sparkline__area\" [attr.d]=\"area()\" />\n <path class=\"vd-sparkline__line\" [attr.d]=\"line()\" vector-effect=\"non-scaling-stroke\" />\n </svg>\n @if (last(); as p) {\n <span\n class=\"vd-sparkline__dot\"\n aria-hidden=\"true\"\n [style.--vd-sparkline-x.%]=\"(p[0] / W) * 100\"\n [style.--vd-sparkline-y.%]=\"(p[1] / H) * 100\"\n ></span>\n }\n `,\n})\nexport class VdSparkline {\n readonly values = input<readonly (number | null)[]>([]);\n /** What the trend shows, e.g. \"Дохід за 12 тижнів\". */\n readonly label = input.required<string>();\n readonly format = input<VdChartFormat>();\n readonly trendSummary =\n input<(first: string, last: string, min: string, max: string) => string>();\n\n protected readonly W = W;\n protected readonly H = H;\n protected readonly t = vdTexts('chart', { trendSummary: this.trendSummary });\n private readonly locale = inject(VD_LOCALE);\n\n private readonly numbers = computed(() =>\n this.values().filter((v): v is number => v !== null && Number.isFinite(v)),\n );\n\n private readonly points = computed<VdPoint[]>(() => {\n const values = this.values();\n const nums = this.numbers();\n if (!nums.length) return [];\n const min = Math.min(...nums);\n const max = Math.max(...nums);\n const y = vdLinearScale(min === max ? [min - 1, max + 1] : [min, max], [H - INSET, INSET]);\n const n = values.length;\n return values.map((v, i) =>\n v === null || !Number.isFinite(v) ? null : [n > 1 ? (i * W) / (n - 1) : W / 2, y(v)],\n );\n });\n\n protected readonly line = computed(() => vdLinePath(this.points()));\n protected readonly area = computed(() => vdAreaPath(this.points(), H));\n protected readonly last = computed(() => [...this.points()].reverse().find((p) => p) ?? null);\n\n protected readonly summary = computed(() => {\n const nums = this.numbers();\n if (!nums.length) return this.label();\n const fmt = this.format() ?? ((v: number) => new Intl.NumberFormat(this.locale.code).format(v));\n const text = this.t().trendSummary(\n fmt(nums[0]),\n fmt(nums[nums.length - 1]),\n fmt(Math.min(...nums)),\n fmt(Math.max(...nums)),\n );\n return `${this.label()}: ${text}`;\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, InjectionToken, ViewEncapsulation, booleanAttribute, computed, inject, input, signal } from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, InjectionToken, ViewEncapsulation, booleanAttribute, computed, inject, input, signal } from "@angular/core";
|
|
3
3
|
import { VdIcon } from "@vadem/ui/icon";
|
|
4
4
|
import { NgControl, Validators } from "@angular/forms";
|
|
5
5
|
import { FormField } from "@angular/forms/signals";
|
|
@@ -456,6 +456,8 @@ var VdFieldControlBase = class VdFieldControlBase {
|
|
|
456
456
|
disabled: false,
|
|
457
457
|
required: false
|
|
458
458
|
}, ...ngDevMode ? [{ debugName: "ngState" }] : /* istanbul ignore next */ []);
|
|
459
|
+
isRadio = inject(ElementRef).nativeElement.getAttribute("type") === "radio";
|
|
460
|
+
requiredByValidator = computed(() => !this.required() && this.ngState().required, ...ngDevMode ? [{ debugName: "requiredByValidator" }] : /* istanbul ignore next */ []);
|
|
459
461
|
showInvalid = computed(() => {
|
|
460
462
|
if (this.invalid() && this.touched() !== false) return true;
|
|
461
463
|
const ng = this.ngState();
|
|
@@ -522,7 +524,8 @@ var VdFieldControlBase = class VdFieldControlBase {
|
|
|
522
524
|
"attr.data-invalid": "showInvalid() ? \"\" : null",
|
|
523
525
|
"attr.aria-invalid": "showInvalid() ? \"true\" : null",
|
|
524
526
|
"attr.aria-describedby": "field?.describedBy() ?? null",
|
|
525
|
-
"attr.required": "required() ? \"\" : null"
|
|
527
|
+
"attr.required": "required() || (requiredByValidator() && isRadio) ? \"\" : null",
|
|
528
|
+
"attr.aria-required": "requiredByValidator() && !isRadio ? \"true\" : null"
|
|
526
529
|
} },
|
|
527
530
|
ngImport: i0
|
|
528
531
|
});
|
|
@@ -539,7 +542,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
539
542
|
"[attr.data-invalid]": "showInvalid() ? \"\" : null",
|
|
540
543
|
"[attr.aria-invalid]": "showInvalid() ? \"true\" : null",
|
|
541
544
|
"[attr.aria-describedby]": "field?.describedBy() ?? null",
|
|
542
|
-
"[attr.required]": "required() ? \"\" : null"
|
|
545
|
+
"[attr.required]": "required() || (requiredByValidator() && isRadio) ? \"\" : null",
|
|
546
|
+
"[attr.aria-required]": "requiredByValidator() && !isRadio ? \"true\" : null"
|
|
543
547
|
} }]
|
|
544
548
|
}],
|
|
545
549
|
ctorParameters: () => [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui-field.mjs","names":[],"sources":["../../../projects/ui/field/src/choice.ts","../../../projects/ui/field/src/field-control.ts","../../../projects/ui/field/src/field.ts","../../../projects/ui/field/src/fieldset.ts","../../../projects/ui/field/src/ng-control-state.ts","../../../projects/ui/field/src/field-control-base.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Label that wraps a checkbox, switch or radio and its text. The whole label is the hit area;\n * the text is the control's accessible name. Spec: specs/checkbox.md\n */\n@Directive({\n selector: 'label[vdChoice]',\n host: { class: 'vd-choice' },\n})\nexport class VdChoice {}\n","import { InjectionToken, Signal } from '@angular/core';\n\n/** What a form control exposes to its surrounding `vd-field`. */\nexport interface VdFieldControl {\n readonly id: Signal<string>;\n readonly invalid: Signal<boolean>;\n readonly required: Signal<boolean>;\n readonly disabled: Signal<boolean>;\n}\n\n/** What `vd-field` exposes to the control inside it. */\nexport interface VdFieldContext {\n /** Space-separated ids for `aria-describedby` (hint or error), or null. */\n readonly describedBy: Signal<string | null>;\n register(control: VdFieldControl): void;\n unregister(control: VdFieldControl): void;\n}\n\nexport const VD_FIELD = new InjectionToken<VdFieldContext>('VD_FIELD');\n\nlet nextId = 0;\n/** Deterministic per-app id. Same creation order on server and client keeps hydration stable. */\nexport function vdUniqueId(prefix: string): string {\n return `${prefix}-${nextId++}`;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\n/**\n * Label, hint and error around one form control. Wires `for`, `aria-describedby`,\n * and the required marker automatically. Spec: specs/field.md\n */\n@Component({\n selector: 'vd-field',\n imports: [VdIcon],\n template: `\n @if (label()) {\n <label class=\"vd-field__label\" [attr.for]=\"control()?.id()\">\n {{ label() }}\n @if (control()?.required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n <ng-content />\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n } @else if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n `,\n host: {\n class: 'vd-field',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.data-disabled]': 'control()?.disabled() ? \"\" : null',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdField }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdField implements VdFieldContext {\n readonly label = input<string>();\n readonly hint = input<string>();\n /** Additional descriptive IDs, e.g. a character counter; retained beside hint/error. */\n readonly descriptionIds = input<string>();\n /** Message shown while the control is invalid. Replaces the hint. */\n readonly error = input<string>();\n\n protected readonly control = signal<VdFieldControl | null>(null);\n protected readonly hintId = vdUniqueId('vd-field-hint');\n protected readonly errorId = vdUniqueId('vd-field-error');\n\n protected readonly showError = computed(() => !!this.error() && !!this.control()?.invalid());\n\n readonly describedBy = computed(() => {\n const primary = this.showError() ? this.errorId : this.hint() ? this.hintId : '';\n const ids = [primary, this.descriptionIds() ?? ''].join(' ').split(/\\s+/).filter(Boolean);\n return [...new Set(ids)].join(' ') || null;\n });\n\n register(control: VdFieldControl): void {\n this.control.set(control);\n }\n\n unregister(control: VdFieldControl): void {\n if (this.control() === control) this.control.set(null);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\nexport type VdFieldsetOrientation = 'vertical' | 'horizontal';\n\n/**\n * Legend, hint and error around a group of choices (radios, checkboxes). The group is named by\n * the legend; hint and error describe the fieldset itself, so they are announced once when the\n * group is entered, not on every option. Spec: specs/field.md\n */\n@Component({\n // Attribute selector: the native fieldset keeps its group semantics.\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'fieldset[vdFieldset]',\n imports: [VdIcon],\n template: `\n @if (legend()) {\n <legend class=\"vd-fieldset__legend\">\n {{ legend() }}\n @if (required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </legend>\n }\n @if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n }\n <div class=\"vd-fieldset__options\"><ng-content /></div>\n `,\n host: {\n class: 'vd-fieldset',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.aria-describedby]': 'groupDescribedBy()',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdFieldset }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdFieldset implements VdFieldContext {\n readonly legend = input<string>();\n readonly hint = input<string>();\n /** Shown while any control in the group is displayed invalid. */\n readonly error = input<string>();\n readonly orientation = input<VdFieldsetOrientation>('vertical');\n\n protected readonly controls = signal<readonly VdFieldControl[]>([]);\n protected readonly hintId = vdUniqueId('vd-fieldset-hint');\n protected readonly errorId = vdUniqueId('vd-fieldset-error');\n\n protected readonly required = computed(() => this.controls().some((c) => c.required()));\n protected readonly showError = computed(\n () => !!this.error() && this.controls().some((c) => c.invalid()),\n );\n protected readonly groupDescribedBy = computed(\n () =>\n [this.hint() ? this.hintId : null, this.showError() ? this.errorId : null]\n .filter(Boolean)\n .join(' ') || null,\n );\n\n /** Controls aren't described individually: the fieldset carries the description. */\n readonly describedBy = signal<string | null>(null).asReadonly();\n\n register(control: VdFieldControl): void {\n this.controls.update((list) => [...list, control]);\n }\n\n unregister(control: VdFieldControl): void {\n this.controls.update((list) => list.filter((c) => c !== control));\n }\n}\n","import { DestroyRef, Signal, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgControl, Validators } from '@angular/forms';\n\nexport interface VdNgControlState {\n invalid: boolean;\n touched: boolean;\n disabled: boolean;\n required: boolean;\n}\n\nconst EMPTY: VdNgControlState = {\n invalid: false,\n touched: false,\n disabled: false,\n required: false,\n};\n\n/**\n * Mirrors a Reactive/Template forms control into a signal (NgControl isn't signal-based).\n * Call once the control is resolved (ngOnInit or later). Returns a static empty state when\n * there's no control or it's a Signal Forms shim without `events`.\n */\nexport function vdNgControlState(\n ngControl: NgControl | null,\n destroyRef: DestroyRef,\n): Signal<VdNgControlState> {\n const control = ngControl?.control;\n const state = signal(EMPTY);\n if (!control?.events) return state;\n const sync = () =>\n state.set({\n invalid: control.invalid,\n touched: control.touched,\n disabled: control.disabled,\n required:\n control.hasValidator(Validators.required) || control.hasValidator(Validators.requiredTrue),\n });\n sync();\n control.events.pipe(takeUntilDestroyed(destroyRef)).subscribe(sync);\n return state;\n}\n","import {\n DestroyRef,\n Directive,\n OnInit,\n Signal,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { FormField } from '@angular/forms/signals';\nimport { VD_FIELD, VdFieldControl, vdUniqueId } from './field-control';\nimport { VdNgControlState, vdNgControlState } from './ng-control-state';\n\n/**\n * Shared behavior for controls on native form elements (input, checkbox, switch):\n * displayed validity from Reactive/Template forms or Signal Forms, `vd-field` registration,\n * and the ARIA/data attributes that go with it. Not part of the styling contract.\n */\n@Directive({\n host: {\n '[id]': 'id()',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.aria-invalid]': 'showInvalid() ? \"true\" : null',\n '[attr.aria-describedby]': 'field?.describedBy() ?? null',\n '[attr.required]': 'required() ? \"\" : null',\n },\n})\nexport abstract class VdFieldControlBase implements OnInit {\n /** Invalid state (e.g. a server error). Reactive/Template form validity is detected on its own. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /**\n * Optional gate for `invalid`: when explicitly false the error isn't shown yet. Signal Forms\n * binds `invalid`, `touched` and `required` here automatically (FormUiControl contract).\n */\n readonly touched = input<boolean | undefined>(undefined);\n readonly required = input(false, { transform: booleanAttribute });\n readonly id = input(vdUniqueId('vd-control'));\n\n protected readonly field = inject(VD_FIELD, { optional: true });\n private readonly ngControl = inject(NgControl, { self: true, optional: true });\n private readonly formField = inject(FormField, { self: true, optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n /** Mirrored Reactive/Template forms state; set once the control is resolved (ngOnInit). */\n private readonly ngSource = signal<Signal<VdNgControlState> | null>(null);\n private readonly ngState = computed(\n () =>\n this.ngSource()?.() ?? { invalid: false, touched: false, disabled: false, required: false },\n );\n\n /** Invalid as displayed: forced, or form-invalid after the user has touched the control. */\n readonly showInvalid = computed(() => {\n if (this.invalid() && this.touched() !== false) return true;\n const ng = this.ngState();\n return ng.invalid && ng.touched;\n });\n\n private readonly fieldControl: VdFieldControl = {\n id: this.id,\n invalid: this.showInvalid,\n required: computed(\n () => this.required() || this.ngState().required || !!this.formField?.state().required(),\n ),\n disabled: computed(() => this.ngState().disabled || !!this.formField?.state().disabled()),\n };\n\n constructor() {\n this.field?.register(this.fieldControl);\n this.destroyRef.onDestroy(() => this.field?.unregister(this.fieldControl));\n }\n\n ngOnInit(): void {\n // NgControl resolves its control only after init. Signal Forms provides an NgControl shim\n // too; its state arrives through the inputs instead.\n if (!this.formField) this.ngSource.set(vdNgControlState(this.ngControl, this.destroyRef));\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vadem-ui-field.mjs","names":[],"sources":["../../../projects/ui/field/src/choice.ts","../../../projects/ui/field/src/field-control.ts","../../../projects/ui/field/src/field.ts","../../../projects/ui/field/src/fieldset.ts","../../../projects/ui/field/src/ng-control-state.ts","../../../projects/ui/field/src/field-control-base.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Label that wraps a checkbox, switch or radio and its text. The whole label is the hit area;\n * the text is the control's accessible name. Spec: specs/checkbox.md\n */\n@Directive({\n selector: 'label[vdChoice]',\n host: { class: 'vd-choice' },\n})\nexport class VdChoice {}\n","import { InjectionToken, Signal } from '@angular/core';\n\n/** What a form control exposes to its surrounding `vd-field`. */\nexport interface VdFieldControl {\n readonly id: Signal<string>;\n readonly invalid: Signal<boolean>;\n readonly required: Signal<boolean>;\n readonly disabled: Signal<boolean>;\n}\n\n/** What `vd-field` exposes to the control inside it. */\nexport interface VdFieldContext {\n /** Space-separated ids for `aria-describedby` (hint or error), or null. */\n readonly describedBy: Signal<string | null>;\n register(control: VdFieldControl): void;\n unregister(control: VdFieldControl): void;\n}\n\nexport const VD_FIELD = new InjectionToken<VdFieldContext>('VD_FIELD');\n\nlet nextId = 0;\n/** Deterministic per-app id. Same creation order on server and client keeps hydration stable. */\nexport function vdUniqueId(prefix: string): string {\n return `${prefix}-${nextId++}`;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\n/**\n * Label, hint and error around one form control. Wires `for`, `aria-describedby`,\n * and the required marker automatically. Spec: specs/field.md\n */\n@Component({\n selector: 'vd-field',\n imports: [VdIcon],\n template: `\n @if (label()) {\n <label class=\"vd-field__label\" [attr.for]=\"control()?.id()\">\n {{ label() }}\n @if (control()?.required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n <ng-content />\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n } @else if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n `,\n host: {\n class: 'vd-field',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.data-disabled]': 'control()?.disabled() ? \"\" : null',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdField }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdField implements VdFieldContext {\n readonly label = input<string>();\n readonly hint = input<string>();\n /** Additional descriptive IDs, e.g. a character counter; retained beside hint/error. */\n readonly descriptionIds = input<string>();\n /** Message shown while the control is invalid. Replaces the hint. */\n readonly error = input<string>();\n\n protected readonly control = signal<VdFieldControl | null>(null);\n protected readonly hintId = vdUniqueId('vd-field-hint');\n protected readonly errorId = vdUniqueId('vd-field-error');\n\n protected readonly showError = computed(() => !!this.error() && !!this.control()?.invalid());\n\n readonly describedBy = computed(() => {\n const primary = this.showError() ? this.errorId : this.hint() ? this.hintId : '';\n const ids = [primary, this.descriptionIds() ?? ''].join(' ').split(/\\s+/).filter(Boolean);\n return [...new Set(ids)].join(' ') || null;\n });\n\n register(control: VdFieldControl): void {\n this.control.set(control);\n }\n\n unregister(control: VdFieldControl): void {\n if (this.control() === control) this.control.set(null);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { VdIcon } from '@vadem/ui/icon';\nimport { VD_FIELD, VdFieldContext, VdFieldControl, vdUniqueId } from './field-control';\n\nexport type VdFieldsetOrientation = 'vertical' | 'horizontal';\n\n/**\n * Legend, hint and error around a group of choices (radios, checkboxes). The group is named by\n * the legend; hint and error describe the fieldset itself, so they are announced once when the\n * group is entered, not on every option. Spec: specs/field.md\n */\n@Component({\n // Attribute selector: the native fieldset keeps its group semantics.\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'fieldset[vdFieldset]',\n imports: [VdIcon],\n template: `\n @if (legend()) {\n <legend class=\"vd-fieldset__legend\">\n {{ legend() }}\n @if (required()) {\n <span class=\"vd-field__required\" aria-hidden=\"true\">*</span>\n }\n </legend>\n }\n @if (hint()) {\n <p class=\"vd-field__hint\" [id]=\"hintId\">{{ hint() }}</p>\n }\n @if (showError()) {\n <p class=\"vd-field__error\" [id]=\"errorId\">\n <vd-icon name=\"alert-circle\" />\n <span>{{ error() }}</span>\n </p>\n }\n <div class=\"vd-fieldset__options\"><ng-content /></div>\n `,\n host: {\n class: 'vd-fieldset',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-invalid]': 'showError() ? \"\" : null',\n '[attr.aria-describedby]': 'groupDescribedBy()',\n },\n providers: [{ provide: VD_FIELD, useExisting: VdFieldset }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdFieldset implements VdFieldContext {\n readonly legend = input<string>();\n readonly hint = input<string>();\n /** Shown while any control in the group is displayed invalid. */\n readonly error = input<string>();\n readonly orientation = input<VdFieldsetOrientation>('vertical');\n\n protected readonly controls = signal<readonly VdFieldControl[]>([]);\n protected readonly hintId = vdUniqueId('vd-fieldset-hint');\n protected readonly errorId = vdUniqueId('vd-fieldset-error');\n\n protected readonly required = computed(() => this.controls().some((c) => c.required()));\n protected readonly showError = computed(\n () => !!this.error() && this.controls().some((c) => c.invalid()),\n );\n protected readonly groupDescribedBy = computed(\n () =>\n [this.hint() ? this.hintId : null, this.showError() ? this.errorId : null]\n .filter(Boolean)\n .join(' ') || null,\n );\n\n /** Controls aren't described individually: the fieldset carries the description. */\n readonly describedBy = signal<string | null>(null).asReadonly();\n\n register(control: VdFieldControl): void {\n this.controls.update((list) => [...list, control]);\n }\n\n unregister(control: VdFieldControl): void {\n this.controls.update((list) => list.filter((c) => c !== control));\n }\n}\n","import { DestroyRef, Signal, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NgControl, Validators } from '@angular/forms';\n\nexport interface VdNgControlState {\n invalid: boolean;\n touched: boolean;\n disabled: boolean;\n required: boolean;\n}\n\nconst EMPTY: VdNgControlState = {\n invalid: false,\n touched: false,\n disabled: false,\n required: false,\n};\n\n/**\n * Mirrors a Reactive/Template forms control into a signal (NgControl isn't signal-based).\n * Call once the control is resolved (ngOnInit or later). Returns a static empty state when\n * there's no control or it's a Signal Forms shim without `events`.\n */\nexport function vdNgControlState(\n ngControl: NgControl | null,\n destroyRef: DestroyRef,\n): Signal<VdNgControlState> {\n const control = ngControl?.control;\n const state = signal(EMPTY);\n if (!control?.events) return state;\n const sync = () =>\n state.set({\n invalid: control.invalid,\n touched: control.touched,\n disabled: control.disabled,\n required:\n control.hasValidator(Validators.required) || control.hasValidator(Validators.requiredTrue),\n });\n sync();\n control.events.pipe(takeUntilDestroyed(destroyRef)).subscribe(sync);\n return state;\n}\n","import {\n DestroyRef,\n Directive,\n ElementRef,\n OnInit,\n Signal,\n booleanAttribute,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { NgControl } from '@angular/forms';\nimport { FormField } from '@angular/forms/signals';\nimport { VD_FIELD, VdFieldControl, vdUniqueId } from './field-control';\nimport { VdNgControlState, vdNgControlState } from './ng-control-state';\n\n/**\n * Shared behavior for controls on native form elements (input, checkbox, switch):\n * displayed validity from Reactive/Template forms or Signal Forms, `vd-field` registration,\n * and the ARIA/data attributes that go with it. Not part of the styling contract.\n */\n@Directive({\n host: {\n '[id]': 'id()',\n '[attr.data-invalid]': 'showInvalid() ? \"\" : null',\n '[attr.aria-invalid]': 'showInvalid() ? \"true\" : null',\n '[attr.aria-describedby]': 'field?.describedBy() ?? null',\n '[attr.required]': 'required() || (requiredByValidator() && isRadio) ? \"\" : null',\n // Reactive/Template validators don't add the native attribute. Announce them with\n // aria-required (not supported on role=radio, which gets the native attribute instead).\n '[attr.aria-required]': 'requiredByValidator() && !isRadio ? \"true\" : null',\n },\n})\nexport abstract class VdFieldControlBase implements OnInit {\n /** Invalid state (e.g. a server error). Reactive/Template form validity is detected on its own. */\n readonly invalid = input(false, { transform: booleanAttribute });\n /**\n * Optional gate for `invalid`: when explicitly false the error isn't shown yet. Signal Forms\n * binds `invalid`, `touched` and `required` here automatically (FormUiControl contract).\n */\n readonly touched = input<boolean | undefined>(undefined);\n readonly required = input(false, { transform: booleanAttribute });\n readonly id = input(vdUniqueId('vd-control'));\n\n protected readonly field = inject(VD_FIELD, { optional: true });\n private readonly ngControl = inject(NgControl, { self: true, optional: true });\n private readonly formField = inject(FormField, { self: true, optional: true });\n private readonly destroyRef = inject(DestroyRef);\n\n /** Mirrored Reactive/Template forms state; set once the control is resolved (ngOnInit). */\n private readonly ngSource = signal<Signal<VdNgControlState> | null>(null);\n private readonly ngState = computed(\n () =>\n this.ngSource()?.() ?? { invalid: false, touched: false, disabled: false, required: false },\n );\n\n protected readonly isRadio =\n inject<ElementRef<HTMLElement>>(ElementRef).nativeElement.getAttribute('type') === 'radio';\n /** Required by a Reactive/Template validator while the `required` input is unset. */\n protected readonly requiredByValidator = computed(\n () => !this.required() && this.ngState().required,\n );\n\n /** Invalid as displayed: forced, or form-invalid after the user has touched the control. */\n readonly showInvalid = computed(() => {\n if (this.invalid() && this.touched() !== false) return true;\n const ng = this.ngState();\n return ng.invalid && ng.touched;\n });\n\n private readonly fieldControl: VdFieldControl = {\n id: this.id,\n invalid: this.showInvalid,\n required: computed(\n () => this.required() || this.ngState().required || !!this.formField?.state().required(),\n ),\n disabled: computed(() => this.ngState().disabled || !!this.formField?.state().disabled()),\n };\n\n constructor() {\n this.field?.register(this.fieldControl);\n this.destroyRef.onDestroy(() => this.field?.unregister(this.fieldControl));\n }\n\n ngOnInit(): void {\n // NgControl resolves its control only after init. Signal Forms provides an NgControl shim\n // too; its state arrives through the inputs instead.\n if (!this.formField) this.ngSource.set(vdNgControlState(this.ngControl, this.destroyRef));\n }\n}\n"],"mappings":"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"}
|
package/fesm2022/vadem-ui.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vadem-ui.mjs","names":[],"sources":["../../../projects/ui/src/public-api.ts"],"sourcesContent":["/*\n * Public API surface of @vadem/ui (primary entry point).\n * Components live in secondary entry points: @vadem/ui/button, @vadem/ui/card, ...\n */\nexport const VD_VERSION = '0.0
|
|
1
|
+
{"version":3,"file":"vadem-ui.mjs","names":[],"sources":["../../../projects/ui/src/public-api.ts"],"sourcesContent":["/*\n * Public API surface of @vadem/ui (primary entry point).\n * Components live in secondary entry points: @vadem/ui/button, @vadem/ui/card, ...\n */\nexport const VD_VERSION = '0.1.0';\n"],"mappings":"AAIA,MAAa,aAAa"}
|
package/package.json
CHANGED
|
@@ -128,5 +128,11 @@
|
|
|
128
128
|
.vd-slider {
|
|
129
129
|
appearance: auto;
|
|
130
130
|
}
|
|
131
|
+
|
|
132
|
+
/* The native control's own indicator is removed by `outline: none` above. */
|
|
133
|
+
.vd-slider:focus-visible {
|
|
134
|
+
outline: var(--vd-focus-ring-width) solid var(--vd-color-focus);
|
|
135
|
+
outline-offset: var(--vd-focus-ring-offset);
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
}
|
|
@@ -13,9 +13,9 @@ export interface VdLinearScale {
|
|
|
13
13
|
range: readonly [number, number];
|
|
14
14
|
(value: number): number;
|
|
15
15
|
}
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function vdLinearScale(domain: readonly [number, number], range: readonly [number, number]): VdLinearScale;
|
|
17
17
|
/** Round numbers for an axis: 1, 2, 2.5 or 5 times a power of ten. Always includes zero. */
|
|
18
|
-
export declare function
|
|
18
|
+
export declare function vdNiceTicks(min: number, max: number, target?: number): number[];
|
|
19
19
|
export interface VdBand {
|
|
20
20
|
/** Start of each band. */
|
|
21
21
|
start: number;
|
|
@@ -25,27 +25,27 @@ export interface VdBand {
|
|
|
25
25
|
step: number;
|
|
26
26
|
}
|
|
27
27
|
/** Evenly spaced bands across `range` for `count` categories. */
|
|
28
|
-
export declare function
|
|
28
|
+
export declare function vdBands(count: number, range: readonly [number, number]): VdBand[];
|
|
29
29
|
/** Index of the band nearest to `position` (pointer or keyboard), clamped. */
|
|
30
|
-
export declare function
|
|
30
|
+
export declare function vdNearestIndex(position: number, count: number, range: readonly [number, number]): number;
|
|
31
31
|
export interface VdStackSegment {
|
|
32
32
|
from: number;
|
|
33
33
|
to: number;
|
|
34
34
|
}
|
|
35
35
|
/** Stacks positive values upward and negative values downward from zero, per category. */
|
|
36
|
-
export declare function
|
|
36
|
+
export declare function vdStack(series: readonly VdChartSeries[], count: number): VdStackSegment[][];
|
|
37
37
|
/** [min, max] over all values (stacked totals when `stacked`). */
|
|
38
|
-
export declare function
|
|
38
|
+
export declare function vdExtent(series: readonly VdChartSeries[], count: number, stacked: boolean): readonly [number, number];
|
|
39
39
|
/**
|
|
40
40
|
* A bar from `base` to `end` along the value axis, `thickness` wide, centred at `center` on the
|
|
41
41
|
* category axis. The data end is rounded (`radius`), the baseline end square.
|
|
42
42
|
*/
|
|
43
|
-
export declare function
|
|
43
|
+
export declare function vdBarPath(center: number, thickness: number, base: number, end: number, radius: number, orientation: 'vertical' | 'horizontal'): string;
|
|
44
44
|
export type VdPoint = readonly [x: number, y: number] | null;
|
|
45
45
|
/** Polyline through points; a `null` starts a new segment (missing data is a gap). */
|
|
46
|
-
export declare function
|
|
46
|
+
export declare function vdLinePath(points: readonly VdPoint[]): string;
|
|
47
47
|
/** Closed area between each continuous run of points and the baseline. */
|
|
48
|
-
export declare function
|
|
48
|
+
export declare function vdAreaPath(points: readonly VdPoint[], baseline: number): string;
|
|
49
49
|
type VdChartKind = 'bar' | 'line';
|
|
50
50
|
/** Formats a value for tooltips and the table (full precision, locale-aware). */
|
|
51
51
|
type VdChartFormat = (value: number) => string;
|
|
@@ -136,6 +136,9 @@ export declare abstract class VdFieldControlBase implements OnInit {
|
|
|
136
136
|
/** Mirrored Reactive/Template forms state; set once the control is resolved (ngOnInit). */
|
|
137
137
|
private readonly ngSource;
|
|
138
138
|
private readonly ngState;
|
|
139
|
+
protected readonly isRadio: boolean;
|
|
140
|
+
/** Required by a Reactive/Template validator while the `required` input is unset. */
|
|
141
|
+
protected readonly requiredByValidator: Signal<boolean>;
|
|
139
142
|
/** Invalid as displayed: forced, or form-invalid after the user has touched the control. */
|
|
140
143
|
readonly showInvalid: Signal<boolean>;
|
|
141
144
|
private readonly fieldControl;
|
package/types/vadem-ui.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VD_VERSION = "0.0
|
|
1
|
+
export declare const VD_VERSION = "0.1.0";
|