@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,4 @@
|
|
|
1
|
+
import { BuildChartDescriptionInput, CHART_OTHER_KEY, CHART_TABLE_ROW_CAP, CHART_TYPES, CHART_TYPE_ORDER, ChartAggregate, ChartCardLabels, ChartCardSize, ChartCardState, ChartCardStatus, ChartColorMode, ChartExtent, ChartExtremes, ChartFieldType, ChartIntent, ChartLegendKind, ChartRampBucket, ChartRecord, ChartRow, ChartSeriesColor, ChartSeriesInfo, ChartSort, ChartSummary, ChartTableColumn, ChartTableModel, ChartTextFormatters, ChartType, ChartTypeFields, ChartTypeInfo, ChartWebRow, CreateChartFormattersOptions, DEFAULT_CHART_LABELS, DeriveChartStateInput, NormalizeChartDataOptions, RADAR_RING_FRACTIONS, buildChartDescription, buildChartPlotDescription, buildChartTableModel, buildRadarWebRows, buildRampBuckets, chartSeriesColorAt, createChartFormatters, deriveChartState, hasEnoughData, inferFieldType, inferGranularity, missingChartFields, normalizeChartData, resolveChartColorMode, resolveChartLabels } from "./ChartCard.model.js";
|
|
2
|
+
import { ChartCard, ChartCardProps, ChartLegendPosition, ChartTableToggle } from "./ChartCard.js";
|
|
3
|
+
import { CHART_AXES_DATASET, CHART_HOVER_PARAM, CHART_SERIES_NAMES_PARAM, CHART_TABLE_DATASET, CHART_X_TICKS_PARAM, ChartSpecOptions, buildChartSpec } from "./ChartCard.chart.js";
|
|
4
|
+
export { type BuildChartDescriptionInput, CHART_AXES_DATASET, CHART_HOVER_PARAM, CHART_OTHER_KEY, CHART_SERIES_NAMES_PARAM, CHART_TABLE_DATASET, CHART_TABLE_ROW_CAP, CHART_TYPES, CHART_TYPE_ORDER, CHART_X_TICKS_PARAM, type ChartAggregate, ChartCard, type ChartCardLabels, type ChartCardProps, type ChartCardSize, type ChartCardState, type ChartCardStatus, type ChartColorMode, type ChartExtent, type ChartExtremes, type ChartFieldType, type ChartIntent, type ChartLegendKind, type ChartLegendPosition, type ChartRampBucket, type ChartRecord, type ChartRow, type ChartSeriesColor, type ChartSeriesInfo, type ChartSort, type ChartSpecOptions, type ChartSummary, type ChartTableColumn, type ChartTableModel, type ChartTableToggle, type ChartTextFormatters, type ChartType, type ChartTypeFields, type ChartTypeInfo, type ChartWebRow, type CreateChartFormattersOptions, DEFAULT_CHART_LABELS, type DeriveChartStateInput, type NormalizeChartDataOptions, RADAR_RING_FRACTIONS, buildChartDescription, buildChartPlotDescription, buildChartSpec, buildChartTableModel, buildRadarWebRows, buildRampBuckets, chartSeriesColorAt, createChartFormatters, deriveChartState, hasEnoughData, inferFieldType, inferGranularity, missingChartFields, normalizeChartData, resolveChartColorMode, resolveChartLabels };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CHART_OTHER_KEY, CHART_TABLE_ROW_CAP, CHART_TYPES, CHART_TYPE_ORDER, DEFAULT_CHART_LABELS, RADAR_RING_FRACTIONS, buildChartDescription, buildChartPlotDescription, buildChartTableModel, buildRadarWebRows, buildRampBuckets, chartSeriesColorAt, createChartFormatters, deriveChartState, hasEnoughData, inferFieldType, inferGranularity, missingChartFields, normalizeChartData, resolveChartColorMode, resolveChartLabels } from "./ChartCard.model.js";
|
|
2
|
+
import { CHART_AXES_DATASET, CHART_HOVER_PARAM, CHART_SERIES_NAMES_PARAM, CHART_TABLE_DATASET, CHART_X_TICKS_PARAM, buildChartSpec } from "./ChartCard.chart.js";
|
|
3
|
+
import { ChartCard } from "./ChartCard.js";
|
|
4
|
+
export { CHART_AXES_DATASET, CHART_HOVER_PARAM, CHART_OTHER_KEY, CHART_SERIES_NAMES_PARAM, CHART_TABLE_DATASET, CHART_TABLE_ROW_CAP, CHART_TYPES, CHART_TYPE_ORDER, CHART_X_TICKS_PARAM, ChartCard, DEFAULT_CHART_LABELS, RADAR_RING_FRACTIONS, buildChartDescription, buildChartPlotDescription, buildChartSpec, buildChartTableModel, buildRadarWebRows, buildRampBuckets, chartSeriesColorAt, createChartFormatters, deriveChartState, hasEnoughData, inferFieldType, inferGranularity, missingChartFields, normalizeChartData, resolveChartColorMode, resolveChartLabels };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ChartTokens } from "../../lib/vega/tokens.js";
|
|
2
|
+
import { ComparisonMark, ComparisonScale } from "./ComparisonCard.model.js";
|
|
3
|
+
import { TopLevelSpec } from "vega-lite";
|
|
4
|
+
//#region src/components/ComparisonCard/ComparisonCard.chart.d.ts
|
|
5
|
+
/** The rows: `{ key, label, value, from, role }` per `ComparisonRow`, in display order. */
|
|
6
|
+
declare const COMPARISON_TABLE_DATASET = "table";
|
|
7
|
+
/** Zero or one row `{ value }` — the target reference rule. */
|
|
8
|
+
declare const COMPARISON_REFERENCE_DATASET = "reference";
|
|
9
|
+
/** Zero or one row `{ value: 0 }` — a hairline at zero, pushed only when a value is negative. */
|
|
10
|
+
declare const COMPARISON_ZERO_DATASET = "zero";
|
|
11
|
+
/** The hovered row's point selection. */
|
|
12
|
+
declare const COMPARISON_HOVER_PARAM = "hover";
|
|
13
|
+
declare const MAX_BAR_HEIGHT = 24;
|
|
14
|
+
/** Which axis the value runs along. `slope` and `column` put the category on x. */
|
|
15
|
+
declare function comparisonOrientation(mark: ComparisonMark): "horizontal" | "vertical";
|
|
16
|
+
/** The marks that read two values per item — the `from` field is theirs alone. */
|
|
17
|
+
declare function comparisonUsesFrom(mark: ComparisonMark): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether length carries the comparison, which forces a zero baseline
|
|
20
|
+
* whatever `scale` asks for: proportional ink is not negotiable for a bar, a
|
|
21
|
+
* column or a lollipop's stem. Position marks (`dot`, `dumbbell`, `slope`) may
|
|
22
|
+
* crop — the card prints every value as text beside the mark, so a cropped
|
|
23
|
+
* scale is never the only reading.
|
|
24
|
+
*/
|
|
25
|
+
declare function comparisonNeedsZero(mark: ComparisonMark): boolean;
|
|
26
|
+
/** The scale the plot actually draws with, after the marks that force zero. */
|
|
27
|
+
declare function resolveComparisonScale(mark: ComparisonMark, scale: ComparisonScale | undefined): ComparisonScale;
|
|
28
|
+
interface ComparisonPlotSpecOptions {
|
|
29
|
+
/** Which form the plot draws. */
|
|
30
|
+
mark: ComparisonMark;
|
|
31
|
+
/** Bar or column thickness in pixels, capped at 24. Centered in each band. */
|
|
32
|
+
barHeight: number;
|
|
33
|
+
/** Dot area in px² for `dot`, `lollipop`, `dumbbell` and the slope's endpoints. */
|
|
34
|
+
pointSize: number;
|
|
35
|
+
/** Initial plot height. Horizontal marks pass rows × step; vertical marks pass their own block height. The live value rides the View API. */
|
|
36
|
+
height: number;
|
|
37
|
+
/** Include zero in the value scale, or let it crop to the data. Bars, columns and lollipops always include zero — see `comparisonNeedsZero`. */
|
|
38
|
+
scale: ComparisonScale;
|
|
39
|
+
/** Draw the target reference rule (the `reference` dataset carries the value). */
|
|
40
|
+
reference: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Draw a hairline at zero (the `zero` dataset carries the one row) — only
|
|
43
|
+
* when a value is negative: for all-positive bars the left edge is the
|
|
44
|
+
* baseline already, and a hairline there would read as a border. Structural
|
|
45
|
+
* rather than data-driven because Vega warns about the infinite extent of an
|
|
46
|
+
* empty dataset that feeds a scale.
|
|
47
|
+
*/
|
|
48
|
+
zeroRule: boolean;
|
|
49
|
+
/** Wire the hover selection and the tooltip channel. */
|
|
50
|
+
tooltip: boolean;
|
|
51
|
+
/** Paint the focus row in the emphasis hue and every other row in the context gray. Without a focus, all marks take the emphasis hue (nominal marks are one color). */
|
|
52
|
+
emphasize: boolean;
|
|
53
|
+
/** Tooltip titles. */
|
|
54
|
+
itemTitle: string;
|
|
55
|
+
valueTitle: string;
|
|
56
|
+
/** Names of the two readings a `dumbbell` or a `slope` compares — the axis labels of a slope, the tooltip rows of both. */
|
|
57
|
+
fromTitle: string;
|
|
58
|
+
toTitle: string;
|
|
59
|
+
/** Localised title for the target reference rule's hover value. */
|
|
60
|
+
targetTitle?: string;
|
|
61
|
+
/** `arcNumber` grammar for values (`currency:THB:compact@en-US`). */
|
|
62
|
+
valueFormat: string;
|
|
63
|
+
locale?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds the plot. One mark per row on a shared value scale — length from
|
|
67
|
+
* zero for `bar`, `column` and `lollipop` (Cleveland & McGill's second-best
|
|
68
|
+
* channel, and the honest one for a zero baseline), position alone for `dot`,
|
|
69
|
+
* `dumbbell` and `slope` (the best channel, and the readable one when the
|
|
70
|
+
* values cluster far from zero) — the focus row in the emphasis hue and the
|
|
71
|
+
* rest in the context gray, a hairline at zero once a value is negative, an
|
|
72
|
+
* optional dotted target rule that joins the value domain, and a hover
|
|
73
|
+
* selection that keeps the pointed mark solid while its siblings recede.
|
|
74
|
+
*
|
|
75
|
+
* Horizontal bands have no padding, so the mark centers line up with the DOM
|
|
76
|
+
* rows that carry the names and values.
|
|
77
|
+
*/
|
|
78
|
+
declare function buildComparisonPlotSpec(options: ComparisonPlotSpecOptions, tokens: ChartTokens): TopLevelSpec;
|
|
79
|
+
//#endregion
|
|
80
|
+
export { COMPARISON_HOVER_PARAM, COMPARISON_REFERENCE_DATASET, COMPARISON_TABLE_DATASET, COMPARISON_ZERO_DATASET, ComparisonPlotSpecOptions, MAX_BAR_HEIGHT, buildComparisonPlotSpec, comparisonNeedsZero, comparisonOrientation, comparisonUsesFrom, resolveComparisonScale };
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { arcVegaConfig } from "../../lib/vega/config.js";
|
|
2
|
+
//#region src/components/ComparisonCard/ComparisonCard.chart.ts
|
|
3
|
+
/** The rows: `{ key, label, value, from, role }` per `ComparisonRow`, in display order. */
|
|
4
|
+
const COMPARISON_TABLE_DATASET = "table";
|
|
5
|
+
/** Zero or one row `{ value }` — the target reference rule. */
|
|
6
|
+
const COMPARISON_REFERENCE_DATASET = "reference";
|
|
7
|
+
/** Zero or one row `{ value: 0 }` — a hairline at zero, pushed only when a value is negative. */
|
|
8
|
+
const COMPARISON_ZERO_DATASET = "zero";
|
|
9
|
+
/** The hovered row's point selection. */
|
|
10
|
+
const COMPARISON_HOVER_PARAM = "hover";
|
|
11
|
+
const MAX_BAR_HEIGHT = 24;
|
|
12
|
+
const RESTING_OPACITY = .6;
|
|
13
|
+
const CONNECTOR_WIDTH = 2;
|
|
14
|
+
const SLOPE_WIDTH = 2;
|
|
15
|
+
const CROP_PADDING = 8;
|
|
16
|
+
const ROW_DOMAIN_EXPR = `pluck(data('${COMPARISON_TABLE_DATASET}'), 'key')`;
|
|
17
|
+
const BAND_LABEL_EXPR = `((data('${COMPARISON_TABLE_DATASET}')[indexof(pluck(data('${COMPARISON_TABLE_DATASET}'), 'key'), datum.value)] || {}).label)`;
|
|
18
|
+
/** Which axis the value runs along. `slope` and `column` put the category on x. */
|
|
19
|
+
function comparisonOrientation(mark) {
|
|
20
|
+
return mark === "column" || mark === "slope" ? "vertical" : "horizontal";
|
|
21
|
+
}
|
|
22
|
+
/** The marks that read two values per item — the `from` field is theirs alone. */
|
|
23
|
+
function comparisonUsesFrom(mark) {
|
|
24
|
+
return mark === "dumbbell" || mark === "slope";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether length carries the comparison, which forces a zero baseline
|
|
28
|
+
* whatever `scale` asks for: proportional ink is not negotiable for a bar, a
|
|
29
|
+
* column or a lollipop's stem. Position marks (`dot`, `dumbbell`, `slope`) may
|
|
30
|
+
* crop — the card prints every value as text beside the mark, so a cropped
|
|
31
|
+
* scale is never the only reading.
|
|
32
|
+
*/
|
|
33
|
+
function comparisonNeedsZero(mark) {
|
|
34
|
+
return mark === "bar" || mark === "column" || mark === "lollipop";
|
|
35
|
+
}
|
|
36
|
+
/** The scale the plot actually draws with, after the marks that force zero. */
|
|
37
|
+
function resolveComparisonScale(mark, scale) {
|
|
38
|
+
if (comparisonNeedsZero(mark)) return "zero";
|
|
39
|
+
return scale ?? "auto";
|
|
40
|
+
}
|
|
41
|
+
const SLOPE_FOLD = ["from", "value"];
|
|
42
|
+
/**
|
|
43
|
+
* Builds the plot. One mark per row on a shared value scale — length from
|
|
44
|
+
* zero for `bar`, `column` and `lollipop` (Cleveland & McGill's second-best
|
|
45
|
+
* channel, and the honest one for a zero baseline), position alone for `dot`,
|
|
46
|
+
* `dumbbell` and `slope` (the best channel, and the readable one when the
|
|
47
|
+
* values cluster far from zero) — the focus row in the emphasis hue and the
|
|
48
|
+
* rest in the context gray, a hairline at zero once a value is negative, an
|
|
49
|
+
* optional dotted target rule that joins the value domain, and a hover
|
|
50
|
+
* selection that keeps the pointed mark solid while its siblings recede.
|
|
51
|
+
*
|
|
52
|
+
* Horizontal bands have no padding, so the mark centers line up with the DOM
|
|
53
|
+
* rows that carry the names and values.
|
|
54
|
+
*/
|
|
55
|
+
function buildComparisonPlotSpec(options, tokens) {
|
|
56
|
+
const { mark, barHeight, pointSize, height, scale, reference, zeroRule, tooltip, emphasize, itemTitle, valueTitle, fromTitle, toTitle, valueFormat, locale } = options;
|
|
57
|
+
const vertical = comparisonOrientation(mark) === "vertical";
|
|
58
|
+
const V = vertical ? "y" : "x";
|
|
59
|
+
const V2 = vertical ? "y2" : "x2";
|
|
60
|
+
const C = vertical ? "x" : "y";
|
|
61
|
+
const valueScale = scale === "auto" ? {
|
|
62
|
+
zero: false,
|
|
63
|
+
nice: true,
|
|
64
|
+
padding: CROP_PADDING
|
|
65
|
+
} : {
|
|
66
|
+
zero: true,
|
|
67
|
+
nice: false
|
|
68
|
+
};
|
|
69
|
+
const valueChannel = (field) => ({
|
|
70
|
+
field,
|
|
71
|
+
type: "quantitative",
|
|
72
|
+
axis: null,
|
|
73
|
+
scale: valueScale
|
|
74
|
+
});
|
|
75
|
+
const categoryChannel = {
|
|
76
|
+
field: "key",
|
|
77
|
+
type: "nominal",
|
|
78
|
+
sort: null,
|
|
79
|
+
axis: vertical ? {
|
|
80
|
+
title: null,
|
|
81
|
+
labelAngle: 0,
|
|
82
|
+
labelPadding: 6,
|
|
83
|
+
domain: false,
|
|
84
|
+
ticks: false,
|
|
85
|
+
grid: false,
|
|
86
|
+
labelExpr: BAND_LABEL_EXPR,
|
|
87
|
+
aria: false
|
|
88
|
+
} : null,
|
|
89
|
+
scale: vertical ? {
|
|
90
|
+
type: "band",
|
|
91
|
+
domain: { expr: ROW_DOMAIN_EXPR },
|
|
92
|
+
paddingInner: .35,
|
|
93
|
+
paddingOuter: .2
|
|
94
|
+
} : {
|
|
95
|
+
type: "band",
|
|
96
|
+
domain: { expr: ROW_DOMAIN_EXPR },
|
|
97
|
+
paddingInner: 0,
|
|
98
|
+
paddingOuter: 0
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const valueTooltip = (field, title) => ({
|
|
102
|
+
field,
|
|
103
|
+
type: "quantitative",
|
|
104
|
+
title,
|
|
105
|
+
format: valueFormat,
|
|
106
|
+
formatType: "arcNumber"
|
|
107
|
+
});
|
|
108
|
+
const tooltipChannel = [
|
|
109
|
+
{
|
|
110
|
+
field: "label",
|
|
111
|
+
type: "nominal",
|
|
112
|
+
title: itemTitle
|
|
113
|
+
},
|
|
114
|
+
...comparisonUsesFrom(mark) ? [valueTooltip("from", fromTitle)] : [],
|
|
115
|
+
valueTooltip("value", comparisonUsesFrom(mark) ? toTitle : valueTitle)
|
|
116
|
+
];
|
|
117
|
+
const hue = emphasize ? {
|
|
118
|
+
condition: {
|
|
119
|
+
test: "datum.role === 'focus'",
|
|
120
|
+
value: tokens.emphasis
|
|
121
|
+
},
|
|
122
|
+
value: tokens.context
|
|
123
|
+
} : { value: tokens.emphasis };
|
|
124
|
+
const hoverOpacity = tooltip ? { opacity: {
|
|
125
|
+
condition: {
|
|
126
|
+
param: COMPARISON_HOVER_PARAM,
|
|
127
|
+
value: 1
|
|
128
|
+
},
|
|
129
|
+
value: RESTING_OPACITY
|
|
130
|
+
} } : {};
|
|
131
|
+
const hoverParam = tooltip ? { params: [{
|
|
132
|
+
name: COMPARISON_HOVER_PARAM,
|
|
133
|
+
select: {
|
|
134
|
+
type: "point",
|
|
135
|
+
on: "pointerover",
|
|
136
|
+
clear: "pointerout",
|
|
137
|
+
encodings: [C]
|
|
138
|
+
}
|
|
139
|
+
}] } : {};
|
|
140
|
+
const layers = [];
|
|
141
|
+
if (zeroRule) layers.push({
|
|
142
|
+
data: { name: COMPARISON_ZERO_DATASET },
|
|
143
|
+
mark: {
|
|
144
|
+
type: "rule",
|
|
145
|
+
stroke: tokens.axis,
|
|
146
|
+
strokeWidth: 1,
|
|
147
|
+
aria: false
|
|
148
|
+
},
|
|
149
|
+
encoding: { [V]: valueChannel("value") }
|
|
150
|
+
});
|
|
151
|
+
if (mark === "bar" || mark === "column") layers.push({
|
|
152
|
+
...hoverParam,
|
|
153
|
+
mark: {
|
|
154
|
+
type: "bar",
|
|
155
|
+
[vertical ? "width" : "height"]: Math.min(24, barHeight),
|
|
156
|
+
cornerRadiusEnd: 2,
|
|
157
|
+
aria: false
|
|
158
|
+
},
|
|
159
|
+
encoding: {
|
|
160
|
+
[C]: categoryChannel,
|
|
161
|
+
[V]: valueChannel("value"),
|
|
162
|
+
fill: hue,
|
|
163
|
+
...hoverOpacity,
|
|
164
|
+
...tooltip ? { tooltip: tooltipChannel } : {}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
if (mark === "lollipop") layers.push({
|
|
168
|
+
mark: {
|
|
169
|
+
type: "rule",
|
|
170
|
+
strokeWidth: CONNECTOR_WIDTH,
|
|
171
|
+
strokeCap: "round",
|
|
172
|
+
aria: false
|
|
173
|
+
},
|
|
174
|
+
encoding: {
|
|
175
|
+
[C]: categoryChannel,
|
|
176
|
+
[V]: valueChannel("value"),
|
|
177
|
+
[V2]: { datum: 0 },
|
|
178
|
+
stroke: hue,
|
|
179
|
+
...hoverOpacity
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
if (mark === "dumbbell") {
|
|
183
|
+
layers.push({
|
|
184
|
+
mark: {
|
|
185
|
+
type: "rule",
|
|
186
|
+
strokeWidth: CONNECTOR_WIDTH,
|
|
187
|
+
strokeCap: "round",
|
|
188
|
+
aria: false
|
|
189
|
+
},
|
|
190
|
+
encoding: {
|
|
191
|
+
[C]: categoryChannel,
|
|
192
|
+
[V]: valueChannel("value"),
|
|
193
|
+
[V2]: { field: "from" },
|
|
194
|
+
stroke: hue,
|
|
195
|
+
...hoverOpacity
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
layers.push({
|
|
199
|
+
mark: {
|
|
200
|
+
type: "point",
|
|
201
|
+
filled: true,
|
|
202
|
+
size: pointSize,
|
|
203
|
+
strokeWidth: 2,
|
|
204
|
+
aria: false
|
|
205
|
+
},
|
|
206
|
+
encoding: {
|
|
207
|
+
[C]: categoryChannel,
|
|
208
|
+
[V]: valueChannel("from"),
|
|
209
|
+
fill: { value: tokens.background },
|
|
210
|
+
stroke: hue,
|
|
211
|
+
...hoverOpacity
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (mark === "slope") {
|
|
216
|
+
const slopeBase = {
|
|
217
|
+
data: { name: COMPARISON_TABLE_DATASET },
|
|
218
|
+
transform: [
|
|
219
|
+
{
|
|
220
|
+
fold: SLOPE_FOLD,
|
|
221
|
+
as: ["end", "reading"]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
calculate: "datum.end === 'from' ? 0 : 1",
|
|
225
|
+
as: "endIndex"
|
|
226
|
+
},
|
|
227
|
+
{ filter: "isValid(datum.reading)" }
|
|
228
|
+
]
|
|
229
|
+
};
|
|
230
|
+
const slopeCategory = {
|
|
231
|
+
field: "endIndex",
|
|
232
|
+
type: "ordinal",
|
|
233
|
+
sort: null,
|
|
234
|
+
scale: {
|
|
235
|
+
type: "point",
|
|
236
|
+
padding: .3
|
|
237
|
+
},
|
|
238
|
+
axis: {
|
|
239
|
+
title: null,
|
|
240
|
+
labelAngle: 0,
|
|
241
|
+
labelPadding: 6,
|
|
242
|
+
domain: false,
|
|
243
|
+
ticks: false,
|
|
244
|
+
grid: false,
|
|
245
|
+
labelExpr: `datum.value === 0 ? ${JSON.stringify(fromTitle)} : ${JSON.stringify(toTitle)}`,
|
|
246
|
+
aria: false
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
layers.push({
|
|
250
|
+
...slopeBase,
|
|
251
|
+
mark: {
|
|
252
|
+
type: "line",
|
|
253
|
+
strokeWidth: SLOPE_WIDTH,
|
|
254
|
+
aria: false
|
|
255
|
+
},
|
|
256
|
+
encoding: {
|
|
257
|
+
x: slopeCategory,
|
|
258
|
+
y: valueChannel("reading"),
|
|
259
|
+
detail: {
|
|
260
|
+
field: "key",
|
|
261
|
+
type: "nominal"
|
|
262
|
+
},
|
|
263
|
+
order: {
|
|
264
|
+
field: "endIndex",
|
|
265
|
+
type: "quantitative"
|
|
266
|
+
},
|
|
267
|
+
stroke: hue,
|
|
268
|
+
...hoverOpacity
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
layers.push({
|
|
272
|
+
...slopeBase,
|
|
273
|
+
...hoverParam,
|
|
274
|
+
mark: {
|
|
275
|
+
type: "point",
|
|
276
|
+
filled: true,
|
|
277
|
+
size: pointSize,
|
|
278
|
+
aria: false
|
|
279
|
+
},
|
|
280
|
+
encoding: {
|
|
281
|
+
x: slopeCategory,
|
|
282
|
+
y: valueChannel("reading"),
|
|
283
|
+
fill: hue,
|
|
284
|
+
...hoverOpacity,
|
|
285
|
+
...tooltip ? { tooltip: tooltipChannel } : {}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (mark === "dot" || mark === "lollipop" || mark === "dumbbell") layers.push({
|
|
290
|
+
...hoverParam,
|
|
291
|
+
mark: {
|
|
292
|
+
type: "point",
|
|
293
|
+
filled: true,
|
|
294
|
+
size: pointSize,
|
|
295
|
+
aria: false
|
|
296
|
+
},
|
|
297
|
+
encoding: {
|
|
298
|
+
[C]: categoryChannel,
|
|
299
|
+
[V]: valueChannel("value"),
|
|
300
|
+
fill: hue,
|
|
301
|
+
...hoverOpacity,
|
|
302
|
+
...tooltip ? { tooltip: tooltipChannel } : {}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
if (reference) layers.push({
|
|
306
|
+
data: { name: COMPARISON_REFERENCE_DATASET },
|
|
307
|
+
mark: {
|
|
308
|
+
type: "rule",
|
|
309
|
+
stroke: tokens.reference,
|
|
310
|
+
strokeWidth: 1.5,
|
|
311
|
+
strokeDash: [0, 4],
|
|
312
|
+
strokeCap: "round",
|
|
313
|
+
opacity: .9,
|
|
314
|
+
aria: false
|
|
315
|
+
},
|
|
316
|
+
encoding: {
|
|
317
|
+
[V]: valueChannel("value"),
|
|
318
|
+
...tooltip ? { tooltip: [valueTooltip("value", options.targetTitle ?? "Target")] } : {}
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
return {
|
|
322
|
+
$schema: "https://vega.github.io/schema/vega-lite/v6.json",
|
|
323
|
+
width: 240,
|
|
324
|
+
height,
|
|
325
|
+
autosize: vertical ? {
|
|
326
|
+
type: "fit",
|
|
327
|
+
contains: "padding"
|
|
328
|
+
} : { type: "none" },
|
|
329
|
+
padding: 0,
|
|
330
|
+
background: "transparent",
|
|
331
|
+
data: { name: COMPARISON_TABLE_DATASET },
|
|
332
|
+
layer: layers,
|
|
333
|
+
config: arcVegaConfig(tokens, { locale })
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
//#endregion
|
|
337
|
+
export { COMPARISON_HOVER_PARAM, COMPARISON_REFERENCE_DATASET, COMPARISON_TABLE_DATASET, COMPARISON_ZERO_DATASET, MAX_BAR_HEIGHT, buildComparisonPlotSpec, comparisonNeedsZero, comparisonOrientation, comparisonUsesFrom, resolveComparisonScale };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { ArcTimeGranularity } from "../../lib/vega/formatters.js";
|
|
2
|
+
import { ComparisonCardLabels, ComparisonCardSize, ComparisonCardStatus, ComparisonDeltaMode, ComparisonGoodDirection, ComparisonHeadline, ComparisonItem, ComparisonMark, ComparisonScale, ComparisonSort } from "./ComparisonCard.model.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import { BoxProps } from "@arcfusionz/arc-primitive-ui";
|
|
5
|
+
import { TopLevelSpec } from "vega-lite";
|
|
6
|
+
import { Result } from "vega-embed";
|
|
7
|
+
//#region src/components/ComparisonCard/ComparisonCard.d.ts
|
|
8
|
+
interface ComparisonCardProps extends Omit<BoxProps, "children" | "padding" | "title"> {
|
|
9
|
+
/** The metric's name — the tile's heading. Pass `name` too when this is not plain text. */
|
|
10
|
+
label: ReactNode;
|
|
11
|
+
/** Plain-text name used in the generated descriptions and control labels. Defaults to `label` when it is a string. */
|
|
12
|
+
name?: string;
|
|
13
|
+
/** Definition of the metric, shown in a tooltip behind an info control beside the label and exposed to assistive technology as the control's description. */
|
|
14
|
+
hint?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The things being compared — periods, segments, sources, plans — as
|
|
17
|
+
* `{ key?, label, value }` records in the order they should read (periods
|
|
18
|
+
* chronological, segments as the product lists them). `key` defaults to
|
|
19
|
+
* `label` and identifies an item for `focus` and `baseline`; `value: null`
|
|
20
|
+
* keeps the row with no bar. Pass `[]` while loading — `expectedItems` rows
|
|
21
|
+
* are reserved.
|
|
22
|
+
*/
|
|
23
|
+
items: readonly ComparisonItem[];
|
|
24
|
+
/**
|
|
25
|
+
* Key of the subject, controlled: its bar takes the emphasis hue, its value
|
|
26
|
+
* is the `focus` headline, and the delta measures it against the baseline.
|
|
27
|
+
* Pair with `onFocusChange` to follow the reader's selection; omit it for
|
|
28
|
+
* the uncontrolled card (`defaultFocus`, else the first item). `null`
|
|
29
|
+
* designates none — every bar then takes the hue, there is no delta, the
|
|
30
|
+
* rows are not selectable, and a `focus` headline renders nothing.
|
|
31
|
+
*/
|
|
32
|
+
focus?: string | null;
|
|
33
|
+
/** The subject on first render when `focus` is uncontrolled. Default: the first item. */
|
|
34
|
+
defaultFocus?: string | null;
|
|
35
|
+
/** Called with the selected row's key when the reader chooses another subject — by click, or with the arrow keys inside the rows. */
|
|
36
|
+
onFocusChange?: (key: string) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Let the reader choose the subject and the reference: the rows become a
|
|
39
|
+
* radio group (click, or arrow keys once a row has focus), rank one selected
|
|
40
|
+
* by default, and the delta stack opens a compare-with menu to the right
|
|
41
|
+
* listing every other row. The headline, badge, hue, table and description
|
|
42
|
+
* follow both choices. A value the app controls without its change handler
|
|
43
|
+
* (`focus` without `onFocusChange`, `baseline` without `onBaselineChange`)
|
|
44
|
+
* is pinned and renders no control. Default `true`; `false` for a static
|
|
45
|
+
* tile. Stamped as `data-selectable`.
|
|
46
|
+
*/
|
|
47
|
+
selectable?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Key of the reference the focus is compared against, controlled — last
|
|
50
|
+
* month, the company average, the forecast. Pair with `onBaselineChange` to
|
|
51
|
+
* follow the reader's pick from the compare-with menu; omit it for the
|
|
52
|
+
* uncontrolled card (`defaultBaseline`, else the first item that is not the
|
|
53
|
+
* focus, so the leader is compared with the runner-up and every other row
|
|
54
|
+
* with the leader). A named baseline keeps its place until the reader
|
|
55
|
+
* selects it as the subject, then falls back to that rule. `null` draws the
|
|
56
|
+
* bars without a delta.
|
|
57
|
+
*/
|
|
58
|
+
baseline?: string | null;
|
|
59
|
+
/** The reference on first render when `baseline` is uncontrolled. Default: the first item that is not the focus. */
|
|
60
|
+
defaultBaseline?: string;
|
|
61
|
+
/** Called with the chosen row's key when the reader picks another reference from the compare-with menu under the delta badge. */
|
|
62
|
+
onBaselineChange?: (key: string) => void;
|
|
63
|
+
/**
|
|
64
|
+
* What the big number is. `focus` (default) shows the focus item's value —
|
|
65
|
+
* the KPI-tile convention — with the delta badge beside it. `gap` shows the
|
|
66
|
+
* change of the focus against the baseline (in `deltaMode`) with the other
|
|
67
|
+
* form in the badge — for a variance card. `none` leaves the bars and the
|
|
68
|
+
* badge to carry the card. Stamped as `data-headline`.
|
|
69
|
+
*/
|
|
70
|
+
headline?: ComparisonHeadline;
|
|
71
|
+
/**
|
|
72
|
+
* Name the subject in a chip under the headline value — a soft primary
|
|
73
|
+
* `Badge` with a swatch in the bar's hue, following the selection — so the
|
|
74
|
+
* number is never read without knowing whose it is. Default `true`; `false`
|
|
75
|
+
* when the card's title already names the subject. Not rendered with
|
|
76
|
+
* `headline="none"`.
|
|
77
|
+
*/
|
|
78
|
+
focusChip?: boolean;
|
|
79
|
+
/** What the delta is against, under the badge. Default: `vs {baseline label}` (`labels.versus`), or `{focus} vs {baseline}` for a `gap` headline. */
|
|
80
|
+
comparisonLabel?: ReactNode;
|
|
81
|
+
/** `percent` (default) is relative change; `absolute` is the difference in the value's units — percentage points for a `percent` format. Also the form of every row's variance in the popover table and tooltip. */
|
|
82
|
+
deltaMode?: ComparisonDeltaMode;
|
|
83
|
+
/**
|
|
84
|
+
* Which direction is good for the focus item: `up` (revenue), `down`
|
|
85
|
+
* (churn, latency, cost) or `none` (headcount — the delta stays neutral).
|
|
86
|
+
* Drives the delta badge's polarity color. Default `up`.
|
|
87
|
+
*/
|
|
88
|
+
goodDirection?: ComparisonGoodDirection;
|
|
89
|
+
/**
|
|
90
|
+
* Number format for the headline, rows, delta, table and tooltip — one
|
|
91
|
+
* grammar so nothing rounds two ways: `number[:digits]`, `integer`,
|
|
92
|
+
* `compact[:digits]`, `percent[:digits]`, `currency:CODE[:digits|compact]`.
|
|
93
|
+
* Default `compact` (`3.8M`); pass `percent` for ratio metrics.
|
|
94
|
+
*/
|
|
95
|
+
format?: string;
|
|
96
|
+
/** Custom formatter for values. Takes precedence over `format` everywhere a value is rendered. */
|
|
97
|
+
formatValue?: (value: number) => string;
|
|
98
|
+
/** Unit shown after a `focus` headline in the muted role (`ms`, `req/s`). Prefer `format="currency:…"` for money. */
|
|
99
|
+
unit?: ReactNode;
|
|
100
|
+
/** A shared goal. Draws a dotted reference rule across every bar and adds a `vs target` column to the popover table; pass `null` while unknown. */
|
|
101
|
+
target?: number | null;
|
|
102
|
+
/**
|
|
103
|
+
* The form the plot draws — the channel the comparison rides, never a
|
|
104
|
+
* choice of variety. `bar` (default) and `column` put length on a zero
|
|
105
|
+
* baseline, `column` standing the bars up for two to five short-named
|
|
106
|
+
* items; `dot` drops the baseline so values clustered far from zero
|
|
107
|
+
* separate; `lollipop` keeps the baseline at a fraction of the ink;
|
|
108
|
+
* `dumbbell` and `slope` draw the two readings of each item (`value` and
|
|
109
|
+
* `from`) as a gap and as a path. `column` and `slope` run vertically, so
|
|
110
|
+
* the plot becomes a block above the rows instead of overlaying them.
|
|
111
|
+
* Stamped as `data-mark`.
|
|
112
|
+
*/
|
|
113
|
+
mark?: ComparisonMark;
|
|
114
|
+
/**
|
|
115
|
+
* Whether the value scale includes zero. Ignored by `bar`, `column` and
|
|
116
|
+
* `lollipop`, where length carries the comparison and a cropped baseline
|
|
117
|
+
* would lie about the ratios. Default `auto` for the position marks
|
|
118
|
+
* (`dot`, `dumbbell`, `slope`), which is what lets NPS 40 and 47 read as
|
|
119
|
+
* different; pass `zero` when the distance from nothing is the point.
|
|
120
|
+
* Stamped as `data-scale`.
|
|
121
|
+
*/
|
|
122
|
+
scale?: ComparisonScale;
|
|
123
|
+
/** Name of the earlier reading a `dumbbell` or a `slope` draws — the slope's left axis label and both marks' tooltip row. Default `labels.from` ("Before"). */
|
|
124
|
+
fromLabel?: string;
|
|
125
|
+
/** Name of the current reading a `dumbbell` or a `slope` draws — the slope's right axis label and both marks' tooltip row. Default `labels.to` ("After"). */
|
|
126
|
+
toLabel?: string;
|
|
127
|
+
/** Row order: `none` (default) keeps the consumer's order — periods stay chronological — while `desc` and `asc` rank by value with missing values last. The focus keeps its hue wherever it lands. */
|
|
128
|
+
sort?: ComparisonSort;
|
|
129
|
+
/**
|
|
130
|
+
* Fold every item past this count (after sorting) into one `Other` row
|
|
131
|
+
* whose value is the sum of the folded values — for additive measures
|
|
132
|
+
* (counts, revenue), never for rates or averages. The focus and the
|
|
133
|
+
* baseline are never folded. Default: no fold.
|
|
134
|
+
*/
|
|
135
|
+
maxItems?: number;
|
|
136
|
+
/** Rows the skeleton reserves before `items` arrive, so the tile is already its final height. Default 2. */
|
|
137
|
+
expectedItems?: number;
|
|
138
|
+
/** The takeaway in a sentence, rendered beside the AI mark under the rows. Wrap values in `<strong>` to set them in bold. */
|
|
139
|
+
insight?: ReactNode;
|
|
140
|
+
/** The transport's status. `loading` with items already present is a refresh: the previous render stays under the veil. Default `ready`. */
|
|
141
|
+
status?: ComparisonCardStatus;
|
|
142
|
+
/** The consumer's filter is active — no values then reads as no-match rather than empty, with a clear-filters action when `onClearFilters` is set. */
|
|
143
|
+
filtered?: boolean;
|
|
144
|
+
/** The data is older than the product's freshness rule (TanStack Query's `isStale`). Shows a badge and stamps `data-stale`. */
|
|
145
|
+
stale?: boolean;
|
|
146
|
+
/** When the data was last true. Rendered as an "as of" line (the date by default — see `updatedAtFormat`) and included in the description. */
|
|
147
|
+
updatedAt?: Date | string | number;
|
|
148
|
+
/**
|
|
149
|
+
* How `updatedAt` is written, as a time-grammar granularity — `day`
|
|
150
|
+
* (default, `Sep 8, 2026`), `datetime` (`Sep 8, 2026, 04:30 PM`), `time`
|
|
151
|
+
* (`04:30 PM`), `month` (`Sep 2026`), `year` — or a formatter for a custom
|
|
152
|
+
* form. Applies to the as-of line and the description alike, in the card's
|
|
153
|
+
* `locale` and `timeZone`.
|
|
154
|
+
*/
|
|
155
|
+
updatedAtFormat?: ArcTimeGranularity | ((date: Date) => string);
|
|
156
|
+
/** Recovery action for the error state; renders a retry button when set. */
|
|
157
|
+
onRetry?: () => void;
|
|
158
|
+
/** Recovery action for the no-match state; renders a clear-filters button when set. */
|
|
159
|
+
onClearFilters?: () => void;
|
|
160
|
+
/** Density: `sm` for dense grids, `md` (default), `lg` for a hero comparison. Scales type, padding, the row height (24 / 28 / 32px) and the bar thickness. */
|
|
161
|
+
size?: ComparisonCardSize;
|
|
162
|
+
/** Heading level of the label for the document outline. Default 3 — tiles usually sit under a page's h2. */
|
|
163
|
+
titleLevel?: 2 | 3 | 4 | 5 | 6;
|
|
164
|
+
/** BCP 47 locale for every number and date. Defaults to the runtime's. Thai products on the Gregorian calendar pass `th-TH-u-ca-gregory`. */
|
|
165
|
+
locale?: string;
|
|
166
|
+
/** IANA time zone for the as-of date. Defaults to the runtime's — pass it for deterministic output. */
|
|
167
|
+
timeZone?: string;
|
|
168
|
+
/** Overrides for every rendered or announced string. */
|
|
169
|
+
labels?: Partial<ComparisonCardLabels>;
|
|
170
|
+
/** Replaces the generated accessible description of the whole card (the figure's `aria-describedby` text). */
|
|
171
|
+
description?: string;
|
|
172
|
+
/** Trailing header slot — a ghost `Button` or `Menu` for drill-through, export, or settings. */
|
|
173
|
+
action?: ReactNode;
|
|
174
|
+
/** Open the data popover on first render, anchored to the card. */
|
|
175
|
+
defaultTableOpen?: boolean;
|
|
176
|
+
/** Hide the header info button for the data popover. Only when another surface exposes the same values to keyboard and screen-reader users. */
|
|
177
|
+
hideTableToggle?: boolean;
|
|
178
|
+
/** Called with vega-embed's result once the bars mount — for `view` access in advanced compositions. */
|
|
179
|
+
onEmbed?: (result: Result) => void;
|
|
180
|
+
/** Escape hatch: transform the bars' spec before it renders. Voids the token and accessibility guarantees for whatever it changes. */
|
|
181
|
+
patchSpec?: (spec: TopLevelSpec) => TopLevelSpec;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A comparison tile for dashboard grids — the second subtype of the KPI card
|
|
185
|
+
* family beside `MetricCard`: one metric across a few items (periods,
|
|
186
|
+
* segments, sources, plans) on one shared scale, with every name and value as
|
|
187
|
+
* text beside the plot, the focus item in the emphasis hue, its delta against
|
|
188
|
+
* a baseline in a polarity badge, an optional target rule, and every loading,
|
|
189
|
+
* empty, error and stale state — layout-stable inside one `Box` frame, with a
|
|
190
|
+
* generated text equivalent and a data table in an info popover.
|
|
191
|
+
*
|
|
192
|
+
* `mark` picks the form the data calls for: `bar` (default), `column` and
|
|
193
|
+
* `lollipop` put length on a zero baseline; `dot` drops the baseline so
|
|
194
|
+
* values clustered far from zero separate; `dumbbell` and `slope` read a
|
|
195
|
+
* second reading per item (`ComparisonItem.from`) and draw the gap and the
|
|
196
|
+
* move between the two.
|
|
197
|
+
*/
|
|
198
|
+
declare const ComparisonCard: import("react").ForwardRefExoticComponent<ComparisonCardProps & import("react").RefAttributes<HTMLElement>>;
|
|
199
|
+
//#endregion
|
|
200
|
+
export { ComparisonCard, ComparisonCardProps };
|