@arcfusionz/arc-analytic-ui 0.0.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/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/components/AnomalyCard/AnomalyCard.chart.d.ts +64 -0
- package/dist/components/AnomalyCard/AnomalyCard.chart.js +341 -0
- package/dist/components/AnomalyCard/AnomalyCard.d.ts +169 -0
- package/dist/components/AnomalyCard/AnomalyCard.js +1019 -0
- package/dist/components/AnomalyCard/AnomalyCard.model.d.ts +508 -0
- package/dist/components/AnomalyCard/AnomalyCard.model.js +553 -0
- package/dist/components/AnomalyCard/index.d.ts +4 -0
- package/dist/components/AnomalyCard/index.js +4 -0
- package/dist/components/ChartCard/ChartCard.chart.d.ts +72 -0
- package/dist/components/ChartCard/ChartCard.chart.js +1333 -0
- package/dist/components/ChartCard/ChartCard.d.ts +206 -0
- package/dist/components/ChartCard/ChartCard.js +718 -0
- package/dist/components/ChartCard/ChartCard.model.d.ts +452 -0
- package/dist/components/ChartCard/ChartCard.model.js +1223 -0
- package/dist/components/ChartCard/index.d.ts +4 -0
- package/dist/components/ChartCard/index.js +4 -0
- package/dist/components/ComparisonCard/ComparisonCard.chart.d.ts +80 -0
- package/dist/components/ComparisonCard/ComparisonCard.chart.js +337 -0
- package/dist/components/ComparisonCard/ComparisonCard.d.ts +200 -0
- package/dist/components/ComparisonCard/ComparisonCard.js +1325 -0
- package/dist/components/ComparisonCard/ComparisonCard.model.d.ts +309 -0
- package/dist/components/ComparisonCard/ComparisonCard.model.js +263 -0
- package/dist/components/ComparisonCard/index.d.ts +4 -0
- package/dist/components/ComparisonCard/index.js +4 -0
- package/dist/components/ForecastCard/ForecastCard.chart.d.ts +82 -0
- package/dist/components/ForecastCard/ForecastCard.chart.js +416 -0
- package/dist/components/ForecastCard/ForecastCard.d.ts +148 -0
- package/dist/components/ForecastCard/ForecastCard.js +1029 -0
- package/dist/components/ForecastCard/ForecastCard.model.d.ts +497 -0
- package/dist/components/ForecastCard/ForecastCard.model.js +554 -0
- package/dist/components/ForecastCard/index.d.ts +4 -0
- package/dist/components/ForecastCard/index.js +4 -0
- package/dist/components/HighlightCard/HighlightCard.chart.d.ts +122 -0
- package/dist/components/HighlightCard/HighlightCard.chart.js +660 -0
- package/dist/components/HighlightCard/HighlightCard.d.ts +202 -0
- package/dist/components/HighlightCard/HighlightCard.js +1286 -0
- package/dist/components/HighlightCard/HighlightCard.model.d.ts +692 -0
- package/dist/components/HighlightCard/HighlightCard.model.js +875 -0
- package/dist/components/HighlightCard/index.d.ts +4 -0
- package/dist/components/HighlightCard/index.js +4 -0
- package/dist/components/InsightCard/InsightCard.chart.d.ts +91 -0
- package/dist/components/InsightCard/InsightCard.chart.js +471 -0
- package/dist/components/InsightCard/InsightCard.d.ts +161 -0
- package/dist/components/InsightCard/InsightCard.js +961 -0
- package/dist/components/InsightCard/InsightCard.model.d.ts +405 -0
- package/dist/components/InsightCard/InsightCard.model.js +421 -0
- package/dist/components/InsightCard/index.d.ts +4 -0
- package/dist/components/InsightCard/index.js +4 -0
- package/dist/components/MetricCard/MetricCard.chart.d.ts +79 -0
- package/dist/components/MetricCard/MetricCard.chart.js +435 -0
- package/dist/components/MetricCard/MetricCard.d.ts +227 -0
- package/dist/components/MetricCard/MetricCard.js +1293 -0
- package/dist/components/MetricCard/MetricCard.model.d.ts +521 -0
- package/dist/components/MetricCard/MetricCard.model.js +627 -0
- package/dist/components/MetricCard/index.d.ts +4 -0
- package/dist/components/MetricCard/index.js +4 -0
- package/dist/components/ProfileCard/ProfileCard.chart.d.ts +64 -0
- package/dist/components/ProfileCard/ProfileCard.chart.js +427 -0
- package/dist/components/ProfileCard/ProfileCard.d.ts +140 -0
- package/dist/components/ProfileCard/ProfileCard.js +735 -0
- package/dist/components/ProfileCard/ProfileCard.model.d.ts +279 -0
- package/dist/components/ProfileCard/ProfileCard.model.js +244 -0
- package/dist/components/ProfileCard/index.d.ts +4 -0
- package/dist/components/ProfileCard/index.js +4 -0
- package/dist/components/ProgressCard/ProgressCard.chart.d.ts +73 -0
- package/dist/components/ProgressCard/ProgressCard.chart.js +373 -0
- package/dist/components/ProgressCard/ProgressCard.d.ts +137 -0
- package/dist/components/ProgressCard/ProgressCard.js +908 -0
- package/dist/components/ProgressCard/ProgressCard.model.d.ts +385 -0
- package/dist/components/ProgressCard/ProgressCard.model.js +389 -0
- package/dist/components/ProgressCard/index.d.ts +4 -0
- package/dist/components/ProgressCard/index.js +4 -0
- package/dist/components/ReportCard/ReportCard.chart.d.ts +45 -0
- package/dist/components/ReportCard/ReportCard.chart.js +231 -0
- package/dist/components/ReportCard/ReportCard.d.ts +153 -0
- package/dist/components/ReportCard/ReportCard.js +1118 -0
- package/dist/components/ReportCard/ReportCard.model.d.ts +392 -0
- package/dist/components/ReportCard/ReportCard.model.js +399 -0
- package/dist/components/ReportCard/index.d.ts +4 -0
- package/dist/components/ReportCard/index.js +4 -0
- package/dist/components/SankeyCard/SankeyCard.chart.d.ts +75 -0
- package/dist/components/SankeyCard/SankeyCard.chart.js +249 -0
- package/dist/components/SankeyCard/SankeyCard.d.ts +185 -0
- package/dist/components/SankeyCard/SankeyCard.js +788 -0
- package/dist/components/SankeyCard/SankeyCard.model.d.ts +501 -0
- package/dist/components/SankeyCard/SankeyCard.model.js +789 -0
- package/dist/components/SankeyCard/index.d.ts +4 -0
- package/dist/components/SankeyCard/index.js +4 -0
- package/dist/components/StatusCard/StatusCard.chart.d.ts +60 -0
- package/dist/components/StatusCard/StatusCard.chart.js +188 -0
- package/dist/components/StatusCard/StatusCard.d.ts +176 -0
- package/dist/components/StatusCard/StatusCard.js +989 -0
- package/dist/components/StatusCard/StatusCard.model.d.ts +555 -0
- package/dist/components/StatusCard/StatusCard.model.js +776 -0
- package/dist/components/StatusCard/index.d.ts +4 -0
- package/dist/components/StatusCard/index.js +4 -0
- package/dist/components/TableCard/TableCard.chart.d.ts +53 -0
- package/dist/components/TableCard/TableCard.chart.js +192 -0
- package/dist/components/TableCard/TableCard.d.ts +140 -0
- package/dist/components/TableCard/TableCard.js +811 -0
- package/dist/components/TableCard/TableCard.model.d.ts +381 -0
- package/dist/components/TableCard/TableCard.model.js +475 -0
- package/dist/components/TableCard/index.d.ts +4 -0
- package/dist/components/TableCard/index.js +4 -0
- package/dist/components/TargetCard/TargetCard.chart.d.ts +52 -0
- package/dist/components/TargetCard/TargetCard.chart.js +273 -0
- package/dist/components/TargetCard/TargetCard.d.ts +143 -0
- package/dist/components/TargetCard/TargetCard.js +910 -0
- package/dist/components/TargetCard/TargetCard.model.d.ts +468 -0
- package/dist/components/TargetCard/TargetCard.model.js +581 -0
- package/dist/components/TargetCard/index.d.ts +4 -0
- package/dist/components/TargetCard/index.js +4 -0
- package/dist/components/TreeCard/TreeCard.chart.d.ts +80 -0
- package/dist/components/TreeCard/TreeCard.chart.js +178 -0
- package/dist/components/TreeCard/TreeCard.d.ts +182 -0
- package/dist/components/TreeCard/TreeCard.js +1187 -0
- package/dist/components/TreeCard/TreeCard.model.d.ts +330 -0
- package/dist/components/TreeCard/TreeCard.model.js +401 -0
- package/dist/components/TreeCard/index.d.ts +4 -0
- package/dist/components/TreeCard/index.js +4 -0
- package/dist/components/TrendCard/TrendCard.chart.d.ts +75 -0
- package/dist/components/TrendCard/TrendCard.chart.js +393 -0
- package/dist/components/TrendCard/TrendCard.d.ts +224 -0
- package/dist/components/TrendCard/TrendCard.js +1053 -0
- package/dist/components/TrendCard/TrendCard.model.d.ts +545 -0
- package/dist/components/TrendCard/TrendCard.model.js +623 -0
- package/dist/components/TrendCard/index.d.ts +4 -0
- package/dist/components/TrendCard/index.js +4 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +57 -0
- package/dist/lib/vega/ArcVegaChart.d.ts +24 -0
- package/dist/lib/vega/ArcVegaChart.js +42 -0
- package/dist/lib/vega/ArcVegaSurface.d.ts +13 -0
- package/dist/lib/vega/ArcVegaSurface.js +38 -0
- package/dist/lib/vega/axisTicks.js +156 -0
- package/dist/lib/vega/config.d.ts +29 -0
- package/dist/lib/vega/config.js +113 -0
- package/dist/lib/vega/embed.d.ts +29 -0
- package/dist/lib/vega/embed.js +29 -0
- package/dist/lib/vega/engine.d.ts +10 -0
- package/dist/lib/vega/engine.js +6 -0
- package/dist/lib/vega/formatters.d.ts +125 -0
- package/dist/lib/vega/formatters.js +277 -0
- package/dist/lib/vega/index.d.ts +11 -0
- package/dist/lib/vega/load.d.ts +13 -0
- package/dist/lib/vega/load.js +21 -0
- package/dist/lib/vega/time.d.ts +45 -0
- package/dist/lib/vega/time.js +105 -0
- package/dist/lib/vega/tokens.d.ts +73 -0
- package/dist/lib/vega/tokens.js +137 -0
- package/dist/lib/vega/tooltip.d.ts +45 -0
- package/dist/lib/vega/tooltip.js +124 -0
- package/dist/lib/vega/useArcVega.d.ts +43 -0
- package/dist/lib/vega/useArcVega.js +121 -0
- package/package.json +60 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
//#region src/lib/vega/config.ts
|
|
2
|
+
function withLocale(format, locale) {
|
|
3
|
+
return locale ? `${format}@${locale}` : format;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The Vega-Lite `config` that makes a chart an Arc chart: transparent
|
|
7
|
+
* background, the brand font stacks (Vega draws its own text, so the Thai
|
|
8
|
+
* fallback rides the stack string), a hairline solid grid on `chart-grid`,
|
|
9
|
+
* quiet axes and labels in the muted text role, ranges drawn from the
|
|
10
|
+
* `chart-*` slots, thin quiet marks, ARIA on, and the Intl-backed
|
|
11
|
+
* `arcNumber` / `arcTime` formatters as the default format types.
|
|
12
|
+
*
|
|
13
|
+
* Rebuild it whenever `tokens` change (a theme flip) — it is part of the spec,
|
|
14
|
+
* so that is the one legitimate re-embed.
|
|
15
|
+
*/
|
|
16
|
+
function arcVegaConfig(tokens, { locale, timeZone, vegaLocale } = {}) {
|
|
17
|
+
const timeFormat = [
|
|
18
|
+
"day",
|
|
19
|
+
locale ?? "",
|
|
20
|
+
timeZone ?? ""
|
|
21
|
+
].join("@").replace(/@+$/, "");
|
|
22
|
+
return {
|
|
23
|
+
background: "transparent",
|
|
24
|
+
font: tokens.fontSans,
|
|
25
|
+
view: { stroke: null },
|
|
26
|
+
axis: {
|
|
27
|
+
domainColor: tokens.axis,
|
|
28
|
+
domainWidth: 1,
|
|
29
|
+
gridColor: tokens.grid,
|
|
30
|
+
gridWidth: 1,
|
|
31
|
+
gridOpacity: 1,
|
|
32
|
+
tickColor: tokens.axis,
|
|
33
|
+
tickSize: 4,
|
|
34
|
+
labelColor: tokens.axisLabel,
|
|
35
|
+
labelFont: tokens.fontSans,
|
|
36
|
+
labelFontSize: 11,
|
|
37
|
+
labelPadding: 6,
|
|
38
|
+
labelOverlap: true,
|
|
39
|
+
titleColor: tokens.axisLabel,
|
|
40
|
+
titleFont: tokens.fontHeading,
|
|
41
|
+
titleFontSize: 11,
|
|
42
|
+
titleFontWeight: 500,
|
|
43
|
+
titlePadding: 8
|
|
44
|
+
},
|
|
45
|
+
legend: {
|
|
46
|
+
orient: "right",
|
|
47
|
+
labelColor: tokens.foreground,
|
|
48
|
+
labelFont: tokens.fontSans,
|
|
49
|
+
labelFontSize: 11,
|
|
50
|
+
titleColor: tokens.mutedForeground,
|
|
51
|
+
titleFont: tokens.fontHeading,
|
|
52
|
+
titleFontSize: 11,
|
|
53
|
+
titleFontWeight: 500,
|
|
54
|
+
symbolType: "circle",
|
|
55
|
+
symbolSize: 64
|
|
56
|
+
},
|
|
57
|
+
title: {
|
|
58
|
+
color: tokens.foreground,
|
|
59
|
+
font: tokens.fontHeading,
|
|
60
|
+
fontSize: 14,
|
|
61
|
+
fontWeight: 600,
|
|
62
|
+
anchor: "start",
|
|
63
|
+
subtitleColor: tokens.mutedForeground,
|
|
64
|
+
subtitleFont: tokens.fontSans,
|
|
65
|
+
subtitleFontSize: 12
|
|
66
|
+
},
|
|
67
|
+
range: {
|
|
68
|
+
category: tokens.category,
|
|
69
|
+
ordinal: tokens.sequential,
|
|
70
|
+
ramp: tokens.sequential,
|
|
71
|
+
heatmap: tokens.sequential,
|
|
72
|
+
diverging: [
|
|
73
|
+
tokens.divergingNegative,
|
|
74
|
+
tokens.divergingMid,
|
|
75
|
+
tokens.divergingPositive
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
mark: { color: tokens.emphasis },
|
|
79
|
+
line: {
|
|
80
|
+
strokeWidth: 2,
|
|
81
|
+
strokeCap: "round",
|
|
82
|
+
strokeJoin: "round"
|
|
83
|
+
},
|
|
84
|
+
area: {
|
|
85
|
+
fillOpacity: .12,
|
|
86
|
+
line: false
|
|
87
|
+
},
|
|
88
|
+
bar: { cornerRadiusEnd: 2 },
|
|
89
|
+
rule: {
|
|
90
|
+
color: tokens.reference,
|
|
91
|
+
strokeWidth: 1
|
|
92
|
+
},
|
|
93
|
+
point: {
|
|
94
|
+
size: 64,
|
|
95
|
+
filled: true
|
|
96
|
+
},
|
|
97
|
+
circle: { size: 64 },
|
|
98
|
+
text: {
|
|
99
|
+
color: tokens.foreground,
|
|
100
|
+
font: tokens.fontSans,
|
|
101
|
+
fontSize: 11
|
|
102
|
+
},
|
|
103
|
+
customFormatTypes: true,
|
|
104
|
+
numberFormatType: "arcNumber",
|
|
105
|
+
numberFormat: withLocale("compact", locale),
|
|
106
|
+
timeFormatType: "arcTime",
|
|
107
|
+
timeFormat,
|
|
108
|
+
...vegaLocale ? { locale: vegaLocale } : {},
|
|
109
|
+
aria: true
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { arcVegaConfig };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { TooltipHandler } from "vega";
|
|
2
|
+
import { EmbedOptions } from "vega-embed";
|
|
3
|
+
//#region src/lib/vega/embed.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* `vega.Warn`. The numeric level is used rather than the constant because the
|
|
6
|
+
* constant is not in vega's typings and importing vega here would pull the
|
|
7
|
+
* engine into a module that must stay engine-free.
|
|
8
|
+
*/
|
|
9
|
+
declare const VEGA_WARN = 2;
|
|
10
|
+
interface ArcEmbedOptionsInput {
|
|
11
|
+
/** The bridge's tooltip handler (`useArcTooltipHandler().handler`), or `false` for none. */
|
|
12
|
+
tooltip?: TooltipHandler | false;
|
|
13
|
+
/** `svg` (default) gives an accessibility tree, DPR-crisp output and deterministic snapshots; `canvas` only for a measured case above the budget. */
|
|
14
|
+
renderer?: "svg" | "canvas";
|
|
15
|
+
/** Vega log level. Default `VEGA_WARN` — a warning is a spec bug to fix, never to silence. */
|
|
16
|
+
logLevel?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* vega-embed options for an Arc chart: Vega-Lite mode, no actions menu (an
|
|
20
|
+
* Arc `Menu` calling `view.toImageURL` replaces it), no injected stylesheet
|
|
21
|
+
* (consumer packages ship no CSS), vega-tooltip replaced by the bridge's
|
|
22
|
+
* handler, hover off.
|
|
23
|
+
*
|
|
24
|
+
* **Memoize the result** — react-vega deep-compares options on every render
|
|
25
|
+
* and a fresh object (or a fresh handler function) re-embeds the view.
|
|
26
|
+
*/
|
|
27
|
+
declare function arcEmbedOptions({ tooltip, renderer, logLevel }?: ArcEmbedOptionsInput): EmbedOptions;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { ArcEmbedOptionsInput, VEGA_WARN, arcEmbedOptions };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/lib/vega/embed.ts
|
|
2
|
+
/**
|
|
3
|
+
* `vega.Warn`. The numeric level is used rather than the constant because the
|
|
4
|
+
* constant is not in vega's typings and importing vega here would pull the
|
|
5
|
+
* engine into a module that must stay engine-free.
|
|
6
|
+
*/
|
|
7
|
+
const VEGA_WARN = 2;
|
|
8
|
+
/**
|
|
9
|
+
* vega-embed options for an Arc chart: Vega-Lite mode, no actions menu (an
|
|
10
|
+
* Arc `Menu` calling `view.toImageURL` replaces it), no injected stylesheet
|
|
11
|
+
* (consumer packages ship no CSS), vega-tooltip replaced by the bridge's
|
|
12
|
+
* handler, hover off.
|
|
13
|
+
*
|
|
14
|
+
* **Memoize the result** — react-vega deep-compares options on every render
|
|
15
|
+
* and a fresh object (or a fresh handler function) re-embeds the view.
|
|
16
|
+
*/
|
|
17
|
+
function arcEmbedOptions({ tooltip = false, renderer = "svg", logLevel = 2 } = {}) {
|
|
18
|
+
return {
|
|
19
|
+
mode: "vega-lite",
|
|
20
|
+
renderer,
|
|
21
|
+
actions: false,
|
|
22
|
+
defaultStyle: false,
|
|
23
|
+
hover: false,
|
|
24
|
+
tooltip,
|
|
25
|
+
logLevel
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { VEGA_WARN, arcEmbedOptions };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ArcVegaDatasets, UseArcVegaParams, useArcVega } from "./useArcVega.js";
|
|
2
|
+
import { ArcVegaSurface, ArcVegaSurfaceProps } from "./ArcVegaSurface.js";
|
|
3
|
+
import { changeset, expressionFunction as expressionFunction$1 } from "vega";
|
|
4
|
+
import { compile } from "vega-lite";
|
|
5
|
+
import { VegaEmbed, useVegaEmbed as useVegaEmbed$1 } from "react-vega";
|
|
6
|
+
declare namespace engine_d_exports {
|
|
7
|
+
export { ArcVegaDatasets, ArcVegaSurface, ArcVegaSurfaceProps, UseArcVegaParams, VegaEmbed, changeset, compile, expressionFunction$1 as expressionFunction, useArcVega, useVegaEmbed$1 as useVegaEmbed };
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { type ArcVegaDatasets, ArcVegaSurface, type ArcVegaSurfaceProps, type UseArcVegaParams, VegaEmbed, changeset, compile, engine_d_exports, expressionFunction$1 as expressionFunction, useArcVega, useVegaEmbed$1 as useVegaEmbed };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useArcVega } from "./useArcVega.js";
|
|
2
|
+
import { ArcVegaSurface } from "./ArcVegaSurface.js";
|
|
3
|
+
import { changeset, expressionFunction } from "vega";
|
|
4
|
+
import { compile } from "vega-lite";
|
|
5
|
+
import { VegaEmbed, useVegaEmbed } from "react-vega";
|
|
6
|
+
export { ArcVegaSurface, VegaEmbed, changeset, compile, expressionFunction, useArcVega, useVegaEmbed };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
//#region src/lib/vega/formatters.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* One formatting grammar shared by axes, tooltips, tiles, and tables, so the
|
|
4
|
+
* same value never rounds two ways (Few's precision pitfall). Everything is
|
|
5
|
+
* built on `Intl`, so locale and time zone are first-class, and the two Vega
|
|
6
|
+
* expression functions registered by `registerArcFormatters` call straight
|
|
7
|
+
* into these helpers.
|
|
8
|
+
*
|
|
9
|
+
* Number grammar — `kind[:arg[:arg]][@locale]`:
|
|
10
|
+
*
|
|
11
|
+
* "number" 0–2 fraction digits (Intl decimal) 1,234.5
|
|
12
|
+
* "number:0" fixed maximum fraction digits 1,235
|
|
13
|
+
* "integer" whole numbers 1,235
|
|
14
|
+
* "compact" short scale, 1 fraction digit 3.8M
|
|
15
|
+
* "compact:0" 4M
|
|
16
|
+
* "percent" ratio → percent, 1 fraction digit 12.4%
|
|
17
|
+
* "percent:0" 12%
|
|
18
|
+
* "currency:THB" Intl currency, default digits ฿3,848,305.93
|
|
19
|
+
* "currency:THB:0" fixed digits ฿3,848,306
|
|
20
|
+
* "currency:THB:compact" short scale ฿3.8M
|
|
21
|
+
* "compact@th-TH" any kind, with a locale suffix
|
|
22
|
+
*
|
|
23
|
+
* Time grammar — `granularity[@locale[@timeZone]]`, granularity one of
|
|
24
|
+
* `day` (8 Sep 2026), `month` (Sep 2026), `year`, `time` (16:30),
|
|
25
|
+
* `datetime` (8 Sep 2026, 16:30), plus the axis-length forms `day-short`
|
|
26
|
+
* (8 Sep), `day-time` (8 Sep, 4 PM) and `month-short` (Sep) for tick labels
|
|
27
|
+
* that have no room for a year — `day-time` is the one a window shorter than
|
|
28
|
+
* two days needs, where a bare clock time repeats at both ends. It carries the
|
|
29
|
+
* hour only: minutes on an axis label are noise, they push the text past the
|
|
30
|
+
* width an axis label is allowed, and the tooltip has them anyway. Thai products that use the Gregorian calendar pass
|
|
31
|
+
* `th-TH-u-ca-gregory`; a bare `th-TH` defaults to the Buddhist calendar.
|
|
32
|
+
*/
|
|
33
|
+
/** Rendered for null, undefined, NaN and infinite values — a typographic dash, never "0". */
|
|
34
|
+
declare const MISSING_VALUE = "—";
|
|
35
|
+
type ArcNumberFormatKind = "number" | "integer" | "compact" | "percent" | "currency";
|
|
36
|
+
interface ArcNumberFormatSpec {
|
|
37
|
+
kind: ArcNumberFormatKind;
|
|
38
|
+
/** Maximum fraction digits, when the format fixes them. */
|
|
39
|
+
digits?: number;
|
|
40
|
+
/** Short-scale notation, for currency formats (`currency:THB:compact`). */
|
|
41
|
+
compact?: boolean;
|
|
42
|
+
/** ISO 4217 code for currency formats. */
|
|
43
|
+
currency?: string;
|
|
44
|
+
/** BCP 47 tag from the `@locale` suffix. */
|
|
45
|
+
locale?: string;
|
|
46
|
+
}
|
|
47
|
+
type ArcTimeGranularity = "day" | "month" | "year" | "time" | "datetime" | "day-short" | "day-time" | "month-short";
|
|
48
|
+
interface ArcTimeFormatSpec {
|
|
49
|
+
granularity: ArcTimeGranularity;
|
|
50
|
+
locale?: string;
|
|
51
|
+
timeZone?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Parses the number grammar. Unknown kinds fall back to `number` rather than throwing — a bad format string must not take a chart down. */
|
|
54
|
+
declare function parseArcNumberFormat(format: string | undefined | null): ArcNumberFormatSpec;
|
|
55
|
+
/** Parses the time grammar. */
|
|
56
|
+
declare function parseArcTimeFormat(format: string | undefined | null): ArcTimeFormatSpec;
|
|
57
|
+
/**
|
|
58
|
+
* Formats a number through the grammar above. `extra` merges Intl options on
|
|
59
|
+
* top (deltas pass `{ signDisplay: "exceptZero" }`); a missing or non-finite
|
|
60
|
+
* value renders as `MISSING_VALUE`.
|
|
61
|
+
*/
|
|
62
|
+
declare function formatNumber(value: number | null | undefined, format?: string, locale?: string, extra?: Intl.NumberFormatOptions): string;
|
|
63
|
+
/**
|
|
64
|
+
* Formats a date at a granularity. `timeZone` defaults to the runtime's; pass
|
|
65
|
+
* it explicitly wherever output must be deterministic (Chromatic, tests, or a
|
|
66
|
+
* product that reports in one business time zone).
|
|
67
|
+
*/
|
|
68
|
+
declare function formatDate(value: Date | string | number | null | undefined, { granularity, locale, timeZone }?: Partial<ArcTimeFormatSpec>): string;
|
|
69
|
+
/**
|
|
70
|
+
* Formats a period between two dates at a granularity, collapsing the parts
|
|
71
|
+
* they share the way the locale does — `Aug 7 – 9, 2026`, `Aug 28 – Sep 8,
|
|
72
|
+
* 2026`, `7–9 ส.ค. 2026` — through `Intl.DateTimeFormat.formatRange`, with
|
|
73
|
+
* `start – end` as the fallback where a runtime lacks it. The bounds may come
|
|
74
|
+
* in either order; an unparseable bound renders as `MISSING_VALUE`.
|
|
75
|
+
*/
|
|
76
|
+
declare function formatDateRange(start: Date | string | number | null | undefined, end: Date | string | number | null | undefined, { granularity, locale, timeZone }?: Partial<ArcTimeFormatSpec>): string;
|
|
77
|
+
type ArcDeltaMode = "percent" | "absolute";
|
|
78
|
+
type ArcDeltaDirection = "up" | "down" | "flat";
|
|
79
|
+
interface FormatDeltaOptions {
|
|
80
|
+
/** `percent` (default) is relative change; `absolute` is the difference in the value's own units. */
|
|
81
|
+
mode?: ArcDeltaMode;
|
|
82
|
+
/** The value's format — an absolute delta of a `percent` value is expressed in percentage points. */
|
|
83
|
+
format?: string;
|
|
84
|
+
locale?: string;
|
|
85
|
+
/** Fraction digits for a percent delta. Default 1. */
|
|
86
|
+
digits?: number;
|
|
87
|
+
/** Unit appended to a percentage-point delta. Default `" pp"`. */
|
|
88
|
+
pointsSuffix?: string;
|
|
89
|
+
}
|
|
90
|
+
interface FormattedDelta {
|
|
91
|
+
direction: ArcDeltaDirection;
|
|
92
|
+
/** Relative change as a ratio, or `null` when the previous value is zero (undefined). */
|
|
93
|
+
percent: number | null;
|
|
94
|
+
/** `current - previous`, in the value's units. */
|
|
95
|
+
absolute: number;
|
|
96
|
+
/** Signed text, e.g. `+12.4%`, `-0.3 pp`, `+฿120K`. */
|
|
97
|
+
text: string;
|
|
98
|
+
/** Which mode actually rendered: a percent delta from zero falls back to absolute. */
|
|
99
|
+
renderedMode: ArcDeltaMode;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Formats the change between two readings with the sign always shown. A
|
|
103
|
+
* relative change from zero is undefined, so `mode: "percent"` renders the
|
|
104
|
+
* absolute difference instead (and says so in `renderedMode`). An absolute
|
|
105
|
+
* delta of a percent-formatted value is in percentage points — never "-7%"
|
|
106
|
+
* for churn going from 4.1% to 3.8%.
|
|
107
|
+
*/
|
|
108
|
+
declare function formatDelta(current: number, previous: number, { mode, format, locale, digits, pointsSuffix }?: FormatDeltaOptions): FormattedDelta;
|
|
109
|
+
type ExpressionFunctionRegistrar = (name: string, fn: (...args: never[]) => unknown) => unknown;
|
|
110
|
+
/**
|
|
111
|
+
* Registers `arcNumber`, `arcTime` and the responsive axis helpers
|
|
112
|
+
* `arcAxisTicks` / `arcAxisLabelAlign` as Vega expression functions, once.
|
|
113
|
+
* Takes `vega.expressionFunction` as an argument so this module never imports
|
|
114
|
+
* the engine itself; the engine-bound modules call it at load time, before the
|
|
115
|
+
* first `parse` — Vega requires that. Returns whether this call did the
|
|
116
|
+
* registering.
|
|
117
|
+
*
|
|
118
|
+
* Both axis helpers take `(domain, width, discrete, format, kind, anchors?)`:
|
|
119
|
+
* `kind` picks the label formatter (`time` → `arcTime`, `number` →
|
|
120
|
+
* `arcNumber`, else the raw category), and `anchors` — a highlighted window's
|
|
121
|
+
* `[start, end]` — switches from evenly spaced labels to the window's bounds.
|
|
122
|
+
*/
|
|
123
|
+
declare function registerArcFormatters(expressionFunction: ExpressionFunctionRegistrar): boolean;
|
|
124
|
+
//#endregion
|
|
125
|
+
export { ArcDeltaDirection, ArcDeltaMode, ArcNumberFormatKind, ArcNumberFormatSpec, ArcTimeFormatSpec, ArcTimeGranularity, FormatDeltaOptions, FormattedDelta, MISSING_VALUE, formatDate, formatDateRange, formatDelta, formatNumber, parseArcNumberFormat, parseArcTimeFormat, registerArcFormatters };
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { axisLabelAlign, selectAxisTicks } from "./axisTicks.js";
|
|
2
|
+
//#region src/lib/vega/formatters.ts
|
|
3
|
+
/**
|
|
4
|
+
* One formatting grammar shared by axes, tooltips, tiles, and tables, so the
|
|
5
|
+
* same value never rounds two ways (Few's precision pitfall). Everything is
|
|
6
|
+
* built on `Intl`, so locale and time zone are first-class, and the two Vega
|
|
7
|
+
* expression functions registered by `registerArcFormatters` call straight
|
|
8
|
+
* into these helpers.
|
|
9
|
+
*
|
|
10
|
+
* Number grammar — `kind[:arg[:arg]][@locale]`:
|
|
11
|
+
*
|
|
12
|
+
* "number" 0–2 fraction digits (Intl decimal) 1,234.5
|
|
13
|
+
* "number:0" fixed maximum fraction digits 1,235
|
|
14
|
+
* "integer" whole numbers 1,235
|
|
15
|
+
* "compact" short scale, 1 fraction digit 3.8M
|
|
16
|
+
* "compact:0" 4M
|
|
17
|
+
* "percent" ratio → percent, 1 fraction digit 12.4%
|
|
18
|
+
* "percent:0" 12%
|
|
19
|
+
* "currency:THB" Intl currency, default digits ฿3,848,305.93
|
|
20
|
+
* "currency:THB:0" fixed digits ฿3,848,306
|
|
21
|
+
* "currency:THB:compact" short scale ฿3.8M
|
|
22
|
+
* "compact@th-TH" any kind, with a locale suffix
|
|
23
|
+
*
|
|
24
|
+
* Time grammar — `granularity[@locale[@timeZone]]`, granularity one of
|
|
25
|
+
* `day` (8 Sep 2026), `month` (Sep 2026), `year`, `time` (16:30),
|
|
26
|
+
* `datetime` (8 Sep 2026, 16:30), plus the axis-length forms `day-short`
|
|
27
|
+
* (8 Sep), `day-time` (8 Sep, 4 PM) and `month-short` (Sep) for tick labels
|
|
28
|
+
* that have no room for a year — `day-time` is the one a window shorter than
|
|
29
|
+
* two days needs, where a bare clock time repeats at both ends. It carries the
|
|
30
|
+
* hour only: minutes on an axis label are noise, they push the text past the
|
|
31
|
+
* width an axis label is allowed, and the tooltip has them anyway. Thai products that use the Gregorian calendar pass
|
|
32
|
+
* `th-TH-u-ca-gregory`; a bare `th-TH` defaults to the Buddhist calendar.
|
|
33
|
+
*/
|
|
34
|
+
/** Rendered for null, undefined, NaN and infinite values — a typographic dash, never "0". */
|
|
35
|
+
const MISSING_VALUE = "—";
|
|
36
|
+
const NUMBER_KINDS = [
|
|
37
|
+
"number",
|
|
38
|
+
"integer",
|
|
39
|
+
"compact",
|
|
40
|
+
"percent",
|
|
41
|
+
"currency"
|
|
42
|
+
];
|
|
43
|
+
const TIME_GRANULARITIES = [
|
|
44
|
+
"day",
|
|
45
|
+
"month",
|
|
46
|
+
"year",
|
|
47
|
+
"time",
|
|
48
|
+
"datetime",
|
|
49
|
+
"day-short",
|
|
50
|
+
"day-time",
|
|
51
|
+
"month-short"
|
|
52
|
+
];
|
|
53
|
+
/** Parses the number grammar. Unknown kinds fall back to `number` rather than throwing — a bad format string must not take a chart down. */
|
|
54
|
+
function parseArcNumberFormat(format) {
|
|
55
|
+
const [body = "", locale] = String(format ?? "number").split("@");
|
|
56
|
+
const [rawKind = "number", ...args] = body.split(":");
|
|
57
|
+
const kind = NUMBER_KINDS.includes(rawKind) ? rawKind : "number";
|
|
58
|
+
const spec = { kind };
|
|
59
|
+
if (locale) spec.locale = locale;
|
|
60
|
+
let rest = args;
|
|
61
|
+
if (kind === "currency") {
|
|
62
|
+
const [code, ...others] = args;
|
|
63
|
+
if (code) spec.currency = code.toUpperCase();
|
|
64
|
+
rest = others;
|
|
65
|
+
}
|
|
66
|
+
for (const arg of rest) if (/^\d+$/.test(arg)) spec.digits = Number(arg);
|
|
67
|
+
else if (arg === "compact") spec.compact = true;
|
|
68
|
+
return spec;
|
|
69
|
+
}
|
|
70
|
+
/** Parses the time grammar. */
|
|
71
|
+
function parseArcTimeFormat(format) {
|
|
72
|
+
const [rawGranularity = "day", locale, timeZone] = String(format ?? "day").split("@");
|
|
73
|
+
const spec = { granularity: TIME_GRANULARITIES.includes(rawGranularity) ? rawGranularity : "day" };
|
|
74
|
+
if (locale) spec.locale = locale;
|
|
75
|
+
if (timeZone) spec.timeZone = timeZone;
|
|
76
|
+
return spec;
|
|
77
|
+
}
|
|
78
|
+
const numberFormatCache = /* @__PURE__ */ new Map();
|
|
79
|
+
const dateFormatCache = /* @__PURE__ */ new Map();
|
|
80
|
+
function numberOptions(spec) {
|
|
81
|
+
switch (spec.kind) {
|
|
82
|
+
case "integer": return { maximumFractionDigits: 0 };
|
|
83
|
+
case "compact": return {
|
|
84
|
+
notation: "compact",
|
|
85
|
+
compactDisplay: "short",
|
|
86
|
+
maximumFractionDigits: spec.digits ?? 1
|
|
87
|
+
};
|
|
88
|
+
case "percent": return {
|
|
89
|
+
style: "percent",
|
|
90
|
+
maximumFractionDigits: spec.digits ?? 1
|
|
91
|
+
};
|
|
92
|
+
case "currency": {
|
|
93
|
+
const options = {
|
|
94
|
+
style: "currency",
|
|
95
|
+
currency: spec.currency ?? "USD",
|
|
96
|
+
currencyDisplay: "narrowSymbol"
|
|
97
|
+
};
|
|
98
|
+
if (spec.compact) {
|
|
99
|
+
options.notation = "compact";
|
|
100
|
+
options.compactDisplay = "short";
|
|
101
|
+
}
|
|
102
|
+
if (spec.digits != null || spec.compact) {
|
|
103
|
+
options.minimumFractionDigits = 0;
|
|
104
|
+
options.maximumFractionDigits = spec.digits ?? (spec.compact ? 1 : 0);
|
|
105
|
+
}
|
|
106
|
+
return options;
|
|
107
|
+
}
|
|
108
|
+
default: return { maximumFractionDigits: spec.digits ?? 2 };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function getNumberFormat(spec, locale, extra) {
|
|
112
|
+
const resolvedLocale = spec.locale ?? locale;
|
|
113
|
+
const options = {
|
|
114
|
+
...numberOptions(spec),
|
|
115
|
+
...extra
|
|
116
|
+
};
|
|
117
|
+
const key = `${resolvedLocale ?? ""}|${JSON.stringify(options)}`;
|
|
118
|
+
let formatter = numberFormatCache.get(key);
|
|
119
|
+
if (!formatter) {
|
|
120
|
+
try {
|
|
121
|
+
formatter = new Intl.NumberFormat(resolvedLocale, options);
|
|
122
|
+
} catch {
|
|
123
|
+
formatter = new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 });
|
|
124
|
+
}
|
|
125
|
+
numberFormatCache.set(key, formatter);
|
|
126
|
+
}
|
|
127
|
+
return formatter;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Formats a number through the grammar above. `extra` merges Intl options on
|
|
131
|
+
* top (deltas pass `{ signDisplay: "exceptZero" }`); a missing or non-finite
|
|
132
|
+
* value renders as `MISSING_VALUE`.
|
|
133
|
+
*/
|
|
134
|
+
function formatNumber(value, format = "number", locale, extra) {
|
|
135
|
+
if (value == null || !Number.isFinite(value)) return "—";
|
|
136
|
+
return getNumberFormat(parseArcNumberFormat(format), locale, extra).format(value);
|
|
137
|
+
}
|
|
138
|
+
function toDate(value) {
|
|
139
|
+
return value instanceof Date ? value : new Date(value);
|
|
140
|
+
}
|
|
141
|
+
const TIME_OPTIONS = {
|
|
142
|
+
day: {
|
|
143
|
+
day: "numeric",
|
|
144
|
+
month: "short",
|
|
145
|
+
year: "numeric"
|
|
146
|
+
},
|
|
147
|
+
month: {
|
|
148
|
+
month: "short",
|
|
149
|
+
year: "numeric"
|
|
150
|
+
},
|
|
151
|
+
year: { year: "numeric" },
|
|
152
|
+
time: {
|
|
153
|
+
hour: "2-digit",
|
|
154
|
+
minute: "2-digit"
|
|
155
|
+
},
|
|
156
|
+
datetime: {
|
|
157
|
+
day: "numeric",
|
|
158
|
+
month: "short",
|
|
159
|
+
year: "numeric",
|
|
160
|
+
hour: "2-digit",
|
|
161
|
+
minute: "2-digit"
|
|
162
|
+
},
|
|
163
|
+
"day-short": {
|
|
164
|
+
day: "numeric",
|
|
165
|
+
month: "short"
|
|
166
|
+
},
|
|
167
|
+
"day-time": {
|
|
168
|
+
day: "numeric",
|
|
169
|
+
month: "short",
|
|
170
|
+
hour: "numeric"
|
|
171
|
+
},
|
|
172
|
+
"month-short": { month: "short" }
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Formats a date at a granularity. `timeZone` defaults to the runtime's; pass
|
|
176
|
+
* it explicitly wherever output must be deterministic (Chromatic, tests, or a
|
|
177
|
+
* product that reports in one business time zone).
|
|
178
|
+
*/
|
|
179
|
+
function formatDate(value, { granularity = "day", locale, timeZone } = {}) {
|
|
180
|
+
if (value == null) return "—";
|
|
181
|
+
const date = toDate(value);
|
|
182
|
+
if (Number.isNaN(date.getTime())) return "—";
|
|
183
|
+
return getDateFormat(granularity, locale, timeZone).format(date);
|
|
184
|
+
}
|
|
185
|
+
function getDateFormat(granularity, locale, timeZone) {
|
|
186
|
+
const key = `${locale ?? ""}|${timeZone ?? ""}|${granularity}`;
|
|
187
|
+
let formatter = dateFormatCache.get(key);
|
|
188
|
+
if (!formatter) {
|
|
189
|
+
try {
|
|
190
|
+
formatter = new Intl.DateTimeFormat(locale, {
|
|
191
|
+
...TIME_OPTIONS[granularity],
|
|
192
|
+
timeZone
|
|
193
|
+
});
|
|
194
|
+
} catch {
|
|
195
|
+
formatter = new Intl.DateTimeFormat(void 0, TIME_OPTIONS[granularity]);
|
|
196
|
+
}
|
|
197
|
+
dateFormatCache.set(key, formatter);
|
|
198
|
+
}
|
|
199
|
+
return formatter;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Formats a period between two dates at a granularity, collapsing the parts
|
|
203
|
+
* they share the way the locale does — `Aug 7 – 9, 2026`, `Aug 28 – Sep 8,
|
|
204
|
+
* 2026`, `7–9 ส.ค. 2026` — through `Intl.DateTimeFormat.formatRange`, with
|
|
205
|
+
* `start – end` as the fallback where a runtime lacks it. The bounds may come
|
|
206
|
+
* in either order; an unparseable bound renders as `MISSING_VALUE`.
|
|
207
|
+
*/
|
|
208
|
+
function formatDateRange(start, end, { granularity = "day", locale, timeZone } = {}) {
|
|
209
|
+
if (start == null || end == null) return "—";
|
|
210
|
+
const a = toDate(start);
|
|
211
|
+
const b = toDate(end);
|
|
212
|
+
if (Number.isNaN(a.getTime()) || Number.isNaN(b.getTime())) return "—";
|
|
213
|
+
const [from, to] = a.getTime() <= b.getTime() ? [a, b] : [b, a];
|
|
214
|
+
const formatter = getDateFormat(granularity, locale, timeZone);
|
|
215
|
+
if (typeof formatter.formatRange === "function") try {
|
|
216
|
+
return formatter.formatRange(from, to);
|
|
217
|
+
} catch {}
|
|
218
|
+
return `${formatter.format(from)} – ${formatter.format(to)}`;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Formats the change between two readings with the sign always shown. A
|
|
222
|
+
* relative change from zero is undefined, so `mode: "percent"` renders the
|
|
223
|
+
* absolute difference instead (and says so in `renderedMode`). An absolute
|
|
224
|
+
* delta of a percent-formatted value is in percentage points — never "-7%"
|
|
225
|
+
* for churn going from 4.1% to 3.8%.
|
|
226
|
+
*/
|
|
227
|
+
function formatDelta(current, previous, { mode = "percent", format = "number", locale, digits = 1, pointsSuffix = " pp" } = {}) {
|
|
228
|
+
const absolute = current - previous;
|
|
229
|
+
const direction = absolute > 0 ? "up" : absolute < 0 ? "down" : "flat";
|
|
230
|
+
const percent = previous === 0 ? null : absolute / Math.abs(previous);
|
|
231
|
+
const signed = { signDisplay: "exceptZero" };
|
|
232
|
+
if (mode === "percent" && percent != null) return {
|
|
233
|
+
direction,
|
|
234
|
+
percent,
|
|
235
|
+
absolute,
|
|
236
|
+
renderedMode: "percent",
|
|
237
|
+
text: formatNumber(percent, `percent:${digits}`, locale, signed)
|
|
238
|
+
};
|
|
239
|
+
const valueSpec = parseArcNumberFormat(format);
|
|
240
|
+
return {
|
|
241
|
+
direction,
|
|
242
|
+
percent,
|
|
243
|
+
absolute,
|
|
244
|
+
renderedMode: "absolute",
|
|
245
|
+
text: valueSpec.kind === "percent" ? `${formatNumber(absolute * 100, `number:${valueSpec.digits ?? 1}`, locale, signed)}${pointsSuffix}` : formatNumber(absolute, format, locale, signed)
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
let registered = false;
|
|
249
|
+
/**
|
|
250
|
+
* Registers `arcNumber`, `arcTime` and the responsive axis helpers
|
|
251
|
+
* `arcAxisTicks` / `arcAxisLabelAlign` as Vega expression functions, once.
|
|
252
|
+
* Takes `vega.expressionFunction` as an argument so this module never imports
|
|
253
|
+
* the engine itself; the engine-bound modules call it at load time, before the
|
|
254
|
+
* first `parse` — Vega requires that. Returns whether this call did the
|
|
255
|
+
* registering.
|
|
256
|
+
*
|
|
257
|
+
* Both axis helpers take `(domain, width, discrete, format, kind, anchors?)`:
|
|
258
|
+
* `kind` picks the label formatter (`time` → `arcTime`, `number` →
|
|
259
|
+
* `arcNumber`, else the raw category), and `anchors` — a highlighted window's
|
|
260
|
+
* `[start, end]` — switches from evenly spaced labels to the window's bounds.
|
|
261
|
+
*/
|
|
262
|
+
function registerArcFormatters(expressionFunction) {
|
|
263
|
+
if (registered) return false;
|
|
264
|
+
registered = true;
|
|
265
|
+
const arcNumber = (value, format) => formatNumber(typeof value === "number" ? value : Number(value), String(format ?? "number"));
|
|
266
|
+
const arcTime = (value, format) => formatDate(value, parseArcTimeFormat(String(format ?? "day")));
|
|
267
|
+
const labelFormatter = (format, kind) => (value) => kind === "time" ? arcTime(value, format) : kind === "number" ? arcNumber(value, format) : String(value);
|
|
268
|
+
const arcAxisTicks = (domain, width, discrete, format, kind, anchors) => selectAxisTicks(domain, width, discrete, labelFormatter(format, kind), anchors);
|
|
269
|
+
const arcAxisLabelAlign = (value, domain, width, discrete, format, kind, anchors) => axisLabelAlign(value, domain, width, discrete, labelFormatter(format, kind), anchors);
|
|
270
|
+
expressionFunction("arcNumber", arcNumber);
|
|
271
|
+
expressionFunction("arcTime", arcTime);
|
|
272
|
+
expressionFunction("arcAxisTicks", arcAxisTicks);
|
|
273
|
+
expressionFunction("arcAxisLabelAlign", arcAxisLabelAlign);
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
export { MISSING_VALUE, formatDate, formatDateRange, formatDelta, formatNumber, parseArcNumberFormat, parseArcTimeFormat, registerArcFormatters };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ArcDeltaDirection, ArcDeltaMode, ArcNumberFormatKind, ArcNumberFormatSpec, ArcTimeFormatSpec, ArcTimeGranularity, FormatDeltaOptions, FormattedDelta, MISSING_VALUE, formatDate, formatDateRange, formatDelta, formatNumber, parseArcNumberFormat, parseArcTimeFormat, registerArcFormatters } from "./formatters.js";
|
|
2
|
+
import { ChartTokens, readChartTokens, useChartTokens } from "./tokens.js";
|
|
3
|
+
import { ArcVegaConfigOptions, arcVegaConfig } from "./config.js";
|
|
4
|
+
import { ZonedParts, resolveInstant, timeZoneOffsetMs, zonedDayStart, zonedMidnight, zonedParts } from "./time.js";
|
|
5
|
+
import { ArcTooltipContext, ArcTooltipHandle, ArcTooltipRows, UseArcTooltipHandlerOptions, useArcTooltipHandler } from "./tooltip.js";
|
|
6
|
+
import { ArcEmbedOptionsInput, VEGA_WARN, arcEmbedOptions } from "./embed.js";
|
|
7
|
+
import { ArcVegaDatasets, UseArcVegaParams } from "./useArcVega.js";
|
|
8
|
+
import { ArcVegaSurfaceProps } from "./ArcVegaSurface.js";
|
|
9
|
+
import { ArcEngine, getLoadedEngine, loadEngine } from "./load.js";
|
|
10
|
+
import { ArcVegaChart, ArcVegaChartProps, useArcEngine } from "./ArcVegaChart.js";
|
|
11
|
+
export { type ArcDeltaDirection, type ArcDeltaMode, type ArcEmbedOptionsInput, type ArcEngine, type ArcNumberFormatKind, type ArcNumberFormatSpec, type ArcTimeFormatSpec, type ArcTimeGranularity, type ArcTooltipContext, type ArcTooltipHandle, ArcTooltipRows, ArcVegaChart, type ArcVegaChartProps, type ArcVegaConfigOptions, type ArcVegaDatasets, type ArcVegaSurfaceProps, type ChartTokens, type FormatDeltaOptions, type FormattedDelta, MISSING_VALUE, type UseArcTooltipHandlerOptions, type UseArcVegaParams, VEGA_WARN, type ZonedParts, arcEmbedOptions, arcVegaConfig, formatDate, formatDateRange, formatDelta, formatNumber, getLoadedEngine, loadEngine, parseArcNumberFormat, parseArcTimeFormat, readChartTokens, registerArcFormatters, resolveInstant, timeZoneOffsetMs, useArcEngine, useArcTooltipHandler, useChartTokens, zonedDayStart, zonedMidnight, zonedParts };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { engine_d_exports } from "./engine.js";
|
|
2
|
+
//#region src/lib/vega/load.d.ts
|
|
3
|
+
type ArcEngine = typeof engine_d_exports;
|
|
4
|
+
/**
|
|
5
|
+
* Loads the engine chunk once and shares the promise. Components render their
|
|
6
|
+
* frame, title and `Skeleton` immediately and mount the chart when this
|
|
7
|
+
* resolves.
|
|
8
|
+
*/
|
|
9
|
+
declare function loadEngine(): Promise<ArcEngine>;
|
|
10
|
+
/** The engine if a previous `loadEngine()` already resolved — lets later mounts skip the fallback frame. */
|
|
11
|
+
declare function getLoadedEngine(): ArcEngine | null;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { ArcEngine, getLoadedEngine, loadEngine };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/lib/vega/load.ts
|
|
2
|
+
let pending = null;
|
|
3
|
+
let resolved = null;
|
|
4
|
+
/**
|
|
5
|
+
* Loads the engine chunk once and shares the promise. Components render their
|
|
6
|
+
* frame, title and `Skeleton` immediately and mount the chart when this
|
|
7
|
+
* resolves.
|
|
8
|
+
*/
|
|
9
|
+
function loadEngine() {
|
|
10
|
+
pending ??= import("./engine.js").then((engine) => {
|
|
11
|
+
resolved = engine;
|
|
12
|
+
return engine;
|
|
13
|
+
});
|
|
14
|
+
return pending;
|
|
15
|
+
}
|
|
16
|
+
/** The engine if a previous `loadEngine()` already resolved — lets later mounts skip the fallback frame. */
|
|
17
|
+
function getLoadedEngine() {
|
|
18
|
+
return resolved;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getLoadedEngine, loadEngine };
|