@akcelik/strct 4.2.1 → 4.3.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.
|
@@ -21612,6 +21612,34 @@ class StrctHeatmap {
|
|
|
21612
21612
|
/** Scale ceiling — the value that maps to full intensity. Auto (data max) when null. */
|
|
21613
21613
|
max = input(null, /* @ts-ignore */
|
|
21614
21614
|
...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
21615
|
+
/**
|
|
21616
|
+
* Label every n-th column (1 = every column, today's behaviour). 24 hourly
|
|
21617
|
+
* columns in a narrow card cannot all carry a readable label; labelling every
|
|
21618
|
+
* third keeps "14:00" legible instead of forcing it down to "14".
|
|
21619
|
+
*/
|
|
21620
|
+
colLabelEvery = input(1, /* @ts-ignore */
|
|
21621
|
+
...(ngDevMode ? [{ debugName: "colLabelEvery" }] : /* istanbul ignore next */ []));
|
|
21622
|
+
/**
|
|
21623
|
+
* Column label text, so a column can be keyed by an ISO time and shown as
|
|
21624
|
+
* "14:00". Return '' to drop a label. Applied after `colLabelEvery`.
|
|
21625
|
+
*/
|
|
21626
|
+
colLabel = input(null, /* @ts-ignore */
|
|
21627
|
+
...(ngDevMode ? [{ debugName: "colLabel" }] : /* istanbul ignore next */ []));
|
|
21628
|
+
/**
|
|
21629
|
+
* Cell tooltip text. Without it a cell reads `row × col: value`, which for a
|
|
21630
|
+
* utilisation grid has no unit — `hv-05 · 14:00 — 47% CPU` is the readable form.
|
|
21631
|
+
*/
|
|
21632
|
+
valueFormat = input(null, /* @ts-ignore */
|
|
21633
|
+
...(ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []));
|
|
21634
|
+
/**
|
|
21635
|
+
* Colour by band instead of one hue: `status` (accent by default) below
|
|
21636
|
+
* `warning`, the warning hue from there, the critical hue from `critical`.
|
|
21637
|
+
* Intensity is scaled by the value's position WITHIN its band, so a 96% cell
|
|
21638
|
+
* reads darker than an 81% one and both read as critical/warning at a glance.
|
|
21639
|
+
* Unset: today's single-hue ramp across the whole range.
|
|
21640
|
+
*/
|
|
21641
|
+
thresholds = input(null, /* @ts-ignore */
|
|
21642
|
+
...(ngDevMode ? [{ debugName: "thresholds" }] : /* istanbul ignore next */ []));
|
|
21615
21643
|
/** Base color of the intensity ramp. */
|
|
21616
21644
|
status = input('accent', /* @ts-ignore */
|
|
21617
21645
|
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
@@ -21710,7 +21738,7 @@ class StrctHeatmap {
|
|
|
21710
21738
|
w: round(w),
|
|
21711
21739
|
h: ch,
|
|
21712
21740
|
fill: value === undefined ? 'var(--bg-2)' : this.fillFor(value),
|
|
21713
|
-
tip: value === undefined ? null :
|
|
21741
|
+
tip: value === undefined ? null : this.tipFor(value, row, col),
|
|
21714
21742
|
});
|
|
21715
21743
|
});
|
|
21716
21744
|
});
|
|
@@ -21732,9 +21760,24 @@ class StrctHeatmap {
|
|
|
21732
21760
|
const gap = this.gap();
|
|
21733
21761
|
const x0 = this.rowLabelWidth();
|
|
21734
21762
|
const y = this.height() - 4;
|
|
21735
|
-
|
|
21763
|
+
const every = Math.max(1, Math.trunc(this.colLabelEvery()));
|
|
21764
|
+
const format = this.colLabel();
|
|
21765
|
+
const out = [];
|
|
21766
|
+
this.colOrder().forEach((col, c) => {
|
|
21767
|
+
if (c % every !== 0)
|
|
21768
|
+
return;
|
|
21769
|
+
const text = format ? format(col, c) : col;
|
|
21770
|
+
if (text === '')
|
|
21771
|
+
return;
|
|
21772
|
+
out.push({ text, x: round(x0 + c * (w + gap) + w / 2), y });
|
|
21773
|
+
});
|
|
21774
|
+
return out;
|
|
21736
21775
|
}, /* @ts-ignore */
|
|
21737
21776
|
...(ngDevMode ? [{ debugName: "colLabels" }] : /* istanbul ignore next */ []));
|
|
21777
|
+
tipFor(value, row, col) {
|
|
21778
|
+
const format = this.valueFormat();
|
|
21779
|
+
return format ? format(value, row, col) : `${row} × ${col}: ${value}`;
|
|
21780
|
+
}
|
|
21738
21781
|
/** Screen-reader summary of the whole grid (role="img" name). */
|
|
21739
21782
|
aria = computed(() => {
|
|
21740
21783
|
const info = {
|
|
@@ -21752,17 +21795,41 @@ class StrctHeatmap {
|
|
|
21752
21795
|
/**
|
|
21753
21796
|
* Intensity ramp: 8% of the status hue for the smallest non-zero value up
|
|
21754
21797
|
* to 100% at the ceiling; zero stays on the empty-cell surface.
|
|
21798
|
+
*
|
|
21799
|
+
* With `thresholds`, the hue comes from the value's band and the intensity
|
|
21800
|
+
* from its position inside that band, floored at 45% — a band has to be
|
|
21801
|
+
* recognisable as itself, and a pale cell must not read as "no data".
|
|
21755
21802
|
*/
|
|
21756
21803
|
fillFor(value) {
|
|
21757
21804
|
if (value <= 0)
|
|
21758
21805
|
return 'var(--bg-2)';
|
|
21759
21806
|
const maxV = this.maxVal();
|
|
21760
|
-
const t =
|
|
21761
|
-
|
|
21807
|
+
const t = this.thresholds();
|
|
21808
|
+
if (t) {
|
|
21809
|
+
const { color, from, to } = this.bandFor(value, t, maxV);
|
|
21810
|
+
const span = to - from;
|
|
21811
|
+
const pos = span > 0 ? Math.min(Math.max((value - from) / span, 0), 1) : 1;
|
|
21812
|
+
const pct = 45 + Math.round(pos * 55);
|
|
21813
|
+
return `color-mix(in srgb, ${color} ${pct}%, var(--bg-1))`;
|
|
21814
|
+
}
|
|
21815
|
+
const ratio = maxV > 0 ? Math.min(value / maxV, 1) : 0;
|
|
21816
|
+
const pct = 8 + Math.round(ratio * 92);
|
|
21762
21817
|
return `color-mix(in srgb, ${this.color()} ${pct}%, var(--bg-1))`;
|
|
21763
21818
|
}
|
|
21819
|
+
/** The band a value falls in: its hue and the range intensity scales over. */
|
|
21820
|
+
bandFor(value, t, maxV) {
|
|
21821
|
+
const ceiling = Math.max(maxV, value);
|
|
21822
|
+
if (t.critical != null && value >= t.critical) {
|
|
21823
|
+
return { color: COLOR.critical, from: t.critical, to: ceiling };
|
|
21824
|
+
}
|
|
21825
|
+
if (t.warning != null && value >= t.warning) {
|
|
21826
|
+
return { color: COLOR.warning, from: t.warning, to: t.critical ?? ceiling };
|
|
21827
|
+
}
|
|
21828
|
+
const upper = t.warning ?? t.critical ?? ceiling;
|
|
21829
|
+
return { color: this.color(), from: 0, to: upper };
|
|
21830
|
+
}
|
|
21764
21831
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctHeatmap, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21765
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctHeatmap, isStandalone: true, selector: "strct-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, summaryFormat: { classPropertyName: "summaryFormat", publicName: "summaryFormat", isSignal: true, isRequired: false, transformFunction: null }, cellHeight: { classPropertyName: "cellHeight", publicName: "cellHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, rowLabelWidth: { classPropertyName: "rowLabelWidth", publicName: "rowLabelWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-heatmap" }, ngImport: i0, template: `
|
|
21832
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctHeatmap, isStandalone: true, selector: "strct-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, colLabelEvery: { classPropertyName: "colLabelEvery", publicName: "colLabelEvery", isSignal: true, isRequired: false, transformFunction: null }, colLabel: { classPropertyName: "colLabel", publicName: "colLabel", isSignal: true, isRequired: false, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, thresholds: { classPropertyName: "thresholds", publicName: "thresholds", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, summaryFormat: { classPropertyName: "summaryFormat", publicName: "summaryFormat", isSignal: true, isRequired: false, transformFunction: null }, cellHeight: { classPropertyName: "cellHeight", publicName: "cellHeight", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, rowLabelWidth: { classPropertyName: "rowLabelWidth", publicName: "rowLabelWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-heatmap" }, ngImport: i0, template: `
|
|
21766
21833
|
@if (isEmpty()) {
|
|
21767
21834
|
<div class="strct-heatmap__empty">{{ emptyText() }}</div>
|
|
21768
21835
|
} @else {
|
|
@@ -21774,7 +21841,10 @@ class StrctHeatmap {
|
|
|
21774
21841
|
[attr.width]="width()"
|
|
21775
21842
|
[attr.height]="height()"
|
|
21776
21843
|
>
|
|
21777
|
-
|
|
21844
|
+
<!-- Tracked by index: label text is data and repeats legitimately (two
|
|
21845
|
+
hosts with the same name, hour 02 twice at the DST fall-back), and
|
|
21846
|
+
a thinned column axis repeats the empty string. -->
|
|
21847
|
+
@for (l of rowLabels(); track $index) {
|
|
21778
21848
|
<text
|
|
21779
21849
|
class="strct-heatmap__label strct-heatmap__label--row"
|
|
21780
21850
|
[attr.x]="l.x"
|
|
@@ -21785,7 +21855,7 @@ class StrctHeatmap {
|
|
|
21785
21855
|
{{ l.text }}
|
|
21786
21856
|
</text>
|
|
21787
21857
|
}
|
|
21788
|
-
@for (l of colLabels(); track
|
|
21858
|
+
@for (l of colLabels(); track $index) {
|
|
21789
21859
|
<text
|
|
21790
21860
|
class="strct-heatmap__label strct-heatmap__label--col"
|
|
21791
21861
|
[attr.x]="l.x"
|
|
@@ -21829,7 +21899,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
21829
21899
|
[attr.width]="width()"
|
|
21830
21900
|
[attr.height]="height()"
|
|
21831
21901
|
>
|
|
21832
|
-
|
|
21902
|
+
<!-- Tracked by index: label text is data and repeats legitimately (two
|
|
21903
|
+
hosts with the same name, hour 02 twice at the DST fall-back), and
|
|
21904
|
+
a thinned column axis repeats the empty string. -->
|
|
21905
|
+
@for (l of rowLabels(); track $index) {
|
|
21833
21906
|
<text
|
|
21834
21907
|
class="strct-heatmap__label strct-heatmap__label--row"
|
|
21835
21908
|
[attr.x]="l.x"
|
|
@@ -21840,7 +21913,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
21840
21913
|
{{ l.text }}
|
|
21841
21914
|
</text>
|
|
21842
21915
|
}
|
|
21843
|
-
@for (l of colLabels(); track
|
|
21916
|
+
@for (l of colLabels(); track $index) {
|
|
21844
21917
|
<text
|
|
21845
21918
|
class="strct-heatmap__label strct-heatmap__label--col"
|
|
21846
21919
|
[attr.x]="l.x"
|
|
@@ -21869,7 +21942,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
21869
21942
|
</svg>
|
|
21870
21943
|
}
|
|
21871
21944
|
`, host: { class: 'strct-heatmap' }, styles: [".strct-heatmap{display:block}.strct-heatmap__svg{width:100%;display:block}.strct-heatmap__empty{display:flex;align-items:center;justify-content:center;min-height:60px;font-size:12px;color:var(--t3)}.strct-heatmap__label{fill:var(--t3);font-size:10px}.strct-heatmap__label--row{font-family:var(--font)}.strct-heatmap__label--col{font-family:var(--mono);font-variant-numeric:tabular-nums}.strct-heatmap__cell{stroke:var(--bg-1);stroke-width:1}@media(prefers-reduced-motion:no-preference){.strct-heatmap__cell{transition:opacity .12s ease}}.strct-heatmap__cell:hover{opacity:.75}\n"] }]
|
|
21872
|
-
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], cols: [{ type: i0.Input, args: [{ isSignal: true, alias: "cols", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], summaryFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "summaryFormat", required: false }] }], cellHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], rowLabelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLabelWidth", required: false }] }] } });
|
|
21945
|
+
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], cols: [{ type: i0.Input, args: [{ isSignal: true, alias: "cols", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], colLabelEvery: [{ type: i0.Input, args: [{ isSignal: true, alias: "colLabelEvery", required: false }] }], colLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "colLabel", required: false }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], thresholds: [{ type: i0.Input, args: [{ isSignal: true, alias: "thresholds", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], summaryFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "summaryFormat", required: false }] }], cellHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellHeight", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], rowLabelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLabelWidth", required: false }] }] } });
|
|
21873
21946
|
|
|
21874
21947
|
/**
|
|
21875
21948
|
* Public API surface of the strct UI library.
|