@aceshooting/lyra-ui 2.0.0 → 2.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/README.md +87 -14
- package/custom-elements.json +11555 -5539
- package/dist/components/app-rail/app-rail-item.d.ts +30 -0
- package/dist/components/app-rail/app-rail-item.js +68 -0
- package/dist/components/app-rail/app-rail-item.styles.d.ts +1 -0
- package/dist/components/app-rail/app-rail-item.styles.js +65 -0
- package/dist/components/app-rail/app-rail.d.ts +21 -24
- package/dist/components/app-rail/app-rail.js +68 -132
- package/dist/components/app-rail/app-rail.styles.js +5 -2
- package/dist/components/attachment-chip/attachment-chip.d.ts +38 -11
- package/dist/components/attachment-chip/attachment-chip.js +73 -29
- package/dist/components/attachment-trigger/attachment-trigger.d.ts +13 -0
- package/dist/components/attachment-trigger/attachment-trigger.js +13 -1
- package/dist/components/attachment-trigger/attachment-trigger.styles.js +28 -6
- package/dist/components/chart/bar-chart.js +2 -18
- package/dist/components/chart/box-plot.d.ts +25 -1
- package/dist/components/chart/box-plot.js +136 -6
- package/dist/components/chart/box-plot.styles.js +13 -0
- package/dist/components/chart/bubble-chart.js +2 -18
- package/dist/components/chart/chart.d.ts +54 -10
- package/dist/components/chart/chart.js +182 -39
- package/dist/components/chart/doughnut-chart.js +2 -18
- package/dist/components/chart/histogram-bin.d.ts +5 -2
- package/dist/components/chart/histogram-bin.js +12 -4
- package/dist/components/chart/histogram.js +8 -16
- package/dist/components/chart/line-chart.js +2 -18
- package/dist/components/chart/lite-chart.d.ts +80 -3
- package/dist/components/chart/lite-chart.js +250 -53
- package/dist/components/chart/pie-chart.js +2 -18
- package/dist/components/chart/polar-area-chart.js +2 -18
- package/dist/components/chart/radar-chart.js +2 -18
- package/dist/components/chart/scatter-chart.js +2 -18
- package/dist/components/chat-composer/chat-composer.d.ts +42 -1
- package/dist/components/chat-composer/chat-composer.js +84 -3
- package/dist/components/chat-composer/chat-composer.styles.js +11 -1
- package/dist/components/chat-message/chat-message.d.ts +32 -4
- package/dist/components/chat-message/chat-message.js +57 -17
- package/dist/components/checkbox/checkbox.d.ts +66 -8
- package/dist/components/checkbox/checkbox.js +173 -50
- package/dist/components/checkbox/checkbox.styles.js +9 -2
- package/dist/components/chip/chip-group.js +8 -2
- package/dist/components/chip/chip.js +9 -2
- package/dist/components/citation-badge/citation-badge.js +21 -3
- package/dist/components/code-block/code-block.d.ts +38 -0
- package/dist/components/code-block/code-block.js +72 -7
- package/dist/components/code-block/code-loader.d.ts +44 -1
- package/dist/components/code-block/code-loader.js +63 -0
- package/dist/components/combobox/combobox.d.ts +46 -5
- package/dist/components/combobox/combobox.js +175 -35
- package/dist/components/combobox/combobox.styles.js +3 -3
- package/dist/components/context-meter/context-meter.js +17 -8
- package/dist/components/context-meter/context-meter.styles.js +0 -6
- package/dist/components/conversation-item/conversation-item.d.ts +13 -16
- package/dist/components/conversation-item/conversation-item.js +29 -20
- package/dist/components/date-picker/calendar-core.d.ts +24 -0
- package/dist/components/date-picker/calendar-core.js +51 -4
- package/dist/components/date-picker/date-input.d.ts +77 -10
- package/dist/components/date-picker/date-input.js +278 -73
- package/dist/components/date-picker/date-picker.d.ts +28 -4
- package/dist/components/date-picker/date-picker.js +95 -37
- package/dist/components/dialog/confirm.js +3 -6
- package/dist/components/dialog/dialog.d.ts +75 -31
- package/dist/components/dialog/dialog.js +147 -131
- package/dist/components/dialog/dialog.styles.js +46 -2
- package/dist/components/dock-panel/dock-panel.d.ts +8 -0
- package/dist/components/dock-panel/dock-panel.js +15 -1
- package/dist/components/dock-panel/dock-panel.styles.js +15 -1
- package/dist/components/document-preview/document-preview.d.ts +15 -7
- package/dist/components/document-preview/document-preview.js +29 -13
- package/dist/components/empty/empty.d.ts +1 -2
- package/dist/components/empty/empty.js +18 -12
- package/dist/components/empty/empty.styles.js +0 -3
- package/dist/components/export-button/export-button.d.ts +12 -0
- package/dist/components/export-button/export-button.js +33 -5
- package/dist/components/export-button/export-button.styles.js +5 -1
- package/dist/components/file-input/accept.js +2 -0
- package/dist/components/file-input/file-input.d.ts +10 -1
- package/dist/components/file-input/file-input.js +36 -5
- package/dist/components/flag/flag.d.ts +1 -1
- package/dist/components/flag/flag.js +15 -1
- package/dist/components/flag/flag.styles.js +1 -1
- package/dist/components/flag/language-map.d.ts +4 -1
- package/dist/components/flag/language-map.js +6 -3
- package/dist/components/gauge/gauge.d.ts +10 -1
- package/dist/components/gauge/gauge.js +28 -9
- package/dist/components/generation-status/generation-status.d.ts +13 -5
- package/dist/components/generation-status/generation-status.js +59 -5
- package/dist/components/graph/graph.d.ts +37 -3
- package/dist/components/graph/graph.js +132 -20
- package/dist/components/heatmap/calendar-grid.d.ts +15 -6
- package/dist/components/heatmap/calendar-grid.js +17 -6
- package/dist/components/heatmap/heatmap-scale.d.ts +5 -1
- package/dist/components/heatmap/heatmap-scale.js +8 -2
- package/dist/components/heatmap/heatmap.d.ts +166 -25
- package/dist/components/heatmap/heatmap.js +372 -89
- package/dist/components/json-viewer/json-viewer.d.ts +22 -5
- package/dist/components/json-viewer/json-viewer.js +115 -37
- package/dist/components/json-viewer/json-viewer.styles.js +2 -1
- package/dist/components/kbd/kbd.js +24 -7
- package/dist/components/live-region/live-region.d.ts +10 -1
- package/dist/components/live-region/live-region.js +42 -6
- package/dist/components/map/map.d.ts +24 -1
- package/dist/components/map/map.js +89 -24
- package/dist/components/markdown/markdown-loader.d.ts +24 -0
- package/dist/components/markdown/markdown-loader.js +35 -1
- package/dist/components/markdown/markdown.d.ts +46 -8
- package/dist/components/markdown/markdown.js +136 -31
- package/dist/components/markdown/markdown.styles.js +7 -1
- package/dist/components/media-card/media-card.d.ts +25 -17
- package/dist/components/media-card/media-card.js +43 -65
- package/dist/components/mention-popover/mention-popover.d.ts +4 -1
- package/dist/components/mention-popover/mention-popover.js +23 -5
- package/dist/components/menu/menu-item.d.ts +32 -3
- package/dist/components/menu/menu-item.js +94 -7
- package/dist/components/menu/menu-item.styles.js +8 -0
- package/dist/components/menu/menu.d.ts +25 -1
- package/dist/components/menu/menu.js +99 -3
- package/dist/components/menu/menu.styles.js +3 -2
- package/dist/components/model-select/model-select.d.ts +48 -3
- package/dist/components/model-select/model-select.js +120 -22
- package/dist/components/model-select/model-select.styles.js +17 -3
- package/dist/components/model-settings-panel/model-settings-panel.d.ts +25 -1
- package/dist/components/model-settings-panel/model-settings-panel.js +65 -1
- package/dist/components/playback/playback.d.ts +6 -2
- package/dist/components/playback/playback.js +72 -29
- package/dist/components/playback/playback.styles.js +6 -1
- package/dist/components/responsive-panel/responsive-panel.d.ts +29 -16
- package/dist/components/responsive-panel/responsive-panel.js +130 -132
- package/dist/components/responsive-panel/responsive-panel.styles.js +1 -1
- package/dist/components/result-card/result-card.d.ts +8 -2
- package/dist/components/result-card/result-card.js +9 -3
- package/dist/components/result-card/result-card.styles.js +0 -1
- package/dist/components/select/select.d.ts +59 -20
- package/dist/components/select/select.js +125 -43
- package/dist/components/skeleton/skeleton.d.ts +3 -0
- package/dist/components/skeleton/skeleton.js +7 -1
- package/dist/components/skeleton/skeleton.styles.js +5 -4
- package/dist/components/slider/slider.d.ts +57 -5
- package/dist/components/slider/slider.js +195 -80
- package/dist/components/source-card/source-card.d.ts +17 -5
- package/dist/components/source-card/source-card.js +55 -8
- package/dist/components/source-card/source-card.styles.js +1 -1
- package/dist/components/source-list/source-list.js +9 -1
- package/dist/components/sparkline/sparkline.js +34 -10
- package/dist/components/split/split.d.ts +141 -14
- package/dist/components/split/split.js +357 -52
- package/dist/components/split/split.styles.js +18 -1
- package/dist/components/stat/stat.d.ts +10 -4
- package/dist/components/stat/stat.js +46 -11
- package/dist/components/stream-status/stream-status.d.ts +27 -11
- package/dist/components/stream-status/stream-status.js +95 -13
- package/dist/components/streaming-text/streaming-text.d.ts +9 -3
- package/dist/components/streaming-text/streaming-text.js +25 -10
- package/dist/components/streaming-text/streaming-text.styles.js +3 -2
- package/dist/components/switch/switch.d.ts +52 -7
- package/dist/components/switch/switch.js +111 -40
- package/dist/components/switch/switch.styles.js +1 -1
- package/dist/components/table/table.d.ts +18 -3
- package/dist/components/table/table.js +88 -20
- package/dist/components/tabs/tabs.d.ts +23 -0
- package/dist/components/tabs/tabs.js +76 -12
- package/dist/components/tabs/tabs.styles.js +11 -0
- package/dist/components/thinking-panel/thinking-panel.d.ts +3 -1
- package/dist/components/thinking-panel/thinking-panel.js +34 -9
- package/dist/components/thinking-panel/thinking-panel.styles.js +6 -0
- package/dist/components/time-range/time-range.d.ts +59 -2
- package/dist/components/time-range/time-range.js +163 -67
- package/dist/components/toast/toast-item.d.ts +12 -3
- package/dist/components/toast/toast-item.js +90 -53
- package/dist/components/toast/toast-item.styles.js +59 -28
- package/dist/components/toast/toast.js +17 -5
- package/dist/components/toast/toaster.js +10 -1
- package/dist/components/tool-approval-dialog/tool-approval-dialog.d.ts +11 -10
- package/dist/components/tool-approval-dialog/tool-approval-dialog.js +50 -124
- package/dist/components/tool-approval-dialog/tool-approval-dialog.styles.js +1 -1
- package/dist/components/tool-call-chip/tool-call-chip.d.ts +18 -2
- package/dist/components/tool-call-chip/tool-call-chip.js +86 -25
- package/dist/components/tool-param-form/tool-param-form.d.ts +89 -28
- package/dist/components/tool-param-form/tool-param-form.js +350 -106
- package/dist/components/tool-result-dialog/tool-result-dialog.d.ts +27 -7
- package/dist/components/tool-result-dialog/tool-result-dialog.js +80 -115
- package/dist/components/tool-result-dialog/tool-result-dialog.styles.js +1 -1
- package/dist/components/tool-result-view/registry.d.ts +0 -8
- package/dist/components/tool-result-view/registry.js +7 -2
- package/dist/components/tool-result-view/tool-result-view.d.ts +6 -3
- package/dist/components/tool-result-view/tool-result-view.js +18 -4
- package/dist/components/tool-select-dialog/tool-select-dialog.d.ts +11 -11
- package/dist/components/tool-select-dialog/tool-select-dialog.js +44 -133
- package/dist/components/tool-select-dialog/tool-select-dialog.styles.js +13 -4
- package/dist/components/tree/tree-node.d.ts +4 -1
- package/dist/components/tree/tree-node.js +4 -1
- package/dist/components/tree/tree.d.ts +17 -8
- package/dist/components/tree/tree.js +21 -20
- package/dist/components/typing-indicator/typing-indicator.d.ts +12 -2
- package/dist/components/typing-indicator/typing-indicator.js +16 -4
- package/dist/components/typing-indicator/typing-indicator.styles.js +2 -2
- package/dist/components/virtual-list/virtual-list.d.ts +56 -19
- package/dist/components/virtual-list/virtual-list.js +184 -38
- package/dist/components/virtual-list/virtual-list.styles.js +12 -0
- package/dist/components/widget/widget.d.ts +5 -4
- package/dist/components/widget/widget.js +54 -120
- package/dist/components/widget/widget.styles.js +8 -2
- package/dist/components/word-cloud/word-cloud-layout.d.ts +7 -0
- package/dist/components/word-cloud/word-cloud-layout.js +20 -6
- package/dist/components/word-cloud/word-cloud.d.ts +22 -2
- package/dist/components/word-cloud/word-cloud.js +45 -6
- package/dist/components/word-cloud/word-cloud.styles.js +13 -1
- package/dist/internal/anchored-validity.d.ts +1 -0
- package/dist/internal/anchored-validity.js +86 -0
- package/dist/internal/form-associated.d.ts +7 -0
- package/dist/internal/form-associated.js +43 -4
- package/dist/internal/numbers.d.ts +12 -0
- package/dist/internal/numbers.js +26 -0
- package/dist/internal/overlay-manager.d.ts +51 -0
- package/dist/internal/overlay-manager.js +523 -0
- package/dist/internal/positioner.js +27 -3
- package/dist/internal/safe-url.d.ts +12 -0
- package/dist/internal/safe-url.js +41 -0
- package/dist/internal/tokens.styles.js +17 -11
- package/dist/lyra.d.ts +5 -2
- package/dist/lyra.js +3 -1
- package/llms-full.txt +970 -426
- package/llms.txt +5 -4
- package/package.json +19 -2
|
@@ -8,9 +8,25 @@ import { html, nothing } from 'lit';
|
|
|
8
8
|
import { property, query, state } from 'lit/decorators.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
+
import { nextId, srOnly } from '../../internal/a11y.js';
|
|
11
12
|
import { loadChartJs, loadChartJsWithZoom } from './chart-loader.js';
|
|
12
13
|
import { styles } from './chart.styles.js';
|
|
13
14
|
import '../skeleton/skeleton.js';
|
|
15
|
+
const CHART_TYPES = new Set([
|
|
16
|
+
'line',
|
|
17
|
+
'bar',
|
|
18
|
+
'scatter',
|
|
19
|
+
'pie',
|
|
20
|
+
'doughnut',
|
|
21
|
+
'radar',
|
|
22
|
+
'polarArea',
|
|
23
|
+
'bubble',
|
|
24
|
+
]);
|
|
25
|
+
function normalizeChartType(value) {
|
|
26
|
+
return typeof value === 'string' && CHART_TYPES.has(value)
|
|
27
|
+
? value
|
|
28
|
+
: 'line';
|
|
29
|
+
}
|
|
14
30
|
/**
|
|
15
31
|
* Recursively merges `override` onto `base`, matching JSON-merge semantics:
|
|
16
32
|
* plain objects are merged key-by-key at every depth; arrays, functions, and
|
|
@@ -39,15 +55,21 @@ const FALLBACK_TICK_COLOR = '#6b7280';
|
|
|
39
55
|
const FALLBACK_LEGEND_COLOR = '#1a1a1a';
|
|
40
56
|
const FALLBACK_TOOLTIP_BG = '#fff';
|
|
41
57
|
const FALLBACK_TOOLTIP_TEXT = '#1a1a1a';
|
|
42
|
-
function deepMerge(base, override) {
|
|
58
|
+
function deepMerge(base, override, seen = new WeakMap()) {
|
|
59
|
+
if (typeof override === 'object' && override !== null) {
|
|
60
|
+
const previous = seen.get(override);
|
|
61
|
+
if (previous !== undefined)
|
|
62
|
+
return previous;
|
|
63
|
+
}
|
|
43
64
|
if (!isPlainObject(base) || !isPlainObject(override)) {
|
|
44
65
|
return (override === undefined ? base : override);
|
|
45
66
|
}
|
|
46
67
|
const result = { ...base };
|
|
68
|
+
seen.set(override, result);
|
|
47
69
|
for (const key of Object.keys(override)) {
|
|
48
70
|
if (UNSAFE_KEYS.has(key))
|
|
49
71
|
continue;
|
|
50
|
-
result[key] = deepMerge(base[key], override[key]);
|
|
72
|
+
result[key] = deepMerge(base[key], override[key], seen);
|
|
51
73
|
}
|
|
52
74
|
return result;
|
|
53
75
|
}
|
|
@@ -76,7 +98,12 @@ function deepMerge(base, override) {
|
|
|
76
98
|
* intersect-only — see `handlePointClick()`) a data point/segment.
|
|
77
99
|
* `detail: { datasetIndex: number, index: number, label: string |
|
|
78
100
|
* undefined, value: unknown }`.
|
|
79
|
-
* @csspart base
|
|
101
|
+
* @csspart base - The chart wrapper.
|
|
102
|
+
* @csspart canvas - The Chart.js canvas.
|
|
103
|
+
* @csspart reset-zoom-button - The reset-zoom control when zoom is active.
|
|
104
|
+
* @csspart description - The accessible chart summary.
|
|
105
|
+
* @csspart data-table - The optional generated or slotted data table.
|
|
106
|
+
* @slot data-table - An optional consumer-provided accessible table alternative.
|
|
80
107
|
*/
|
|
81
108
|
export class LyraChart extends LyraElement {
|
|
82
109
|
constructor() {
|
|
@@ -92,6 +119,12 @@ export class LyraChart extends LyraElement {
|
|
|
92
119
|
this.yLabel = '';
|
|
93
120
|
this.y2Label = '';
|
|
94
121
|
this.beginAtZero = true;
|
|
122
|
+
/** Accessible name applied to the canvas. Falls back to the dataset labels. */
|
|
123
|
+
this.accessibleLabel = '';
|
|
124
|
+
/** Accessible description for the canvas. When unset, a concise data/trend summary is generated. */
|
|
125
|
+
this.accessibleDescription = '';
|
|
126
|
+
/** Makes the generated data table visible; it remains screen-reader available when false. */
|
|
127
|
+
this.showDataTable = false;
|
|
95
128
|
/** Sets `options.indexAxis = 'y'`, Chart.js's own mechanism for horizontal bars (also applies to line/area types). */
|
|
96
129
|
this.horizontal = false;
|
|
97
130
|
/** Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types. */
|
|
@@ -100,15 +133,15 @@ export class LyraChart extends LyraElement {
|
|
|
100
133
|
this.loading = true;
|
|
101
134
|
this.zoomed = false;
|
|
102
135
|
this.visible = true;
|
|
103
|
-
this.lastSignature = '';
|
|
104
136
|
// `chartjs-plugin-zoom`'s own `resetZoom()` synchronously re-invokes the
|
|
105
137
|
// `onZoomComplete` callback below as part of its reset, which would emit a
|
|
106
138
|
// stale `{zoomed: true}` right before `resetZoom()` emits the real
|
|
107
139
|
// `{zoomed: false}`. Set while this component's own `resetZoom()` is
|
|
108
140
|
// driving the plugin so that re-entrant callback is ignored.
|
|
109
141
|
this.suppressZoomComplete = false;
|
|
142
|
+
this.descriptionId = nextId('chart-description');
|
|
110
143
|
}
|
|
111
|
-
static { this.styles = [LyraElement.styles, styles]; }
|
|
144
|
+
static { this.styles = [LyraElement.styles, styles, srOnly]; }
|
|
112
145
|
connectedCallback() {
|
|
113
146
|
super.connectedCallback();
|
|
114
147
|
const load = this.zoom ? loadChartJsWithZoom() : loadChartJs();
|
|
@@ -137,6 +170,27 @@ export class LyraChart extends LyraElement {
|
|
|
137
170
|
this.chart = undefined;
|
|
138
171
|
this.intersectionObserver?.disconnect();
|
|
139
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Resets a stale `zoomed` flag before the render pass that's about to call
|
|
175
|
+
* `draw()`: a `type` (or `config.type` override) change that lands on a
|
|
176
|
+
* *different* effective Chart.js type makes `draw()` destroy the old
|
|
177
|
+
* `Chart` instance and construct a brand-new one, which was never zoomed —
|
|
178
|
+
* without this, `render()`'s reset-zoom-button stays visible for an
|
|
179
|
+
* instance that has no zoom/pan state left to reset. Computed here (before
|
|
180
|
+
* render), not in `updated()`/`draw()`, because setting `zoomed` — a
|
|
181
|
+
* reactive `@state` property — from `updated()` would schedule a second,
|
|
182
|
+
* redundant update pass; `willUpdate()` runs before this cycle's render is
|
|
183
|
+
* considered complete, so the same set just folds into the render already
|
|
184
|
+
* in progress. Same rationale as `toast-item.ts`'s `willUpdate()`-vs-
|
|
185
|
+
* `updated()` split.
|
|
186
|
+
*/
|
|
187
|
+
willUpdate() {
|
|
188
|
+
if (!this.zoomed)
|
|
189
|
+
return;
|
|
190
|
+
if (this.effectiveType() !== this.builtType) {
|
|
191
|
+
this.zoomed = false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
140
194
|
updated(changed) {
|
|
141
195
|
// Disconnected between the property change that scheduled this update
|
|
142
196
|
// and Lit's (microtask-deferred) processing of it — e.g. a property
|
|
@@ -186,15 +240,27 @@ export class LyraChart extends LyraElement {
|
|
|
186
240
|
this.draw();
|
|
187
241
|
});
|
|
188
242
|
}
|
|
189
|
-
const
|
|
190
|
-
|
|
243
|
+
const contentChanged = [
|
|
244
|
+
'type',
|
|
245
|
+
'labels',
|
|
246
|
+
'datasets',
|
|
247
|
+
'legend',
|
|
248
|
+
'area',
|
|
249
|
+
'height',
|
|
250
|
+
'xLabel',
|
|
251
|
+
'yLabel',
|
|
252
|
+
'y2Label',
|
|
253
|
+
'beginAtZero',
|
|
254
|
+
'horizontal',
|
|
255
|
+
'stacked',
|
|
256
|
+
'config',
|
|
257
|
+
'zoom',
|
|
258
|
+
'loading',
|
|
259
|
+
].some((name) => changed.has(name));
|
|
260
|
+
if (!contentChanged)
|
|
191
261
|
return;
|
|
192
262
|
if (!this.visible)
|
|
193
263
|
return; // becoming visible again triggers its own draw() via the observer above
|
|
194
|
-
const signature = this.computeSignature();
|
|
195
|
-
if (signature === this.lastSignature)
|
|
196
|
-
return;
|
|
197
|
-
this.lastSignature = signature;
|
|
198
264
|
this.draw();
|
|
199
265
|
}
|
|
200
266
|
seriesToDataset(s) {
|
|
@@ -244,29 +310,6 @@ export class LyraChart extends LyraElement {
|
|
|
244
310
|
tooltipText: cs.getPropertyValue('--lyra-chart-tooltip-text').trim() || FALLBACK_TOOLTIP_TEXT,
|
|
245
311
|
};
|
|
246
312
|
}
|
|
247
|
-
/**
|
|
248
|
-
* A content-affecting-properties fingerprint used by `updated()` to skip a
|
|
249
|
-
* redundant `draw()` when neither visibility nor any of these properties
|
|
250
|
-
* actually changed since the last draw (e.g. an unrelated property/state
|
|
251
|
-
* update, or `requestUpdate()` with nothing changed). Mirrors
|
|
252
|
-
* `lite-chart.ts`'s `computeSignature()`.
|
|
253
|
-
*/
|
|
254
|
-
computeSignature() {
|
|
255
|
-
return JSON.stringify([
|
|
256
|
-
this.type,
|
|
257
|
-
this.labels,
|
|
258
|
-
this.datasets,
|
|
259
|
-
this.legend,
|
|
260
|
-
this.area,
|
|
261
|
-
this.xLabel,
|
|
262
|
-
this.yLabel,
|
|
263
|
-
this.y2Label,
|
|
264
|
-
this.beginAtZero,
|
|
265
|
-
this.horizontal,
|
|
266
|
-
this.stacked,
|
|
267
|
-
this.config,
|
|
268
|
-
]);
|
|
269
|
-
}
|
|
270
313
|
/**
|
|
271
314
|
* Builds `options.scales` for the effective chart type: no scale at all for
|
|
272
315
|
* pie/doughnut (a proportional-area chart has no axis), the single radial
|
|
@@ -352,6 +395,17 @@ export class LyraChart extends LyraElement {
|
|
|
352
395
|
const value = chart.data.datasets[datasetIndex]?.data?.[index] ?? null;
|
|
353
396
|
this.emit('lyra-point-click', { datasetIndex, index, label, value });
|
|
354
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* `config.type` (if set) overrides the attribute `type` post-merge — this
|
|
400
|
+
* is the one place that resolution logic lives, shared by `buildConfig()`
|
|
401
|
+
* (which needs it to build scales/interaction for the right type) and
|
|
402
|
+
* `willUpdate()` (which needs it to detect a type change against the last
|
|
403
|
+
* *actually built* type, `this.builtType`, before the render pass that
|
|
404
|
+
* would rebuild the `Chart` instance).
|
|
405
|
+
*/
|
|
406
|
+
effectiveType() {
|
|
407
|
+
return (this.config?.type ?? normalizeChartType(this.type));
|
|
408
|
+
}
|
|
355
409
|
buildConfig() {
|
|
356
410
|
const theme = this.themeColors();
|
|
357
411
|
// Resolve the effective type up front: `config.type` (if set) overrides
|
|
@@ -359,8 +413,7 @@ export class LyraChart extends LyraElement {
|
|
|
359
413
|
// for *that* type, not `this.type` — otherwise a config.type override
|
|
360
414
|
// (e.g. line -> radar) ships with the wrong axis shape (categorical x/y
|
|
361
415
|
// instead of a radial r scale).
|
|
362
|
-
const effectiveType = this.
|
|
363
|
-
this.type;
|
|
416
|
+
const effectiveType = this.effectiveType();
|
|
364
417
|
const generated = {
|
|
365
418
|
type: effectiveType,
|
|
366
419
|
data: {
|
|
@@ -463,6 +516,56 @@ export class LyraChart extends LyraElement {
|
|
|
463
516
|
refreshTheme() {
|
|
464
517
|
this.draw();
|
|
465
518
|
}
|
|
519
|
+
seriesValues(series) {
|
|
520
|
+
if (series.points)
|
|
521
|
+
return series.points.map((point) => point.y).filter((value) => Number.isFinite(value));
|
|
522
|
+
return (series.data ?? []).filter((value) => value != null && Number.isFinite(value));
|
|
523
|
+
}
|
|
524
|
+
chartDescription() {
|
|
525
|
+
if (this.accessibleDescription)
|
|
526
|
+
return this.accessibleDescription;
|
|
527
|
+
const summaries = this.datasets.map((series) => {
|
|
528
|
+
const values = this.seriesValues(series);
|
|
529
|
+
if (!values.length)
|
|
530
|
+
return `${series.label}: no data`;
|
|
531
|
+
const first = values[0];
|
|
532
|
+
const last = values[values.length - 1];
|
|
533
|
+
const trend = last > first ? 'increasing' : last < first ? 'decreasing' : 'flat';
|
|
534
|
+
let min = values[0];
|
|
535
|
+
let max = values[0];
|
|
536
|
+
for (const value of values) {
|
|
537
|
+
min = Math.min(min, value);
|
|
538
|
+
max = Math.max(max, value);
|
|
539
|
+
}
|
|
540
|
+
return `${series.label}: ${values.length} values, range ${min} to ${max}, ${trend} trend`;
|
|
541
|
+
});
|
|
542
|
+
return `${this.effectiveType()} chart${summaries.length ? `. ${summaries.join('. ')}` : ' with no data'}.`;
|
|
543
|
+
}
|
|
544
|
+
renderDataTable() {
|
|
545
|
+
const rowCount = Math.max(this.labels.length, ...this.datasets.map((series) => (series.points ? series.points.length : series.data?.length ?? 0)), 0);
|
|
546
|
+
return html `
|
|
547
|
+
<table class=${this.showDataTable ? nothing : 'sr-only'}>
|
|
548
|
+
<caption>${this.accessibleLabel || 'Chart data'}</caption>
|
|
549
|
+
<thead>
|
|
550
|
+
<tr>
|
|
551
|
+
<th scope="col">Category</th>
|
|
552
|
+
${this.datasets.map((series) => html `<th scope="col">${series.label}</th>`)}
|
|
553
|
+
</tr>
|
|
554
|
+
</thead>
|
|
555
|
+
<tbody>
|
|
556
|
+
${Array.from({ length: rowCount }, (_, index) => html `
|
|
557
|
+
<tr>
|
|
558
|
+
<th scope="row">${this.labels[index] ?? `Point ${index + 1}`}</th>
|
|
559
|
+
${this.datasets.map((series) => {
|
|
560
|
+
const value = series.points ? series.points[index]?.y : series.data?.[index];
|
|
561
|
+
return html `<td>${value == null || !Number.isFinite(value) ? 'No data' : value}</td>`;
|
|
562
|
+
})}
|
|
563
|
+
</tr>
|
|
564
|
+
`)}
|
|
565
|
+
</tbody>
|
|
566
|
+
</table>
|
|
567
|
+
`;
|
|
568
|
+
}
|
|
466
569
|
render() {
|
|
467
570
|
if (this.loading) {
|
|
468
571
|
return html `
|
|
@@ -471,10 +574,16 @@ export class LyraChart extends LyraElement {
|
|
|
471
574
|
</div>
|
|
472
575
|
`;
|
|
473
576
|
}
|
|
474
|
-
const label = this.datasets.map((d) => d.label).join(', ') || 'Chart';
|
|
577
|
+
const label = this.accessibleLabel || this.datasets.map((d) => d.label).join(', ') || 'Chart';
|
|
578
|
+
const description = this.chartDescription();
|
|
475
579
|
return html `
|
|
476
580
|
<div part="base">
|
|
477
|
-
<canvas part="canvas" role="img" aria-label=${label}></canvas>
|
|
581
|
+
<canvas part="canvas" role="img" aria-label=${label} aria-describedby=${this.descriptionId}></canvas>
|
|
582
|
+
<p part="description" id=${this.descriptionId} class="sr-only">${description}</p>
|
|
583
|
+
<div part="data-table">
|
|
584
|
+
<slot name="data-table"></slot>
|
|
585
|
+
${this.renderDataTable()}
|
|
586
|
+
</div>
|
|
478
587
|
${this.zoom && this.zoomed
|
|
479
588
|
? html `<button part="reset-zoom-button" type="button" @click=${() => this.resetZoom()}>
|
|
480
589
|
Reset zoom
|
|
@@ -485,7 +594,7 @@ export class LyraChart extends LyraElement {
|
|
|
485
594
|
}
|
|
486
595
|
}
|
|
487
596
|
__decorate([
|
|
488
|
-
property()
|
|
597
|
+
property({ converter: { fromAttribute: (value) => normalizeChartType(value) } })
|
|
489
598
|
], LyraChart.prototype, "type", void 0);
|
|
490
599
|
__decorate([
|
|
491
600
|
property({ attribute: false })
|
|
@@ -517,6 +626,15 @@ __decorate([
|
|
|
517
626
|
__decorate([
|
|
518
627
|
property({ type: Boolean, attribute: 'begin-at-zero' })
|
|
519
628
|
], LyraChart.prototype, "beginAtZero", void 0);
|
|
629
|
+
__decorate([
|
|
630
|
+
property({ attribute: 'accessible-label' })
|
|
631
|
+
], LyraChart.prototype, "accessibleLabel", void 0);
|
|
632
|
+
__decorate([
|
|
633
|
+
property({ attribute: 'accessible-description' })
|
|
634
|
+
], LyraChart.prototype, "accessibleDescription", void 0);
|
|
635
|
+
__decorate([
|
|
636
|
+
property({ type: Boolean, attribute: 'show-data-table' })
|
|
637
|
+
], LyraChart.prototype, "showDataTable", void 0);
|
|
520
638
|
__decorate([
|
|
521
639
|
property({ type: Boolean })
|
|
522
640
|
], LyraChart.prototype, "horizontal", void 0);
|
|
@@ -539,3 +657,28 @@ __decorate([
|
|
|
539
657
|
query('canvas')
|
|
540
658
|
], LyraChart.prototype, "canvasEl", void 0);
|
|
541
659
|
defineElement('chart', LyraChart);
|
|
660
|
+
/**
|
|
661
|
+
* Installs a read-only `type` accessor pair on a `LyraChart` subclass's
|
|
662
|
+
* prototype, locking it to `value` — assigning `.type` afterwards (attribute
|
|
663
|
+
* or property) is silently ignored. `LyraChart` declares `type` as a plain
|
|
664
|
+
* (decorator-managed) class field, and TypeScript forbids a subclass from
|
|
665
|
+
* re-declaring a base field as a getter/setter pair via ordinary class
|
|
666
|
+
* syntax (TS2611), so the accessor pair is installed directly on the
|
|
667
|
+
* prototype instead, which is runtime-equivalent (same shadowing semantics
|
|
668
|
+
* as a class-syntax override) without tripping that check. Shared by every
|
|
669
|
+
* `lyra-*-chart` subclass (bar/line/pie/doughnut/scatter/bubble/radar/
|
|
670
|
+
* polarArea) plus `lyra-histogram`, replacing what used to be an identical
|
|
671
|
+
* ~16-line `Object.defineProperty` block copy-pasted into each file.
|
|
672
|
+
*/
|
|
673
|
+
export function lockChartType(ctor, value) {
|
|
674
|
+
Object.defineProperty(ctor.prototype, 'type', {
|
|
675
|
+
configurable: true,
|
|
676
|
+
enumerable: true,
|
|
677
|
+
get() {
|
|
678
|
+
return value;
|
|
679
|
+
},
|
|
680
|
+
set(_v) {
|
|
681
|
+
/* locked to `value`; direct writes are ignored */
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LyraChart } from './chart.js';
|
|
1
|
+
import { LyraChart, lockChartType } from './chart.js';
|
|
2
2
|
import { defineElement } from '../../internal/prefix.js';
|
|
3
3
|
/**
|
|
4
4
|
* `<lyra-doughnut-chart>` — `<lyra-chart>` with `type` locked to `"doughnut"`.
|
|
@@ -7,21 +7,5 @@ import { defineElement } from '../../internal/prefix.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export class LyraDoughnutChart extends LyraChart {
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
// default value — `LyraChart` declares it as a plain (decorator-managed)
|
|
12
|
-
// class field, and TypeScript forbids a subclass from re-declaring a base
|
|
13
|
-
// field as a getter/setter pair via ordinary class syntax (TS2611) — so the
|
|
14
|
-
// accessor pair is installed directly on the prototype instead, which is
|
|
15
|
-
// runtime-equivalent (same shadowing semantics as a class-syntax override)
|
|
16
|
-
// without tripping that check.
|
|
17
|
-
Object.defineProperty(LyraDoughnutChart.prototype, 'type', {
|
|
18
|
-
configurable: true,
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get() {
|
|
21
|
-
return 'doughnut';
|
|
22
|
-
},
|
|
23
|
-
set(_v) {
|
|
24
|
-
/* locked to 'doughnut'; direct writes are ignored */
|
|
25
|
-
},
|
|
26
|
-
});
|
|
10
|
+
lockChartType(LyraDoughnutChart, 'doughnut');
|
|
27
11
|
defineElement('doughnut-chart', LyraDoughnutChart);
|
|
@@ -2,8 +2,11 @@ export interface HistogramBucket {
|
|
|
2
2
|
label: string;
|
|
3
3
|
count: number;
|
|
4
4
|
}
|
|
5
|
+
export declare const MAX_HISTOGRAM_BINS = 1000;
|
|
6
|
+
/** Converts an untyped bucket count to a bounded, non-negative integer. */
|
|
7
|
+
export declare function normalizeHistogramBinCount(binCount: unknown): number;
|
|
5
8
|
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
6
9
|
* Non-finite `binCount` (or <= 0) yields no buckets; a fractional `binCount`
|
|
7
|
-
* is floored; non-finite samples in
|
|
8
|
-
* corrupting bucket-index math. */
|
|
10
|
+
* is floored and an excessive count is capped; non-finite samples in
|
|
11
|
+
* `values` are dropped rather than corrupting bucket-index math. */
|
|
9
12
|
export declare function binValues(values: number[], binCount: number): HistogramBucket[];
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
export const MAX_HISTOGRAM_BINS = 1_000;
|
|
2
|
+
/** Converts an untyped bucket count to a bounded, non-negative integer. */
|
|
3
|
+
export function normalizeHistogramBinCount(binCount) {
|
|
4
|
+
const numeric = typeof binCount === 'number' ? binCount : Number(binCount);
|
|
5
|
+
if (!Number.isFinite(numeric))
|
|
6
|
+
return 0;
|
|
7
|
+
return Math.min(MAX_HISTOGRAM_BINS, Math.max(0, Math.floor(numeric)));
|
|
8
|
+
}
|
|
1
9
|
/** Splits `values` into `binCount` equal-width buckets and counts membership.
|
|
2
10
|
* Non-finite `binCount` (or <= 0) yields no buckets; a fractional `binCount`
|
|
3
|
-
* is floored; non-finite samples in
|
|
4
|
-
* corrupting bucket-index math. */
|
|
11
|
+
* is floored and an excessive count is capped; non-finite samples in
|
|
12
|
+
* `values` are dropped rather than corrupting bucket-index math. */
|
|
5
13
|
export function binValues(values, binCount) {
|
|
6
14
|
const finite = values.filter((v) => Number.isFinite(v));
|
|
7
|
-
if (finite.length === 0
|
|
15
|
+
if (finite.length === 0)
|
|
8
16
|
return [];
|
|
9
|
-
const bins =
|
|
17
|
+
const bins = normalizeHistogramBinCount(binCount);
|
|
10
18
|
if (bins <= 0)
|
|
11
19
|
return [];
|
|
12
20
|
let lo = finite[0];
|
|
@@ -5,10 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { property } from 'lit/decorators.js';
|
|
8
|
-
import { LyraChart } from './chart.js';
|
|
8
|
+
import { LyraChart, lockChartType } from './chart.js';
|
|
9
9
|
import { LyraElement } from '../../internal/lyra-element.js';
|
|
10
10
|
import { defineElement } from '../../internal/prefix.js';
|
|
11
|
-
import { binValues } from './histogram-bin.js';
|
|
11
|
+
import { binValues, normalizeHistogramBinCount, } from './histogram-bin.js';
|
|
12
12
|
import { styles } from './histogram.styles.js';
|
|
13
13
|
/**
|
|
14
14
|
* `<lyra-histogram>` — bins `values` into `bins` equal-width buckets and
|
|
@@ -32,7 +32,7 @@ export class LyraHistogram extends LyraChart {
|
|
|
32
32
|
static { this.styles = [LyraElement.styles, styles]; }
|
|
33
33
|
}
|
|
34
34
|
__decorate([
|
|
35
|
-
property({
|
|
35
|
+
property({ converter: { fromAttribute: (value) => normalizeHistogramBinCount(value) } })
|
|
36
36
|
], LyraHistogram.prototype, "bins", void 0);
|
|
37
37
|
__decorate([
|
|
38
38
|
property({ attribute: false })
|
|
@@ -48,12 +48,13 @@ __decorate([
|
|
|
48
48
|
// change doesn't re-run the O(n) bucketing loop from scratch on every access.
|
|
49
49
|
const bucketCache = new WeakMap();
|
|
50
50
|
export function binnedBuckets(el) {
|
|
51
|
+
const bins = normalizeHistogramBinCount(el.bins);
|
|
51
52
|
const cached = bucketCache.get(el);
|
|
52
|
-
if (cached && cached.values === el.values && cached.bins ===
|
|
53
|
+
if (cached && cached.values === el.values && cached.bins === bins) {
|
|
53
54
|
return cached.buckets;
|
|
54
55
|
}
|
|
55
|
-
const buckets = binValues(el.values,
|
|
56
|
-
bucketCache.set(el, { values: el.values, bins
|
|
56
|
+
const buckets = binValues(el.values, bins);
|
|
57
|
+
bucketCache.set(el, { values: el.values, bins, buckets });
|
|
57
58
|
return buckets;
|
|
58
59
|
}
|
|
59
60
|
// `labels`/`datasets` are computed from `values`/`bins` rather than settable
|
|
@@ -87,14 +88,5 @@ Object.defineProperty(LyraHistogram.prototype, 'datasets', {
|
|
|
87
88
|
// just a default value, not an enforced lock, so without this a `type="line"`
|
|
88
89
|
// attribute (or `el.type = 'line'`) would silently turn a histogram into a
|
|
89
90
|
// line chart of its own bucket counts.
|
|
90
|
-
|
|
91
|
-
configurable: true,
|
|
92
|
-
enumerable: true,
|
|
93
|
-
get() {
|
|
94
|
-
return 'bar';
|
|
95
|
-
},
|
|
96
|
-
set(_v) {
|
|
97
|
-
/* locked to 'bar'; direct writes are ignored */
|
|
98
|
-
},
|
|
99
|
-
});
|
|
91
|
+
lockChartType(LyraHistogram, 'bar');
|
|
100
92
|
defineElement('histogram', LyraHistogram);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LyraChart } from './chart.js';
|
|
1
|
+
import { LyraChart, lockChartType } from './chart.js';
|
|
2
2
|
import { defineElement } from '../../internal/prefix.js';
|
|
3
3
|
/**
|
|
4
4
|
* `<lyra-line-chart>` — `<lyra-chart>` with `type` locked to `"line"`.
|
|
@@ -7,21 +7,5 @@ import { defineElement } from '../../internal/prefix.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export class LyraLineChart extends LyraChart {
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
// default value — `LyraChart` declares it as a plain (decorator-managed)
|
|
12
|
-
// class field, and TypeScript forbids a subclass from re-declaring a base
|
|
13
|
-
// field as a getter/setter pair via ordinary class syntax (TS2611) — so the
|
|
14
|
-
// accessor pair is installed directly on the prototype instead, which is
|
|
15
|
-
// runtime-equivalent (same shadowing semantics as a class-syntax override)
|
|
16
|
-
// without tripping that check.
|
|
17
|
-
Object.defineProperty(LyraLineChart.prototype, 'type', {
|
|
18
|
-
configurable: true,
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get() {
|
|
21
|
-
return 'line';
|
|
22
|
-
},
|
|
23
|
-
set(_v) {
|
|
24
|
-
/* locked to 'line'; direct writes are ignored */
|
|
25
|
-
},
|
|
26
|
-
});
|
|
10
|
+
lockChartType(LyraLineChart, 'line');
|
|
27
11
|
defineElement('line-chart', LyraLineChart);
|
|
@@ -40,6 +40,22 @@ export type LyraLiteChartLayout = 'fit' | 'scroll';
|
|
|
40
40
|
* calendar columns — overriding the internal slot math for both bars and
|
|
41
41
|
* their labels. All three are additive and no-ops when left unset.
|
|
42
42
|
*
|
|
43
|
+
* Seven further additive, opt-in properties: `pointText` overrides the
|
|
44
|
+
* per-bar/per-point `<title>`/`aria-label` tooltip text (mirrors
|
|
45
|
+
* `lyra-heatmap`'s `cellText` hook), falling back to the built-in raw-value
|
|
46
|
+
* template when unset; `roundedBars` draws bars as a rounded-top path
|
|
47
|
+
* instead of a square-cornered rect; `skipZero` omits a bar entirely (not
|
|
48
|
+
* just zero-height) for an exactly-`0` value; `padLeft`/`barGapRatio`
|
|
49
|
+
* override the internal `PAD_LEFT`/`BAR_GROUP_GAP` layout constants; `scale`
|
|
50
|
+
* (`type="bar"` only) switches the bar-height mapping from the default
|
|
51
|
+
* linear `niceDomain` fraction to a `Math.sqrt(value / domainMax)`
|
|
52
|
+
* compression (mirroring `lyra-heatmap`'s matrix-mode `sqrt` scale) so a
|
|
53
|
+
* skewed dataset's smaller bars don't get washed out by one dominant value
|
|
54
|
+
* — gridlines/tick labels stay on the linear domain regardless, only the bar
|
|
55
|
+
* marks' own height changes, and `type="line"` ignores `scale` entirely; and
|
|
56
|
+
* `hideAxis` suppresses `renderGrid()`'s gridlines/tick labels altogether
|
|
57
|
+
* (x-axis category labels, rendered separately, are unaffected).
|
|
58
|
+
*
|
|
43
59
|
* @customElement lyra-lite-chart
|
|
44
60
|
* @event lyra-point-click - Fired when a bar/point is activated (click, or
|
|
45
61
|
* Enter/Space while focused). `detail: { datasetIndex: number, index:
|
|
@@ -55,6 +71,8 @@ export type LyraLiteChartLayout = 'fit' | 'scroll';
|
|
|
55
71
|
* @csspart legend - The legend row, when `legend` is set.
|
|
56
72
|
* @csspart legend-item - Each legend entry.
|
|
57
73
|
* @csspart legend-swatch - Each legend entry's color swatch.
|
|
74
|
+
* @csspart live-region - The current mark announcement for keyboard users.
|
|
75
|
+
* @csspart data-list - A visually hidden list of all plotted data points.
|
|
58
76
|
*/
|
|
59
77
|
export declare class LyraLiteChart extends LyraElement {
|
|
60
78
|
static styles: import("lit").CSSResultGroup[];
|
|
@@ -92,21 +110,80 @@ export declare class LyraLiteChart extends LyraElement {
|
|
|
92
110
|
* coordinate function. Unset (the default) uses the existing internal per-category slot math,
|
|
93
111
|
* unchanged from before this property existed. */
|
|
94
112
|
barX?: (index: number) => number;
|
|
113
|
+
/** Formats the per-bar/per-point `<title>`/`aria-label` tooltip text — receives the category
|
|
114
|
+
* label, the raw value, and the dataset index. Falls back to the built-in raw-value template
|
|
115
|
+
* when unset (mirrors `lyra-heatmap`'s `cellText` hook). */
|
|
116
|
+
pointText?: (label: string, value: number, datasetIndex: number) => string;
|
|
117
|
+
/** `type="bar"` only: draws each bar as a rounded-top-corner shape instead of the default
|
|
118
|
+
* square-cornered rect. Default `false` renders exactly today's plain `<rect>`. */
|
|
119
|
+
roundedBars: boolean;
|
|
120
|
+
/** `type="bar"` only: omits a bar entirely (no mark, no `tabindex`, no tooltip) for a value that
|
|
121
|
+
* is exactly `0` — `null`/non-finite values are always skipped regardless of this flag. Default
|
|
122
|
+
* `false` preserves today's behavior of a zero-height but focusable/titled bar. */
|
|
123
|
+
skipZero: boolean;
|
|
124
|
+
/** Overrides the internal `PAD_LEFT` (36px) plot-left-padding constant. Unset (the default) keeps
|
|
125
|
+
* today's fixed 36px. */
|
|
126
|
+
padLeft?: number;
|
|
127
|
+
/** Overrides the internal `BAR_GROUP_GAP` (0.2) fraction of a category slot left as a gap between
|
|
128
|
+
* categories. Unset (the default) keeps today's fixed 0.2. */
|
|
129
|
+
barGapRatio?: number;
|
|
130
|
+
/** `type="bar"` only (no effect on `type="line"`): `'linear'` (default) maps a bar's value to
|
|
131
|
+
* height via the standard `niceDomain`-based fraction, unchanged from before this property
|
|
132
|
+
* existed. `'sqrt'` instead maps via `Math.sqrt(value / domainMax)` (mirroring `lyra-heatmap`'s
|
|
133
|
+
* matrix-mode `sqrt` scale), boosting smaller values relative to one dominant value so a skewed
|
|
134
|
+
* dataset's smaller bars don't get washed out. Gridlines/tick labels stay on the linear domain
|
|
135
|
+
* either way — only the bar marks' own height mapping changes. */
|
|
136
|
+
scale: 'linear' | 'sqrt';
|
|
137
|
+
/** Suppresses `renderGrid()` entirely — no gridlines, no y-axis tick labels. x-axis category
|
|
138
|
+
* labels (rendered separately) are unaffected. Default `false` preserves today's behavior. */
|
|
139
|
+
hideAxis: boolean;
|
|
95
140
|
private plotWidth;
|
|
96
141
|
private plotHeight;
|
|
97
142
|
private visible;
|
|
143
|
+
/** One roving tab stop across all bar/point marks. */
|
|
144
|
+
private activeMarkIndex;
|
|
145
|
+
private liveText;
|
|
98
146
|
private svgEl?;
|
|
99
147
|
private resizeObserver?;
|
|
100
148
|
private intersectionObserver?;
|
|
101
|
-
private lastSignature;
|
|
102
|
-
private lastResult?;
|
|
103
149
|
connectedCallback(): void;
|
|
104
150
|
disconnectedCallback(): void;
|
|
105
151
|
protected firstUpdated(): void;
|
|
106
152
|
protected updated(changed: PropertyValues): void;
|
|
107
153
|
private colorFor;
|
|
154
|
+
/** Dispatches to the host-provided `pointText` formatter when set, otherwise `undefined` (the
|
|
155
|
+
* caller falls back to its own built-in template) — mirrors `lyra-heatmap`'s `resolveCellText()`. */
|
|
156
|
+
private resolvePointText;
|
|
157
|
+
/** The ordered set of visible marks used by both keyboard navigation and
|
|
158
|
+
* the screen-reader data alternative. */
|
|
159
|
+
private interactiveMarks;
|
|
160
|
+
private markIndexMap;
|
|
161
|
+
private normalizedMarkIndex;
|
|
162
|
+
private markAnnouncement;
|
|
163
|
+
private onMarkFocus;
|
|
164
|
+
private focusMark;
|
|
165
|
+
/**
|
|
166
|
+
* A value-to-y-pixel mapping for a bar's top/bottom edge. `'linear'` (the
|
|
167
|
+
* default) is the standard `niceDomain`-fraction formula, unchanged from
|
|
168
|
+
* before `scale` existed. `'sqrt'` instead compresses via
|
|
169
|
+
* `Math.sqrt(value / domainMax)` (mirroring `lyra-heatmap`'s matrix-mode
|
|
170
|
+
* `sqrt` branch), clamping `value` to `[0, hi]` first since a negative
|
|
171
|
+
* input has no real square root — bar charts using `scale="sqrt"` are
|
|
172
|
+
* expected to carry non-negative data, same assumption as the heatmap
|
|
173
|
+
* precedent this mirrors.
|
|
174
|
+
*/
|
|
175
|
+
private barValueToY;
|
|
176
|
+
/**
|
|
177
|
+
* A rounded-top-corners `<path>` `d` string for a bar occupying
|
|
178
|
+
* `[x, y, x+w, y+h]` — an SVG `<rect>` can only express a uniform radius
|
|
179
|
+
* on all four corners, so `roundedBars` switches the mark to a path
|
|
180
|
+
* instead of adding `rx`/`ry` to keep the bottom edge square against the
|
|
181
|
+
* baseline. `r` is clamped so it never exceeds half the bar's width or its
|
|
182
|
+
* full height (a thin/short bar degrades to a plain rectangle path rather
|
|
183
|
+
* than self-intersecting).
|
|
184
|
+
*/
|
|
185
|
+
private roundedBarPath;
|
|
108
186
|
private domain;
|
|
109
|
-
private computeSignature;
|
|
110
187
|
private emitPoint;
|
|
111
188
|
private onPointKeyDown;
|
|
112
189
|
private renderGrid;
|