import{type TemplateResult,type PropertyValues}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';import'../../overlays/skeleton/skeleton.class.js';import type{LyraVariant}from'../../../internal/variants.js';import{type LyraChartLegendVisibilityChangeDetail,type LyraChartDatumVisibilityChangeDetail}from'./chart-legend-visibility.js';export type{LyraChartLegendVisibilityChangeDetail,LyraChartDatumVisibilityChangeDetail}from'./chart-legend-visibility.js';export{seriesPalette}from'./chart-colors.js';export interface LyraChartPoint{readonly x:number;readonly y:number; /** Bubble radius. Ignored by chart types that do not consume a radius. */ readonly r?:number; /** * Caller-owned per-point label retained verbatim by events/export and interpolated into the * localized whole-point message used by descriptions, tables, and keyboard announcements. */ readonly label?:string;}export interface LyraChartSeries{readonly label:string;readonly data?:readonly(number|null)[];readonly points?:readonly LyraChartPoint[];readonly color?:string|readonly string[];readonly fill?:boolean;readonly width?:number;readonly dash?:boolean;readonly noTooltip?:boolean;readonly axis?:'y'|'y2'; /** * Chart.js dataset `stack` group id. Series sharing the same `stack` value on the same axis * accumulate into one stack; a different id starts an independent stack that Chart.js draws * side by side with the first on that same (stacked) axis. Omitted series default to Chart.js's * own ungrouped stack, matching every series's behavior before this existed. Only meaningful on * an axis that is actually stacked -- see `LyraChart.stacked`/`LyraChart.stackedAxes`. */ readonly stack?:string;readonly pointColors?:readonly string[]; /** * Per-point radius. A single number applies to every point; an array (matching `data`'s * length) sets each point independently — passed straight through to Chart.js, which * supports both natively. */ readonly pointRadius?:number|readonly number[]; /** * Per-segment (the line between two consecutive points) border color, indexed by the * *starting* point of each segment — e.g. `['red', 'green']` on 3 points colors the first * segment red and the second green. Wired to Chart.js's `segment.borderColor`, and cycled * when shorter than the segment count. Sampled segments retain the original source starting * point's palette index. Only meaningful for line-type series. */ readonly segmentColors?:readonly string[];readonly type?:'line'|'bar';}export type LyraChartType='line'|'bar'|'scatter'|'pie'|'doughnut'|'radar'|'polarArea'|'bubble';export type LyraChartGrid='x'|'y'|'both'|'none'; /** Complete cartesian axes, including their ticks, labels, borders and grid lines. */ export type LyraChartAxes=LyraChartGrid;export type LyraChartIndexAxis='x'|'y'; /** Scale type for a chart's value axis. The categorical axis is never affected. */ export type LyraChartScaleType='linear'|'logarithmic'; /** * One declarative chart annotation: a reference line (`value`) or a shaded band (`from`/`to`) on * the named axis. * * `value` and `from`/`to` are mutually exclusive; an entry supplying neither, or non-finite * numbers, is dropped rather than handed to Chart.js, where it would silently render nothing or * throw. `axis` defaults to `'y'`, the value axis for the common threshold case. */ export interface LyraChartAnnotation{readonly axis?:LyraChartIndexAxis;readonly value?:number;readonly from?:number;readonly to?:number;readonly label?:string;readonly tone?:LyraVariant;}export type LyraChartLayoutPosition='left'|'top'|'right'|'bottom'|'center'|'chartArea'|{[scaleId:string]:number;};export type LyraChartLegendPosition=LyraChartLayoutPosition|'start'|'end'|'auto'; /** Dataset toggles, or shared category toggles for pie/doughnut/polar-area charts. */ export type LyraChartLegendMode='auto'|'dataset'|'datum'; /** Text shown in the DOM legend, independently of tooltip and axis formatting. */ export type LyraChartLegendDisplay='auto'|'label'|'value'|'percentage'|'value-percentage';export type LyraChartValueFormatterContext='tick'|'tooltip'|'legend'|'table';export type LyraChartValueFormatter=(value:number,context:LyraChartValueFormatterContext)=>string;export type LyraChartFormatSurface=LyraChartValueFormatterContext|'visual'|'spoken'|'export'; /** Identifies which numeric component of a structured datum the formatter receives. */ export type LyraChartStatistic='x'|'y'|'r'|'min'|'q1'|'median'|'q3'|'max'|'total'; /** * The scale a formatted number belongs to: the two cartesian value axes (`y`, and `y2` for a * `LyraChartSeries.axis: 'y2'` series), the `x` scale wherever it carries numbers rather than * categories (scatter/bubble, and a horizontal bar/line), and the single radial `r` scale of a * radar/polar-area chart. `undefined` where there is no axis at all -- a pie/doughnut slice, or a * surface whose value is not bound to one scale. */ export type LyraChartFormatterAxis='x'|'y'|'y2'|'r';export interface LyraChartFormatterContext{readonly value:number;readonly surface:LyraChartFormatSurface;readonly datasetIndex?:number;readonly index?:number;readonly label?:string;readonly seriesLabel?:string;readonly statistic?:LyraChartStatistic; /** * Which scale this number is plotted against. Two axes usually exist precisely because they * carry different units, so without it one formatter cannot render a secondary axis correctly -- * the gap that forced dual-axis and scatter charts onto the raw `config` tick callback, which * bypasses this formatter and so drops the same unit text from the data table, the CSV export and * the spoken announcement. */ readonly axis?:LyraChartFormatterAxis; /** * This entry's share of the represented `surface: 'legend'` total, as a fraction in `[0, 1]` * (`0.5` is 50%) -- present only on that surface, so a `legendDisplay: 'value'` or * `'value-percentage'` formatter can render a share without recomputing it from raw data. There * is no accompanying `total`: internally the sum is computed in a per-entry rescaled coordinate * system for numeric stability with datasets whose finite values sum beyond * `Number.MAX_VALUE`, so it has no fixed public unit -- `percentage` alone is stable regardless. */ readonly percentage?:number;}export type LyraChartFormatter=(context:LyraChartFormatterContext)=>string; /** * Tooltip title/footer formatter. Chart.js calls its own `title`/`footer` tooltip callbacks once * per tooltip render against every hovered item, not once per item like the label path -- so * unlike `LyraChartFormatter`, this receives every hovered item's context at once, each in the * same `LyraChartFormatterContext` shape `formatter`'s `'tooltip'` surface already produces (one * entry per dataset the tooltip covers, e.g. every stacked series sharing the hovered category). * The property itself being unset -- not the formatter's return value -- is what leaves Chart.js's * own default title (the shared category label) or default footer (none) in place. */ export type LyraChartTooltipGroupFormatter=(items:readonly LyraChartFormatterContext[])=>string;export type LyraChartExportFormat='csv'|'png';export interface LyraChartArea{readonly top:number;readonly left:number;readonly right:number;readonly bottom:number;readonly width:number;readonly height:number;} /** A Chart.js-compatible plugin shape without making `chart.js` a type dependency for consumers. */ export interface LyraChartPlugin{readonly id:string;} /** Dataset configuration accepted by the raw `config` passthrough. */ export interface LyraChartDatasetConfiguration{type?:string;label?:unknown;data?:unknown[];hidden?:boolean;axis?:string;yAxisID?:string;stack?:string;noTooltip?:boolean;fill?:unknown;backgroundColor?:unknown;borderColor?:unknown;borderRadius?:unknown;borderWidth?:unknown;borderDash?:unknown;color?:unknown;pointStyle?:unknown;pointBackgroundColor?:unknown;pointRadius?:unknown;segment?:unknown;} /** Data block accepted by the raw `config` passthrough. */ export interface LyraChartDataConfiguration{labels?:unknown[];datasets?:LyraChartDatasetConfiguration[];} /** * Peer-neutral structural configuration accepted by `LyraChart.config`. * Install `chart.js` and use its own `ChartConfiguration` type when stricter * controller-specific checking is useful; that type remains structurally * assignable to this passthrough surface. */ export interface LyraChartConfiguration{type?:string;data?:LyraChartDataConfiguration;options?:object;plugins?:LyraChartPlugin[];} /** A single Chart.js hit-test result, as returned by `LyraChartInstance.getElementsAtEventForMode()`. * Exported so the documented `LyraChartInstance` reference (`llms/charts.md`) names a real, * importable symbol instead of an inaccessible internal interface. */ interface ChartHit{datasetIndex:number;index:number;} /** Structural shape of a live Chart.js instance, without imposing `chart.js` as a type dependency * on consumers. Exported so `LyraChartInstance`'s documented `extends RuntimeChart` reference * names a real, importable symbol. */ interface RuntimeChart{data:{labels?:unknown[];datasets:LyraChartDatasetConfiguration[];};options:Record;config:{type?:unknown;};legend?:unknown;chartArea?:LyraChartArea;destroy():void;update(mode?:string):void;toBase64Image?():string;getElementsAtEventForMode(event:Event,mode:string,options:Record,useFinalPosition:boolean):ChartHit[];getDatasetMeta?(index:number):{hidden:boolean|null;};isDatasetVisible(index:number):boolean;setDatasetVisibility(index:number,visible:boolean):void;getDataVisibility?(index:number):boolean;toggleDataVisibility?(index:number):void;} /** Public structural view of the current Chart.js instance, without imposing `chart.js` as a * type dependency on consumers. The value is `undefined` before the peer loads and after the * component disconnects. */ export interface LyraChartInstance extends RuntimeChart{}export type LyraChartDatumKind='bar'|'point'|'segment'|'slice'|'box';type LyraCoreChartDatumKind=Exclude; /** Input-neutral detail shared by every chart-family `lr-datum-activate` event. */ export interface LyraChartDatumActivateDetail{readonly kind:TKind;readonly datasetIndex:number;readonly index:number;readonly label:string|undefined;readonly value:TValue;}export interface LyraChartEventMap{'lr-point-click':CustomEvent<{datasetIndex:number;index:number;label:string|undefined;value:unknown;}>;'lr-zoom':CustomEvent<{zoomed:boolean;}>;'lr-before-legend-visibility-change':CustomEvent;'lr-legend-visibility-change':CustomEvent;'lr-before-datum-visibility-change':CustomEvent;'lr-datum-visibility-change':CustomEvent;'lr-datum-activate':CustomEvent>;} /** * `` — the core Chart.js wrapper used directly and by the typed * Chart.js tags plus ``. `` and `` * are independent implementations. Requires the optional peer dep `chart.js`; `chartjs-plugin-zoom` * (for `zoom`) and `chartjs-plugin-datalabels` (for `data-labels`/`stack-totals`) * are further optional peers loaded only on demand. * With IntersectionObserver available, canvas construction waits for the first delivered * visibility decision; without it, drawing starts as soon as the peer and canvas are ready. * Simplified pie/doughnut datasets with magnitudes above Number.MAX_SAFE_INTEGER are uniformly * scaled for finite peer arc geometry. Legends, tooltips, data labels and semantic exports retain * original values; direct peer callbacks see scaled values. Explicit config.data is passed through. * * **API mirror note:** the real `wa-chart` docs page * (https://webawesome.com/docs/components/chart/) documents a `config: * ChartJS['config']` property alongside its simplified attributes — "a * flexible wrapper around Chart.js" supporting *both* simplified attributes * and full Chart.js configuration passthrough, not a `data`/`options` prop * pair. `lr-chart` mirrors that dual surface: the `LyraChartSeries`-based * `datasets`/`labels`/`type`/`withoutLegend`/`xLabel`/`yLabel`/`zoom` attributes * below are the simplified surface (compatible with WA's `type`, `xLabel`, * `yLabel`, `withoutLegend`, etc.), and the additional * `config` property is the raw-passthrough escape hatch — a * `LyraChartConfiguration` deep-merged over the generated config in * `buildConfig()`, mirroring WA's `config` property without discarding the * `LyraChartSeries` shape the rest of this component family (subclasses, box-plot, * histogram) is built on. * * `datasets`, `annotations`, and `hiddenDatasets` take bounded, clone-owned readonly snapshots. * Create a new collection and reassign it after changes; mutating the assigned array does not * update the view. `labels` does not yet share this contract. * * @customElement lr-chart * @event lr-zoom - `detail: { zoomed }`. * @event lr-point-click - Fired when pointer input lands on a data point/segment, when a generated * data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. * `detail: { datasetIndex: number, index: number, label: string | * undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and * `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`). * @event lr-datum-activate - Family-normalized activation event. Its detail adds `kind` * (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail. * @event lr-before-legend-visibility-change - Cancelable proposal emitted before a DOM legend * toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` * value, and the complete canonical proposed `hiddenDatasets` snapshot. * @event lr-legend-visibility-change - Emitted after an accepted DOM legend toggle commits the * same detail. Programmatic `hiddenDatasets` changes reconcile without either event. * @event lr-before-datum-visibility-change - Cancelable category visibility proposal in datum * legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. * Source category indexes apply to every dataset/ring. The complete detail is frozen. * @event lr-datum-visibility-change - Emitted after an accepted category toggle commits the same * frozen detail. Programmatic `hiddenDatums` assignments are silent. * @csspart base - The chart wrapper. * @csspart plot - The fixed-height canvas/overlay region. * @csspart canvas - The Chart.js canvas. * @csspart legend - The wrapping DOM legend, rendered unless `withoutLegend` is set. * @csspart legend-item - A keyboard-operable dataset or category visibility toggle. * @csspart legend-item-hidden - Added while the legend item's dataset or category is hidden. * @csspart legend-swatch - The resolved dataset/category color swatch in a legend item. * @csspart reset-zoom-button - The reset-zoom control when zoom is active. * @csspart description - The accessible chart summary. * @csspart data-table - The optional generated or slotted data table. * @csspart data-table-toggle - The disclosure button rendered by `dataTableToggle`. * @csspart center - The chart-area-centered overlay wrapper for the `center` slot. * @csspart error - Static visible error shown instead of `canvas` when the optional `chart.js` * peer dependency is not installed; its transition is announced through a shared light-DOM alert. * @csspart notices - Wrapper for nonfatal feature warnings and generated-data truncation notices. * @csspart data-truncation - Explanation shown when the generated accessible alternative samples * a data set larger than its 1,000-record ceiling. * @csspart feature-warning - Static nonfatal warning when a requested optional feature peer is * unavailable while the core chart remains usable. * @cssprop [--lr-chart-height=var(--lr-size-280px)] - The plot region's `block-size` and the * host's minimum block size. A visible data table or wrapping DOM legend grows the host in * normal flow instead of overlapping following content. `height` supplies a private fallback; * this public token always wins when a consumer sets it. * @cssprop [--lr-chart-grid-color=var(--lr-color-border)] - Grid-line color. Resolved via * `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`). * @cssprop [--lr-chart-tick-color=var(--lr-color-text-quiet)] - Axis tick-label color; also used * for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). * Resolved via `getComputedStyle` on every draw. * @cssprop [--lr-chart-tick-font-size=var(--lr-font-size-xs)] - Axis tick-label font size, in any * CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that * matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered * before this token existed -- leaving it unset must stay byte-identical to that, not shrink to * ``'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the * spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct * `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this * token's size once the consumer explicitly sets it, at which point ticks and point labels match. * Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` * token here (Chart.js paints to canvas and cannot consume `var()`). * @cssprop [--lr-chart-legend-color=var(--lr-color-text)] - Legend label color. Resolved via * `getComputedStyle` on every draw. * @cssprop [--lr-chart-legend-side-max=var(--lr-size-15rem)] - Maximum inline size reserved for a * side-positioned DOM legend; the track is also capped at one third of the chart allocation. * @cssprop [--lr-chart-legend-item-hover-bg=var(--lr-color-brand-quiet)] - Hover background of a * legend visibility button. * @cssprop --lr-chart-legend-item-active-bg - Pressed background of a legend visibility button; * defaults to the standard active mix of `--lr-color-brand-quiet`. * @cssprop [--lr-chart-data-table-button-hover-bg=var(--lr-color-brand-quiet)] - Hover background * of an actionable generated-table value. * @cssprop --lr-chart-data-table-button-active-bg - Pressed background of an actionable generated- * table value; defaults to the standard active mix of `--lr-color-brand-quiet`. * @cssprop [--lr-chart-data-table-toggle-hover-bg=var(--lr-color-brand-quiet)] - Hover background * of the `dataTableToggle` disclosure button. * @cssprop --lr-chart-data-table-toggle-active-bg - Pressed background of the `dataTableToggle` * disclosure button; defaults to a mix of the hover background with the shared active mix * partner. * @cssprop [--lr-chart-reset-zoom-button-hover-bg=var(--lr-color-brand-quiet)] - Hover background * of the reset-zoom button. * @cssprop --lr-chart-reset-zoom-button-active-bg - Pressed background of the reset-zoom button; * defaults to the standard active mix of `--lr-color-brand-quiet`. * @cssprop [--lr-chart-tooltip-bg=var(--lr-color-surface)] - Tooltip background color. Resolved * via `getComputedStyle` on every draw. * @cssprop [--lr-chart-tooltip-text=var(--lr-color-text)] - Tooltip text color. Resolved via * `getComputedStyle` on every draw. * @cssprop [--lr-chart-canvas-hover-outline-width=var(--lr-border-width-thin)] - Width of the * `[part='canvas']` hover-state outline. * @cssprop [--lr-chart-canvas-hover-outline-color=var(--lr-chart-grid-color)] - Color of the * `[part='canvas']` hover-state outline. * @cssprop [--lr-chart-pattern-step=var(--lr-space-2xs)] - Tile size of the texture painted on * `[part='legend-swatch']` while `forced-colors: active` matches, where every series collapses to * one system color and the stripe/crosshatch pattern becomes the only channel keeping series * apart. Declared on the swatch part rather than the host; the stripe width within a tile stays * `--lr-border-width-thin`, so a larger step spaces the stripes further apart. * @cssprop [--border-color-1=var(--lr-color-chart-1)] - First dataset border color. * @cssprop [--border-color-2=var(--lr-color-chart-2)] - Second dataset border color. * @cssprop [--border-color-3=var(--lr-color-chart-3)] - Third dataset border color. * @cssprop [--border-color-4=var(--lr-color-chart-4)] - Fourth dataset border color. * @cssprop [--border-color-5=var(--lr-color-chart-5)] - Fifth dataset border color. * @cssprop [--border-color-6=var(--lr-color-chart-6)] - Sixth dataset border color. * @cssprop [--fill-color-1=var(--lr-color-chart-1)] - First dataset fill color. * @cssprop [--fill-color-2=var(--lr-color-chart-2)] - Second dataset fill color. * @cssprop [--fill-color-3=var(--lr-color-chart-3)] - Third dataset fill color. * @cssprop [--fill-color-4=var(--lr-color-chart-4)] - Fourth dataset fill color. * @cssprop [--fill-color-5=var(--lr-color-chart-5)] - Fifth dataset fill color. * @cssprop [--fill-color-6=var(--lr-color-chart-6)] - Sixth dataset fill color. * @cssprop [--border-radius=var(--lr-radius)] - Dataset element corner radius. * @cssprop [--border-width=var(--lr-border-width-thin)] - Dataset element border width. * @cssprop [--grid-border-width=var(--lr-border-width-thin)] - Axis and grid line width. * @cssprop [--grid-color=var(--lr-chart-grid-color)] - Grid line color. * @cssprop [--line-border-width=var(--lr-border-width-medium)] - Line dataset stroke width. * @cssprop [--point-radius=var(--lr-space-2xs)] - Line/scatter point radius. * @slot - An optional `