@c2n/chart 0.0.7

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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -0
  3. package/dist/area-chart.js +29 -0
  4. package/dist/bar-chart.js +65 -0
  5. package/dist/chart-adapter.js +0 -0
  6. package/dist/chart-base-C4-1TyKq.js +666 -0
  7. package/dist/chart-base.js +2 -0
  8. package/dist/chart-data.js +286 -0
  9. package/dist/chart-series-BnpHO3lm.js +83 -0
  10. package/dist/chart-series.js +2 -0
  11. package/dist/chart-theme.js +151 -0
  12. package/dist/chart-types.js +8 -0
  13. package/dist/chart.js +13 -0
  14. package/dist/echarts-chart-base-LogCQN10.js +228 -0
  15. package/dist/echarts-chart-base.js +2 -0
  16. package/dist/line-chart.js +31 -0
  17. package/dist/pie-chart.js +100 -0
  18. package/dist/sparkline.js +79 -0
  19. package/dist/uplot-chart-base-BWr0zJE2.js +253 -0
  20. package/dist/uplot-chart-base.js +2 -0
  21. package/dist/uplot-paths-ChKohvIX.js +95 -0
  22. package/package.json +146 -0
  23. package/react.d.ts +34 -0
  24. package/react.js +3 -0
  25. package/types/src/area-chart.d.ts +36 -0
  26. package/types/src/area-chart.d.ts.map +1 -0
  27. package/types/src/bar-chart.d.ts +46 -0
  28. package/types/src/bar-chart.d.ts.map +1 -0
  29. package/types/src/chart-adapter.d.ts +67 -0
  30. package/types/src/chart-adapter.d.ts.map +1 -0
  31. package/types/src/chart-base.d.ts +265 -0
  32. package/types/src/chart-base.d.ts.map +1 -0
  33. package/types/src/chart-data.d.ts +43 -0
  34. package/types/src/chart-data.d.ts.map +1 -0
  35. package/types/src/chart-series.d.ts +51 -0
  36. package/types/src/chart-series.d.ts.map +1 -0
  37. package/types/src/chart-theme.d.ts +64 -0
  38. package/types/src/chart-theme.d.ts.map +1 -0
  39. package/types/src/chart-types.d.ts +162 -0
  40. package/types/src/chart-types.d.ts.map +1 -0
  41. package/types/src/chart.d.ts +27 -0
  42. package/types/src/chart.d.ts.map +1 -0
  43. package/types/src/echarts-chart-base.d.ts +28 -0
  44. package/types/src/echarts-chart-base.d.ts.map +1 -0
  45. package/types/src/engines/echarts-adapter.d.ts +17 -0
  46. package/types/src/engines/echarts-adapter.d.ts.map +1 -0
  47. package/types/src/engines/echarts-loader.d.ts +16 -0
  48. package/types/src/engines/echarts-loader.d.ts.map +1 -0
  49. package/types/src/engines/uplot-adapter.d.ts +4 -0
  50. package/types/src/engines/uplot-adapter.d.ts.map +1 -0
  51. package/types/src/engines/uplot-loader.d.ts +20 -0
  52. package/types/src/engines/uplot-loader.d.ts.map +1 -0
  53. package/types/src/engines/uplot-paths.d.ts +25 -0
  54. package/types/src/engines/uplot-paths.d.ts.map +1 -0
  55. package/types/src/line-chart.d.ts +40 -0
  56. package/types/src/line-chart.d.ts.map +1 -0
  57. package/types/src/pie-chart.d.ts +59 -0
  58. package/types/src/pie-chart.d.ts.map +1 -0
  59. package/types/src/sparkline.d.ts +56 -0
  60. package/types/src/sparkline.d.ts.map +1 -0
  61. package/types/src/uplot-chart-base.d.ts +50 -0
  62. package/types/src/uplot-chart-base.d.ts.map +1 -0
  63. package/vue.d.ts +134 -0
  64. package/vue.js +3 -0
@@ -0,0 +1,666 @@
1
+ import { ChartFrameBuilder, columnValue } from "./chart-data.js";
2
+ import { ChartThemeController, PROBE_COLORS } from "./chart-theme.js";
3
+ import { i as __decorate, n as SERIES_CHANGE_EVENT, r as SERIES_TAG } from "./chart-series-BnpHO3lm.js";
4
+ import { property, query, state } from "lit/decorators.js";
5
+ import { LitElement, html, isServer, nothing, unsafeCSS } from "lit";
6
+ import { jsonPropertyConverter } from "@c2n/core/lit-helper.js";
7
+ //#region src/chart.scss?inline
8
+ var chart_default = "@charset \"UTF-8\";\n/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n width: var(--c2-chart--width,100%);\n height: var(--c2-chart--height,320px);\n /*\n * The plot is absolutely positioned, so nothing inside the host contributes intrinsic width. As a flex\n * item — which is what every example frame in the docs site makes it — the host would otherwise shrink\n * to its legend, and to nothing at all when there is no legend. `min-width: 0` keeps it able to shrink\n * below its content when a layout genuinely needs that.\n */\n min-width: 0;\n padding: var(--c2-chart--padding,12px);\n background: var(--c2-chart--background,#ffffff);\n color: var(--c2-chart--color,#18181b);\n font-family: var(--c2-chart--font-family,inherit);\n font-size: var(--c2-chart--font-size,12px);\n border-top: var(--c2-chart--border-top,1px solid #e4e4e7);\n border-right: var(--c2-chart--border-right,1px solid #e4e4e7);\n border-bottom: var(--c2-chart--border-bottom,1px solid #e4e4e7);\n border-left: var(--c2-chart--border-left,1px solid #e4e4e7);\n border-top-left-radius: var(--c2-chart--border-top-left-radius,8px);\n border-top-right-radius: var(--c2-chart--border-top-right-radius,8px);\n border-bottom-left-radius: var(--c2-chart--border-bottom-left-radius,8px);\n border-bottom-right-radius: var(--c2-chart--border-bottom-right-radius,8px);\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.frame {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n}\n\n/*\n * The plot area is the engine's territory. `contain: strict` plus absolute positioning means the canvas\n * the engine sizes inside it can never feed its own size back into the ResizeObserver watching this box,\n * which is what makes the resize loop structurally impossible rather than merely unlikely.\n */\n.plot-area {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n overflow: hidden;\n}\n\n.plot {\n position: absolute;\n inset: 0;\n contain: strict;\n}\n\n.plot canvas {\n display: block;\n position: absolute;\n inset: 0;\n}\n\n.overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.tooltip {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n pointer-events: none;\n will-change: transform;\n display: flex;\n flex-direction: column;\n gap: var(--c2-chart__tooltip--gap,6px);\n padding: var(--c2-chart__tooltip--padding,8px 10px);\n border-radius: var(--c2-chart__tooltip--border-radius,6px);\n background: var(--c2-chart__tooltip--background-color,#18181b);\n color: var(--c2-chart__tooltip--color,#fafafa);\n font-size: var(--c2-chart__tooltip--font-size,12px);\n box-shadow: var(--c2-chart__tooltip--box-shadow,0 8px 24px rgba(24, 24, 27, 0.08));\n white-space: nowrap;\n}\n\n.tooltip[hidden] {\n display: none;\n}\n\n.tooltip-row {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.tooltip-marker {\n width: var(--c2-chart__legend-marker--size,10px);\n height: var(--c2-chart__legend-marker--size,10px);\n border-radius: var(--c2-chart__legend-marker--border-radius,999px);\n flex: none;\n}\n\n.tooltip-label {\n flex: 1 1 auto;\n}\n\n.tooltip-value {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.actions {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: auto;\n display: flex;\n gap: 4px;\n}\n\n.state {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--c2-chart__state--color,#71717a);\n font-size: var(--c2-chart__state--font-size,14px);\n background: var(--c2-chart--background,#ffffff);\n}\n\n.legend {\n display: flex;\n flex-wrap: wrap;\n gap: var(--c2-chart__legend--gap,12px);\n padding: var(--c2-chart__legend--padding,8px 0 0);\n color: var(--c2-chart__legend--color,#71717a);\n font-size: var(--c2-chart__legend--font-size,12px);\n}\n\n.legend--start,\n.legend--end {\n flex-direction: column;\n align-content: flex-start;\n flex: 0 0 auto;\n align-self: center;\n max-height: 100%;\n overflow: auto;\n}\n\n/* The legend is on an inline edge, so the frame runs as a row. */\n.frame--side {\n flex-direction: row;\n align-items: stretch;\n}\n\n.legend-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 0;\n border: 0;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n}\n\n.legend-item[aria-pressed=false] {\n opacity: var(--c2-chart__legend__disabled--opacity,0.38);\n}\n\n.legend-marker {\n width: var(--c2-chart__legend-marker--size,10px);\n height: var(--c2-chart__legend-marker--size,10px);\n border-radius: var(--c2-chart__legend-marker--border-radius,999px);\n flex: none;\n}\n\n.definitions {\n display: none;\n}\n\n/*\n * Colour probes. `getComputedStyle().getPropertyValue()` hands back the author's text for a `var()` or\n * `color-mix()` chain, which no canvas engine can parse; the computed `color` of an element always\n * resolves to `rgb(…)`. `display: none` keeps them free.\n */\n.theme-probe {\n display: none;\n}\n.theme-probe i:nth-child(1) {\n color: var(--c2-chart__series-1--color,#0265dc);\n}\n.theme-probe i:nth-child(2) {\n color: var(--c2-chart__series-2--color,#ea580c);\n}\n.theme-probe i:nth-child(3) {\n color: var(--c2-chart__series-3--color,#0f766e);\n}\n.theme-probe i:nth-child(4) {\n color: var(--c2-chart__series-4--color,#db2777);\n}\n.theme-probe i:nth-child(5) {\n color: var(--c2-chart__series-5--color,#a16207);\n}\n.theme-probe i:nth-child(6) {\n color: var(--c2-chart__series-6--color,#7c3aed);\n}\n.theme-probe i:nth-child(7) {\n color: var(--c2-chart__series-7--color,#0891b2);\n}\n.theme-probe i:nth-child(8) {\n color: var(--c2-chart__series-8--color,#52525b);\n}\n.theme-probe i:nth-child(9) {\n color: var(--c2-chart__axis--color,#71717a);\n}\n.theme-probe i:nth-child(10) {\n color: var(--c2-chart__grid--color,#e4e4e7);\n}\n.theme-probe i:nth-child(11) {\n color: var(--c2-chart--color,#18181b);\n}\n.theme-probe i:nth-child(12) {\n color: var(--c2-chart__muted--color,#71717a);\n}\n.theme-probe i:nth-child(13) {\n color: var(--c2-chart__tooltip--background-color,#18181b);\n}\n.theme-probe i:nth-child(14) {\n color: var(--c2-chart__tooltip--color,#fafafa);\n}\n.theme-probe i:nth-child(15) {\n color: var(--c2-chart__crosshair--color,#a1a1aa);\n}\n.theme-probe i:nth-child(16) {\n color: var(--c2-chart__positive--color,#16a34a);\n}\n.theme-probe i:nth-child(17) {\n color: var(--c2-chart__negative--color,#dc2626);\n}\n.theme-probe i:nth-child(18) {\n color: var(--c2-chart__surface--color,#ffffff);\n}\n\n/*\n * uPlot's structural CSS, hand-ported.\n *\n * `uplot/dist/uPlot.min.css` is a global stylesheet and a shadow root cannot see it, so the rules the\n * engine's DOM depends on live here instead. Only the structural half is kept: the legend and title rules\n * are dropped because this component renders its own. Version-coupled to the `uplot` peer range — re-check\n * after an upgrade.\n */\n.uplot,\n.uplot *,\n.uplot *::before,\n.uplot *::after {\n box-sizing: border-box;\n}\n\n.uplot {\n font-family: var(--c2-chart--font-family,inherit);\n line-height: 1.5;\n width: min-content;\n}\n\n.u-wrap {\n position: relative;\n user-select: none;\n}\n\n.u-over,\n.u-under {\n position: absolute;\n}\n\n.u-under {\n overflow: hidden;\n}\n\n.uplot canvas {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.u-axis {\n position: absolute;\n}\n\n.u-select {\n position: absolute;\n pointer-events: none;\n background: rgba(0, 0, 0, 0.07);\n}\n\n.u-cursor-x,\n.u-cursor-y {\n position: absolute;\n left: 0;\n top: 0;\n pointer-events: none;\n will-change: transform;\n}\n\n.u-hz .u-cursor-x,\n.u-vt .u-cursor-y {\n height: 100%;\n border-right: var(--c2-chart__crosshair--width,1px) dashed var(--c2-chart__crosshair--color,#a1a1aa);\n}\n\n.u-hz .u-cursor-y,\n.u-vt .u-cursor-x {\n width: 100%;\n border-bottom: var(--c2-chart__crosshair--width,1px) dashed var(--c2-chart__crosshair--color,#a1a1aa);\n}\n\n.u-cursor-pt {\n position: absolute;\n top: 0;\n left: 0;\n border-radius: 50%;\n border: 0 solid;\n pointer-events: none;\n will-change: transform;\n /* Must stay !important: uPlot sets the `background` shorthand inline. */\n background-clip: padding-box !important;\n}\n\n.u-axis.u-off,\n.u-select.u-off,\n.u-cursor-x.u-off,\n.u-cursor-y.u-off,\n.u-cursor-pt.u-off {\n display: none;\n}";
9
+ //#endregion
10
+ //#region src/chart-base.ts
11
+ /** Properties that only ever move data. A change limited to these takes the fast path. */
12
+ var DATA_KEYS = /* @__PURE__ */ new Set(["data", "revision"]);
13
+ /**
14
+ * Reactive properties that change only this component's own DOM and never the engine's options.
15
+ *
16
+ * The hover state is the important one. Without it, moving the pointer counts as a presentation change and
17
+ * rebuilds the engine options — and under uPlot `setOptions` destroys and reconstructs the instance, which
18
+ * resets the cursor mid-hover, makes the tooltip impossible to show, and throws away the chart on every
19
+ * mouse move. The legend and the state messages are likewise ours to draw, not the engine's.
20
+ */
21
+ var VIEW_ONLY_KEYS = /* @__PURE__ */ new Set([
22
+ "hoverContext",
23
+ "hiddenSeries",
24
+ "engineFailed",
25
+ "loading",
26
+ "error",
27
+ "emptyMessage",
28
+ "tooltip",
29
+ "legend",
30
+ "maxPoints",
31
+ "lazyRender",
32
+ "renderTooltip",
33
+ "renderLegendItem",
34
+ "dataSource"
35
+ ]);
36
+ /** `stats.cpu` -> `Cpu`, `unit_price` -> `Unit price`: a readable label for an inferred field. */
37
+ function humanize(field) {
38
+ const spaced = (field.split(".").pop() ?? field).replace(/[_-]+/g, " ").replace(/([a-z\d])([A-Z])/g, "$1 $2");
39
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
40
+ }
41
+ /** Pixels a resize must exceed before the engine is told; a canvas resize is a full redraw. */
42
+ var RESIZE_EPSILON = 1;
43
+ /**
44
+ * Shared behaviour of every `c2-*-chart`: the chrome and its slots, the resize observer, theme
45
+ * resolution, data normalisation, and the routing that keeps a realtime update off the expensive path.
46
+ * It defines no tag and is never registered — the concrete charts extend it.
47
+ *
48
+ * **Why the data and presentation inputs are separate.** `data` and `revision` are the only properties on
49
+ * the data path; everything else is presentation. A change limited to the data path is pushed straight
50
+ * into the engine from `shouldUpdate`, which returns `false`, so Lit never renders or commits and the
51
+ * canvas container is not touched. Anything else rebuilds the engine options, which is allowed to be
52
+ * expensive. That is what makes a streaming tick cost one engine redraw and nothing more.
53
+ *
54
+ * **Sizing.** A canvas has no intrinsic size, so the host is sized by `--c2-chart--height` (320px by
55
+ * default) rather than by its content. Give the host a height — through the variable, a CSS rule, or a
56
+ * flex parent — or the plot area collapses.
57
+ *
58
+ * @slot default - The series definitions: `c2-chart-series` elements. They render nothing themselves.
59
+ * @slot legend - Replaces the built-in legend. The built-in one is still what `legend` positions.
60
+ * @slot tooltip - Replaces the built-in tooltip body. The hovered point is available through the `renderTooltip` property when a function is easier than markup.
61
+ * @slot actions - Controls pinned to the top-right of the plot area, for a range picker or an export button.
62
+ * @slot empty - Replaces the built-in "no data" message.
63
+ * @slot loading - Replaces the built-in message shown while `loading` is set.
64
+ * @slot error - Replaces the built-in message shown when `error` is set.
65
+ *
66
+ * @slotcomponent c2-chart-series
67
+ *
68
+ * @event {CustomEvent<{ engine: string }>} chart-ready - Fired after the engine has loaded and drawn for the first time. The host also gains `data-chart-ready`, which is what a test should wait on.
69
+ * @event {CustomEvent<{ error: unknown }>} chart-error - Fired when the engine fails to load or to draw. `detail.error` is the underlying failure.
70
+ * @event {CustomEvent<ChartPointEventDetail>} point-click - Fired when a datum is clicked. Does not bubble: several components fire point events, so a listener belongs on the element itself.
71
+ * @event {CustomEvent<ChartPointEventDetail>} point-hover - Fired as the pointer moves between data points, and with a `null` detail when it leaves the plot. Does not bubble.
72
+ * @event {CustomEvent<ChartRangeEventDetail>} range-change - Fired after the user zooms or brushes. `detail.min` and `detail.max` are the new x bounds. Does not bubble.
73
+ * @event {CustomEvent<ChartSeriesToggleEventDetail>} series-toggle - Fired when a legend entry is toggled. Does not bubble.
74
+ *
75
+ * @csspart frame - The outer flex column holding the legend and the plot area.
76
+ * @csspart plot-area - The positioned box the engine draws into.
77
+ * @csspart plot - The engine's container element. Carries no Lit bindings, so the canvas survives every update.
78
+ * @csspart overlay - The non-interactive layer above the canvas that holds the tooltip and the actions.
79
+ * @csspart tooltip - The tooltip bubble.
80
+ * @csspart actions - The container for the `actions` slot.
81
+ * @csspart state - The empty, loading or error message layer.
82
+ * @csspart legend - The legend container.
83
+ * @csspart legend-item - One legend entry, a toggle button.
84
+ * @csspart legend-marker - The colour swatch inside a legend entry.
85
+ *
86
+ * @cssproperty {length} [--c2-chart--width=100%] - Width of the host. The plot is absolutely positioned and has no intrinsic width, so a chart used as a flex item would otherwise collapse to its legend.
87
+ * @cssproperty {pixel} [--c2-chart--height=320px] - Height of the host. A canvas has no intrinsic size, so this is what gives the chart a box.
88
+ * @cssproperty {color} [--c2-chart--background=#ffffff] - Background of the chart surface.
89
+ * @cssproperty {color} [--c2-chart--color=#18181b] - Primary text colour.
90
+ * @cssproperty {font-family} [--c2-chart--font-family=inherit] - Font family used for the chart chrome and the labels the engine draws.
91
+ * @cssproperty {font-size} [--c2-chart--font-size=12px] - Base font size.
92
+ * @cssproperty {padding} [--c2-chart--padding=12px] - Padding around the whole chart.
93
+ *
94
+ * @cssproperty {border} [--c2-chart--border-top=1px solid #e4e4e7] - Top border.
95
+ * @cssproperty {border} [--c2-chart--border-right=1px solid #e4e4e7] - Right border.
96
+ * @cssproperty {border} [--c2-chart--border-bottom=1px solid #e4e4e7] - Bottom border.
97
+ * @cssproperty {border} [--c2-chart--border-left=1px solid #e4e4e7] - Left border.
98
+ * @cssproperty {border-radius} [--c2-chart--border-top-left-radius=8px] - Top-left corner radius.
99
+ * @cssproperty {border-radius} [--c2-chart--border-top-right-radius=8px] - Top-right corner radius.
100
+ * @cssproperty {border-radius} [--c2-chart--border-bottom-left-radius=8px] - Bottom-left corner radius.
101
+ * @cssproperty {border-radius} [--c2-chart--border-bottom-right-radius=8px] - Bottom-right corner radius.
102
+ *
103
+ * @cssproperty {color} [--c2-chart__series-1--color=#0265dc] - Colour of the first series.
104
+ * @cssproperty {color} [--c2-chart__series-2--color=#ea580c] - Colour of the second series.
105
+ * @cssproperty {color} [--c2-chart__series-3--color=#0f766e] - Colour of the third series.
106
+ * @cssproperty {color} [--c2-chart__series-4--color=#db2777] - Colour of the fourth series.
107
+ * @cssproperty {color} [--c2-chart__series-5--color=#a16207] - Colour of the fifth series.
108
+ * @cssproperty {color} [--c2-chart__series-6--color=#7c3aed] - Colour of the sixth series.
109
+ * @cssproperty {color} [--c2-chart__series-7--color=#0891b2] - Colour of the seventh series.
110
+ * @cssproperty {color} [--c2-chart__series-8--color=#52525b] - Colour of the eighth series. Series beyond the eighth reuse the palette from the start.
111
+ *
112
+ * @cssproperty {pixel} [--c2-chart__line--width=2px] - Stroke width of a line series.
113
+ * @cssproperty {pixel} [--c2-chart__point--radius=2.5px] - Radius of a data point marker.
114
+ * @cssproperty {opacity} [--c2-chart__area--opacity=0.15] - Opacity of the fill under an area series.
115
+ *
116
+ * @cssproperty {color} [--c2-chart__axis--color=#71717a] - Colour of the axis lines and tick labels.
117
+ * @cssproperty {font-size} [--c2-chart__axis--font-size=12px] - Font size of the tick labels.
118
+ * @cssproperty {color} [--c2-chart__grid--color=#e4e4e7] - Colour of the grid lines.
119
+ * @cssproperty {pixel} [--c2-chart__grid--width=1px] - Width of the grid lines.
120
+ * @cssproperty {color} [--c2-chart__crosshair--color=#a1a1aa] - Colour of the cursor crosshair.
121
+ * @cssproperty {pixel} [--c2-chart__crosshair--width=1px] - Width of the cursor crosshair.
122
+ *
123
+ * @cssproperty {color} [--c2-chart__surface--color=#ffffff] - Surface colour handed to the engine, for marker borders and label backdrops.
124
+ * @cssproperty {color} [--c2-chart__muted--color=#71717a] - Secondary text colour.
125
+ * @cssproperty {color} [--c2-chart__positive--color=#16a34a] - Colour for a rising value, used by the candlestick and gauge charts.
126
+ * @cssproperty {color} [--c2-chart__negative--color=#dc2626] - Colour for a falling value, used by the candlestick and gauge charts.
127
+ *
128
+ * @cssproperty {pixel} [--c2-chart__legend--gap=12px] - Gap between legend entries.
129
+ * @cssproperty {padding} [--c2-chart__legend--padding=8px 0 0] - Padding around the legend.
130
+ * @cssproperty {color} [--c2-chart__legend--color=#71717a] - Legend text colour.
131
+ * @cssproperty {font-size} [--c2-chart__legend--font-size=12px] - Legend font size.
132
+ * @cssproperty {opacity} [--c2-chart__legend__disabled--opacity=0.38] - Opacity of a legend entry whose series is hidden.
133
+ * @cssproperty {pixel} [--c2-chart__legend-marker--size=10px] - Size of the legend colour swatch.
134
+ * @cssproperty {border-radius} [--c2-chart__legend-marker--border-radius=999px] - Corner radius of the legend colour swatch.
135
+ *
136
+ * @cssproperty {color} [--c2-chart__tooltip--background-color=#18181b] - Tooltip background.
137
+ * @cssproperty {color} [--c2-chart__tooltip--color=#fafafa] - Tooltip text colour.
138
+ * @cssproperty {font-size} [--c2-chart__tooltip--font-size=12px] - Tooltip font size.
139
+ * @cssproperty {padding} [--c2-chart__tooltip--padding=8px 10px] - Tooltip padding.
140
+ * @cssproperty {border-radius} [--c2-chart__tooltip--border-radius=6px] - Tooltip corner radius.
141
+ * @cssproperty {box-shadow} [--c2-chart__tooltip--box-shadow=0 8px 24px rgba(24, 24, 27, 0.08)] - Tooltip shadow.
142
+ * @cssproperty {pixel} [--c2-chart__tooltip--gap=6px] - Gap between tooltip rows.
143
+ *
144
+ * @cssproperty {color} [--c2-chart__state--color=#71717a] - Colour of the empty, loading and error text.
145
+ * @cssproperty {font-size} [--c2-chart__state--font-size=14px] - Font size of the empty, loading and error text.
146
+ */
147
+ var ChartBase = class extends LitElement {
148
+ constructor(..._args) {
149
+ super(..._args);
150
+ this.revision = 0;
151
+ this.xField = "";
152
+ this.labelField = "";
153
+ this.xType = "linear";
154
+ this.legend = "bottom";
155
+ this.tooltip = "axis";
156
+ this.animation = "none";
157
+ this.loading = false;
158
+ this.error = "";
159
+ this.emptyMessage = "No data";
160
+ this.maxPoints = 0;
161
+ this.lazyRender = false;
162
+ this.seriesElements = [];
163
+ this.hiddenSeries = /* @__PURE__ */ new Set();
164
+ this.hoverContext = null;
165
+ this.engineFailed = false;
166
+ this.themeController = new ChartThemeController(this, () => this.handleThemeChange());
167
+ this.frameBuilder = new ChartFrameBuilder();
168
+ this.#creating = false;
169
+ this.#optionsDirty = false;
170
+ this.#optionsMode = "merge";
171
+ this.#dataDirty = false;
172
+ this.#appended = 0;
173
+ this.#measured = {
174
+ width: 0,
175
+ height: 0
176
+ };
177
+ this.#visible = false;
178
+ this.#handleSeriesChange = (event) => {
179
+ event.stopPropagation();
180
+ this.#collectSeries();
181
+ };
182
+ }
183
+ static {
184
+ this.styles = unsafeCSS(chart_default);
185
+ }
186
+ /** Guards against two `createChart` runs racing while the engine chunk is in flight. */
187
+ #creating;
188
+ #optionsDirty;
189
+ #optionsMode;
190
+ #dataDirty;
191
+ #appended;
192
+ #measured;
193
+ #resizeObserver;
194
+ #intersectionObserver;
195
+ #visible;
196
+ #unsubscribe;
197
+ connectedCallback() {
198
+ super.connectedCallback();
199
+ this.addEventListener(SERIES_CHANGE_EVENT, this.#handleSeriesChange);
200
+ if (isServer) return;
201
+ if (typeof ResizeObserver !== "undefined" && !this.#resizeObserver) this.#resizeObserver = new ResizeObserver((entries) => this.#handleResize(entries));
202
+ if (this.plotElement) this.#resizeObserver?.observe(this.plotElement);
203
+ if (this.lazyRender && typeof IntersectionObserver !== "undefined") {
204
+ if (!this.#intersectionObserver) this.#intersectionObserver = new IntersectionObserver((entries) => {
205
+ if (!entries.some((entry) => entry.isIntersecting)) return;
206
+ this.#visible = true;
207
+ this.#intersectionObserver?.disconnect();
208
+ this.requestUpdate();
209
+ });
210
+ this.#intersectionObserver.observe(this);
211
+ } else this.#visible = true;
212
+ }
213
+ disconnectedCallback() {
214
+ super.disconnectedCallback();
215
+ this.removeEventListener(SERIES_CHANGE_EVENT, this.#handleSeriesChange);
216
+ this.#resizeObserver?.disconnect();
217
+ this.#intersectionObserver?.disconnect();
218
+ this.#unsubscribe?.();
219
+ this.#unsubscribe = void 0;
220
+ this.adapter?.destroy();
221
+ this.adapter = void 0;
222
+ this.removeAttribute("data-chart-ready");
223
+ }
224
+ /**
225
+ * The fast path. A change confined to `data`/`revision` on a live chart is pushed into the engine here
226
+ * and `false` is returned, so Lit skips render and commit entirely and the canvas is never touched.
227
+ */
228
+ shouldUpdate(changed) {
229
+ if (!this.hasUpdated || !this.adapter) return true;
230
+ for (const key of changed.keys()) if (!DATA_KEYS.has(key)) return true;
231
+ this.frame = this.frameBuilder.build(this.data, this.normalizeContext());
232
+ this.#flushData();
233
+ return false;
234
+ }
235
+ willUpdate(changed) {
236
+ if (changed.has("data") || changed.has("revision")) {
237
+ this.frame = this.frameBuilder.build(this.data, this.normalizeContext());
238
+ this.#dataDirty = true;
239
+ }
240
+ if (changed.has("dataSource")) this.#bindDataSource();
241
+ for (const key of changed.keys()) {
242
+ const name = key;
243
+ if (!DATA_KEYS.has(name) && !VIEW_ONLY_KEYS.has(name)) {
244
+ this.#optionsDirty = true;
245
+ break;
246
+ }
247
+ }
248
+ if (changed.has("series") || changed.has("seriesElements")) this.#optionsMode = "replace";
249
+ }
250
+ updated(changed) {
251
+ super.updated(changed);
252
+ if (isServer) return;
253
+ this.#sync();
254
+ }
255
+ /**
256
+ * Replaces the data without going through the update queue. Equivalent to assigning `data`, but skips
257
+ * Lit's scheduling — worth it in a tight loop.
258
+ */
259
+ updateData(next) {
260
+ this.data = next;
261
+ this.frame = this.frameBuilder.build(next, this.normalizeContext());
262
+ this.#flushData();
263
+ }
264
+ /**
265
+ * Appends one point across every series at a shared x. The frame grows in place, so nothing is
266
+ * re-normalised and no Lit update is scheduled: a 10 Hz feed costs one engine redraw per tick.
267
+ */
268
+ appendPoint(x, values) {
269
+ if (!this.frame) {
270
+ this.frame = this.frameBuilder.build([], this.normalizeContext());
271
+ if (!this.frame) return;
272
+ }
273
+ this.frameBuilder.push(this.frame, x, values, this.maxPoints);
274
+ this.#appended += 1;
275
+ this.#flushData();
276
+ }
277
+ /** Shows or hides one series, as the legend does. */
278
+ setSeriesVisible(index, visible) {
279
+ const next = new Set(this.hiddenSeries);
280
+ if (visible) next.delete(index);
281
+ else next.add(index);
282
+ this.hiddenSeries = next;
283
+ this.adapter?.setSeriesVisibility(index, visible);
284
+ const series = this.resolvedSeries[index];
285
+ if (!series) return;
286
+ this.dispatchEvent(new CustomEvent("series-toggle", { detail: {
287
+ seriesIndex: index,
288
+ series,
289
+ visible,
290
+ hidden: [...next]
291
+ } }));
292
+ }
293
+ /** The series in draw order: `c2-chart-series` children when present, otherwise the `series` property. */
294
+ get resolvedSeries() {
295
+ if (this.seriesElements.length > 0) return this.seriesElements.filter((element) => !element.hidden).map((element) => element.toConfig());
296
+ if (this.series && this.series.length > 0) return this.series.filter((series) => !series.hidden);
297
+ return this.inferredSeries();
298
+ }
299
+ /**
300
+ * The series to draw when nothing was declared: every numeric field of the first row except the ones
301
+ * already spoken for by `x-field` and `label-field`.
302
+ *
303
+ * This reads `data` rather than the normalised frame on purpose. Deriving it from the frame would be
304
+ * circular — the frame is built *from* the series list — and naming the results positionally would be
305
+ * worse than circular: the next normalisation would look up a field that does not exist in the rows and
306
+ * quietly read every value as a gap.
307
+ */
308
+ inferredSeries() {
309
+ const rows = this.data;
310
+ if (!Array.isArray(rows) || rows.length === 0) return [];
311
+ const first = rows[0];
312
+ if (typeof first === "number") return [{
313
+ field: "value",
314
+ label: "Value"
315
+ }];
316
+ if (Array.isArray(first) || ArrayBuffer.isView(first)) return rows.slice(1).map((_column, index) => ({
317
+ field: `${index}`,
318
+ label: `Series ${index + 1}`
319
+ }));
320
+ const row = first;
321
+ return Object.keys(row).filter((key) => typeof row[key] === "number" && key !== this.xField && key !== this.labelField).map((key) => ({
322
+ field: key,
323
+ label: humanize(key)
324
+ }));
325
+ }
326
+ /** The colour a series draws with: its own `color`, else its palette slot. */
327
+ colorOf(series, index, theme = this.themeController.theme) {
328
+ return series.color ?? theme.palette[index % theme.palette.length];
329
+ }
330
+ normalizeContext() {
331
+ const series = this.resolvedSeries;
332
+ return {
333
+ xField: this.xField,
334
+ labelField: this.labelField,
335
+ series,
336
+ signature: `${this.xField}|${this.labelField}|${this.xType}|${series.map((item) => item.field).join(",")}`
337
+ };
338
+ }
339
+ buildContext() {
340
+ return {
341
+ theme: this.themeController.theme,
342
+ series: this.resolvedSeries,
343
+ hidden: this.hiddenSeries,
344
+ labels: this.frame?.labels,
345
+ width: this.#measured.width || this.plotElement?.clientWidth || 0,
346
+ height: this.#measured.height || this.plotElement?.clientHeight || 0
347
+ };
348
+ }
349
+ /** True once there is something to draw and somewhere to draw it. */
350
+ #canRender() {
351
+ if (!this.#visible || this.engineFailed || this.error || this.loading) return false;
352
+ if (!this.plotElement || !this.frame || this.frame.length === 0) return false;
353
+ const { width, height } = this.buildContext();
354
+ return width > 0 && height > 0;
355
+ }
356
+ async #sync() {
357
+ if (!this.#canRender()) return;
358
+ if (!this.adapter) {
359
+ await this.#createChart();
360
+ return;
361
+ }
362
+ if (this.#optionsDirty) {
363
+ this.#optionsDirty = false;
364
+ this.adapter.setOptions(this.buildOptions(this.buildContext()), this.#optionsMode);
365
+ this.#optionsMode = "merge";
366
+ this.#dataDirty = true;
367
+ }
368
+ if (this.#dataDirty) this.#flushData();
369
+ }
370
+ async #createChart() {
371
+ if (this.#creating || !this.plotElement || !this.frame) return;
372
+ this.#creating = true;
373
+ try {
374
+ const adapter = await this.createAdapter();
375
+ if (!this.isConnected || !this.plotElement) {
376
+ adapter.destroy();
377
+ return;
378
+ }
379
+ const context = this.buildContext();
380
+ await adapter.create(this.plotElement, this.buildOptions(context), this.projectData(this.frame, context), {
381
+ hover: (detail) => this.#handleHover(detail),
382
+ click: (detail) => this.#handleClick(detail),
383
+ rangeChange: (detail) => this.dispatchEvent(new CustomEvent("range-change", { detail }))
384
+ });
385
+ this.adapter = adapter;
386
+ this.#optionsDirty = false;
387
+ this.#dataDirty = false;
388
+ for (const index of this.hiddenSeries) adapter.setSeriesVisibility(index, false);
389
+ this.setAttribute("data-chart-ready", "true");
390
+ this.dispatchEvent(new CustomEvent("chart-ready", { detail: { engine: this.engineName } }));
391
+ } catch (error) {
392
+ this.engineFailed = true;
393
+ this.dispatchEvent(new CustomEvent("chart-error", { detail: { error } }));
394
+ } finally {
395
+ this.#creating = false;
396
+ }
397
+ }
398
+ #flushData() {
399
+ if (!this.adapter || !this.frame) return;
400
+ this.#dataDirty = false;
401
+ const projected = this.projectData(this.frame, this.buildContext());
402
+ if (this.#appended > 0 && this.adapter.appendData) this.adapter.appendData(projected, this.#appended);
403
+ else this.adapter.setData(projected);
404
+ this.#appended = 0;
405
+ }
406
+ #handleResize(entries) {
407
+ const rect = entries[entries.length - 1]?.contentRect;
408
+ if (!rect) return;
409
+ if (Math.abs(rect.width - this.#measured.width) < RESIZE_EPSILON && Math.abs(rect.height - this.#measured.height) < RESIZE_EPSILON) return;
410
+ this.#measured = {
411
+ width: rect.width,
412
+ height: rect.height
413
+ };
414
+ if (this.adapter) this.adapter.resize(rect.width, rect.height);
415
+ else this.#sync();
416
+ }
417
+ handleThemeChange() {
418
+ this.#optionsDirty = true;
419
+ this.requestUpdate();
420
+ }
421
+ #handleSeriesChange;
422
+ #collectSeries() {
423
+ const slot = this.renderRoot?.querySelector("slot.definitions");
424
+ if (!slot) return;
425
+ const found = [];
426
+ for (const element of slot.assignedElements({ flatten: true })) if (element.localName === "c2-chart-series") found.push(element);
427
+ else found.push(...Array.from(element.querySelectorAll(SERIES_TAG)));
428
+ if (!isServer && typeof customElements !== "undefined") for (const element of found) customElements.upgrade(element);
429
+ this.seriesElements = found;
430
+ }
431
+ #bindDataSource() {
432
+ this.#unsubscribe?.();
433
+ this.#unsubscribe = void 0;
434
+ const source = this.dataSource;
435
+ if (!source) return;
436
+ const controller = new AbortController();
437
+ source.getWindow({
438
+ maxPoints: this.maxPoints || 2e3,
439
+ signal: controller.signal
440
+ }).then((result) => {
441
+ this.updateData(result.data);
442
+ }).catch((error) => {
443
+ this.dispatchEvent(new CustomEvent("chart-error", { detail: { error } }));
444
+ });
445
+ if (source.subscribe) {
446
+ const stop = source.subscribe((x, values) => this.appendPoint(x, values));
447
+ this.#unsubscribe = () => {
448
+ controller.abort();
449
+ stop();
450
+ };
451
+ } else this.#unsubscribe = () => controller.abort();
452
+ }
453
+ #handleHover(detail) {
454
+ if (!detail || !this.frame || this.tooltip === "none") {
455
+ this.#setHover(null);
456
+ return;
457
+ }
458
+ const context = this.#tooltipContextAt(detail);
459
+ this.#setHover(context);
460
+ const point = this.#pointAt(detail.index, detail.seriesIndex);
461
+ if (point) this.dispatchEvent(new CustomEvent("point-hover", { detail: point }));
462
+ }
463
+ /**
464
+ * Positions the tooltip imperatively. A pointer move must not schedule a Lit update, so the transform is
465
+ * written straight to the node; only a change of hovered index re-renders, and only when the body is
466
+ * actually dynamic.
467
+ */
468
+ #setHover(context) {
469
+ const previous = this.hoverContext;
470
+ if (context && this.tooltipElement) this.tooltipElement.style.transform = `translate(${context.px}px, ${context.py}px)`;
471
+ if (previous && context && previous.index === context.index) return;
472
+ this.hoverContext = context;
473
+ }
474
+ #tooltipContextAt(detail) {
475
+ const frame = this.frame;
476
+ const theme = this.themeController.theme;
477
+ const series = this.resolvedSeries;
478
+ const x = columnValue(frame.x, detail.index) ?? detail.index;
479
+ const entries = [];
480
+ series.forEach((item, index) => {
481
+ if (this.hiddenSeries.has(index)) return;
482
+ if (this.tooltip === "item" && index !== detail.seriesIndex) return;
483
+ const column = frame.columns[index];
484
+ if (!column) return;
485
+ const value = columnValue(column, detail.index);
486
+ entries.push({
487
+ seriesIndex: index,
488
+ series: item,
489
+ value,
490
+ formatted: value === null ? "—" : item.format?.(value) ?? this.formatValue(value),
491
+ color: this.colorOf(item, index, theme)
492
+ });
493
+ });
494
+ return {
495
+ index: detail.index,
496
+ x,
497
+ formattedX: frame.labels?.[detail.index] ?? this.formatX(x),
498
+ entries,
499
+ px: detail.px,
500
+ py: detail.py
501
+ };
502
+ }
503
+ #pointAt(index, seriesIndex) {
504
+ const frame = this.frame;
505
+ const series = this.resolvedSeries[seriesIndex];
506
+ if (!frame || !series) return void 0;
507
+ return {
508
+ index,
509
+ seriesIndex,
510
+ series,
511
+ x: columnValue(frame.x, index) ?? index,
512
+ y: frame.columns[seriesIndex] ? columnValue(frame.columns[seriesIndex], index) : null,
513
+ label: frame.labels?.[index]
514
+ };
515
+ }
516
+ #handleClick(detail) {
517
+ const point = this.#pointAt(detail.index, detail.seriesIndex);
518
+ if (point) this.dispatchEvent(new CustomEvent("point-click", { detail: point }));
519
+ }
520
+ /** Formats an x value for the tooltip. Time charts get a date, everything else a number. */
521
+ formatX(value) {
522
+ if (this.xType === "time") return new Intl.DateTimeFormat(this.locale, {
523
+ dateStyle: "medium",
524
+ timeStyle: "short"
525
+ }).format(new Date(value));
526
+ return this.formatValue(value);
527
+ }
528
+ /**
529
+ * How much time the chart currently covers, in milliseconds, or `0` when that is not a meaningful question.
530
+ * Axis labels are chosen from it: a day of five-minute samples and a year of daily ones want different ticks.
531
+ */
532
+ xSpan() {
533
+ const frame = this.frame;
534
+ if (!frame || frame.length < 2) return 0;
535
+ const first = Number(frame.x[0]);
536
+ const last = Number(frame.x[frame.length - 1]);
537
+ return Number.isFinite(first) && Number.isFinite(last) ? Math.abs(last - first) : 0;
538
+ }
539
+ /** Formats a y value for the tooltip and the built-in labels. */
540
+ formatValue(value) {
541
+ return new Intl.NumberFormat(this.locale, { maximumFractionDigits: 2 }).format(value);
542
+ }
543
+ render() {
544
+ const legendBefore = this.legend === "top" || this.legend === "start";
545
+ const legendAfter = this.legend === "bottom" || this.legend === "end";
546
+ const side = this.legend === "start" || this.legend === "end";
547
+ return html`
548
+ <div class="frame ${side ? "frame--side" : ""}" part="frame">
549
+ ${legendBefore ? this.renderLegend() : nothing}
550
+ <div class="plot-area" part="plot-area">
551
+ <!-- No bindings inside: Lit never patches this node, so the engine's canvas survives updates. -->
552
+ <div class="plot" part="plot"></div>
553
+ <div class="overlay" part="overlay">
554
+ <div class="tooltip" part="tooltip" role="tooltip" ?hidden=${!this.hoverContext || this.tooltip === "none"}>${this.renderTooltipBody()}</div>
555
+ <div class="actions" part="actions"><slot name="actions"></slot></div>
556
+ </div>
557
+ ${this.renderState()}
558
+ </div>
559
+ ${legendAfter ? this.renderLegend() : nothing}
560
+ </div>
561
+ <div class="theme-probe" aria-hidden="true">${PROBE_COLORS.map(() => html`<i></i>`)}</div>
562
+ <slot class="definitions" @slotchange=${this.#collectSeries}></slot>
563
+ `;
564
+ }
565
+ /** Named slot, then the renderer property, then the built-in rows — the library's three-layer fallback. */
566
+ renderTooltipBody() {
567
+ const context = this.hoverContext;
568
+ return html`<slot name="tooltip">${context ? this.renderTooltip?.(context) ?? this.defaultTooltip(context) : nothing}</slot>`;
569
+ }
570
+ defaultTooltip(context) {
571
+ return html`
572
+ <div class="tooltip-title">${context.formattedX}</div>
573
+ ${context.entries.map((entry) => html`
574
+ <div class="tooltip-row">
575
+ <span class="tooltip-marker" style="background:${entry.color}"></span>
576
+ <span class="tooltip-label">${entry.series.label ?? entry.series.field}</span>
577
+ <span class="tooltip-value">${entry.formatted}</span>
578
+ </div>
579
+ `)}
580
+ `;
581
+ }
582
+ renderState() {
583
+ if (this.error) return html`<div class="state" part="state"><slot name="error">${this.error}</slot></div>`;
584
+ if (this.loading) return html`<div class="state" part="state"><slot name="loading">Loading…</slot></div>`;
585
+ if (!this.frame || this.frame.length === 0) return html`<div class="state" part="state"><slot name="empty">${this.emptyMessage}</slot></div>`;
586
+ return nothing;
587
+ }
588
+ /**
589
+ * What the legend lists. One entry per series for every cartesian chart — but a chart whose data is one
590
+ * dimensional overrides this: a pie has a single series and many slices, and listing "Revenue" above a
591
+ * four-slice donut tells the reader nothing.
592
+ */
593
+ legendItems() {
594
+ return this.resolvedSeries.map((item, index) => ({
595
+ label: item.label ?? item.field,
596
+ color: this.colorOf(item, index),
597
+ visible: !this.hiddenSeries.has(index),
598
+ toggle: () => this.setSeriesVisible(index, this.hiddenSeries.has(index)),
599
+ series: item,
600
+ index
601
+ }));
602
+ }
603
+ renderLegend() {
604
+ return html`
605
+ <div class="legend legend--${this.legend}" part="legend">
606
+ <slot name="legend">
607
+ ${this.legendItems().map((item) => html`
608
+ <button class="legend-item" part="legend-item" type="button" aria-pressed=${item.visible ? "true" : "false"} @click=${item.toggle}>
609
+ ${this.renderLegendItem?.(item.series, item.index) ?? html`
610
+ <span class="legend-marker" part="legend-marker" style="background:${item.color}"></span>
611
+ <span class="legend-label">${item.label}</span>
612
+ `}
613
+ </button>
614
+ `)}
615
+ </slot>
616
+ </div>
617
+ `;
618
+ }
619
+ };
620
+ __decorate([query(".plot")], ChartBase.prototype, "plotElement", void 0);
621
+ __decorate([query(".tooltip")], ChartBase.prototype, "tooltipElement", void 0);
622
+ __decorate([property({ converter: jsonPropertyConverter })], ChartBase.prototype, "data", void 0);
623
+ __decorate([property({ type: Number })], ChartBase.prototype, "revision", void 0);
624
+ __decorate([property({ attribute: false })], ChartBase.prototype, "dataSource", void 0);
625
+ __decorate([property({ converter: jsonPropertyConverter })], ChartBase.prototype, "series", void 0);
626
+ __decorate([property({
627
+ type: String,
628
+ attribute: "x-field"
629
+ })], ChartBase.prototype, "xField", void 0);
630
+ __decorate([property({
631
+ type: String,
632
+ attribute: "label-field"
633
+ })], ChartBase.prototype, "labelField", void 0);
634
+ __decorate([property({
635
+ type: String,
636
+ attribute: "x-type"
637
+ })], ChartBase.prototype, "xType", void 0);
638
+ __decorate([property({ type: String })], ChartBase.prototype, "legend", void 0);
639
+ __decorate([property({ type: String })], ChartBase.prototype, "tooltip", void 0);
640
+ __decorate([property({ type: String })], ChartBase.prototype, "animation", void 0);
641
+ __decorate([property({ type: String })], ChartBase.prototype, "locale", void 0);
642
+ __decorate([property({
643
+ type: Boolean,
644
+ reflect: true
645
+ })], ChartBase.prototype, "loading", void 0);
646
+ __decorate([property({ type: String })], ChartBase.prototype, "error", void 0);
647
+ __decorate([property({
648
+ type: String,
649
+ attribute: "empty-message"
650
+ })], ChartBase.prototype, "emptyMessage", void 0);
651
+ __decorate([property({
652
+ type: Number,
653
+ attribute: "max-points"
654
+ })], ChartBase.prototype, "maxPoints", void 0);
655
+ __decorate([property({
656
+ type: Boolean,
657
+ attribute: "lazy-render"
658
+ })], ChartBase.prototype, "lazyRender", void 0);
659
+ __decorate([property({ attribute: false })], ChartBase.prototype, "renderTooltip", void 0);
660
+ __decorate([property({ attribute: false })], ChartBase.prototype, "renderLegendItem", void 0);
661
+ __decorate([state()], ChartBase.prototype, "seriesElements", void 0);
662
+ __decorate([state()], ChartBase.prototype, "hiddenSeries", void 0);
663
+ __decorate([state()], ChartBase.prototype, "hoverContext", void 0);
664
+ __decorate([state()], ChartBase.prototype, "engineFailed", void 0);
665
+ //#endregion
666
+ export { chart_default as n, ChartBase as t };