@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.
Files changed (156) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +13 -0
  2. package/dist/components/AnomalyCard/AnomalyCard.chart.d.ts +64 -0
  3. package/dist/components/AnomalyCard/AnomalyCard.chart.js +341 -0
  4. package/dist/components/AnomalyCard/AnomalyCard.d.ts +169 -0
  5. package/dist/components/AnomalyCard/AnomalyCard.js +1019 -0
  6. package/dist/components/AnomalyCard/AnomalyCard.model.d.ts +508 -0
  7. package/dist/components/AnomalyCard/AnomalyCard.model.js +553 -0
  8. package/dist/components/AnomalyCard/index.d.ts +4 -0
  9. package/dist/components/AnomalyCard/index.js +4 -0
  10. package/dist/components/ChartCard/ChartCard.chart.d.ts +72 -0
  11. package/dist/components/ChartCard/ChartCard.chart.js +1333 -0
  12. package/dist/components/ChartCard/ChartCard.d.ts +206 -0
  13. package/dist/components/ChartCard/ChartCard.js +718 -0
  14. package/dist/components/ChartCard/ChartCard.model.d.ts +452 -0
  15. package/dist/components/ChartCard/ChartCard.model.js +1223 -0
  16. package/dist/components/ChartCard/index.d.ts +4 -0
  17. package/dist/components/ChartCard/index.js +4 -0
  18. package/dist/components/ComparisonCard/ComparisonCard.chart.d.ts +80 -0
  19. package/dist/components/ComparisonCard/ComparisonCard.chart.js +337 -0
  20. package/dist/components/ComparisonCard/ComparisonCard.d.ts +200 -0
  21. package/dist/components/ComparisonCard/ComparisonCard.js +1325 -0
  22. package/dist/components/ComparisonCard/ComparisonCard.model.d.ts +309 -0
  23. package/dist/components/ComparisonCard/ComparisonCard.model.js +263 -0
  24. package/dist/components/ComparisonCard/index.d.ts +4 -0
  25. package/dist/components/ComparisonCard/index.js +4 -0
  26. package/dist/components/ForecastCard/ForecastCard.chart.d.ts +82 -0
  27. package/dist/components/ForecastCard/ForecastCard.chart.js +416 -0
  28. package/dist/components/ForecastCard/ForecastCard.d.ts +148 -0
  29. package/dist/components/ForecastCard/ForecastCard.js +1029 -0
  30. package/dist/components/ForecastCard/ForecastCard.model.d.ts +497 -0
  31. package/dist/components/ForecastCard/ForecastCard.model.js +554 -0
  32. package/dist/components/ForecastCard/index.d.ts +4 -0
  33. package/dist/components/ForecastCard/index.js +4 -0
  34. package/dist/components/HighlightCard/HighlightCard.chart.d.ts +122 -0
  35. package/dist/components/HighlightCard/HighlightCard.chart.js +660 -0
  36. package/dist/components/HighlightCard/HighlightCard.d.ts +202 -0
  37. package/dist/components/HighlightCard/HighlightCard.js +1286 -0
  38. package/dist/components/HighlightCard/HighlightCard.model.d.ts +692 -0
  39. package/dist/components/HighlightCard/HighlightCard.model.js +875 -0
  40. package/dist/components/HighlightCard/index.d.ts +4 -0
  41. package/dist/components/HighlightCard/index.js +4 -0
  42. package/dist/components/InsightCard/InsightCard.chart.d.ts +91 -0
  43. package/dist/components/InsightCard/InsightCard.chart.js +471 -0
  44. package/dist/components/InsightCard/InsightCard.d.ts +161 -0
  45. package/dist/components/InsightCard/InsightCard.js +961 -0
  46. package/dist/components/InsightCard/InsightCard.model.d.ts +405 -0
  47. package/dist/components/InsightCard/InsightCard.model.js +421 -0
  48. package/dist/components/InsightCard/index.d.ts +4 -0
  49. package/dist/components/InsightCard/index.js +4 -0
  50. package/dist/components/MetricCard/MetricCard.chart.d.ts +79 -0
  51. package/dist/components/MetricCard/MetricCard.chart.js +435 -0
  52. package/dist/components/MetricCard/MetricCard.d.ts +227 -0
  53. package/dist/components/MetricCard/MetricCard.js +1293 -0
  54. package/dist/components/MetricCard/MetricCard.model.d.ts +521 -0
  55. package/dist/components/MetricCard/MetricCard.model.js +627 -0
  56. package/dist/components/MetricCard/index.d.ts +4 -0
  57. package/dist/components/MetricCard/index.js +4 -0
  58. package/dist/components/ProfileCard/ProfileCard.chart.d.ts +64 -0
  59. package/dist/components/ProfileCard/ProfileCard.chart.js +427 -0
  60. package/dist/components/ProfileCard/ProfileCard.d.ts +140 -0
  61. package/dist/components/ProfileCard/ProfileCard.js +735 -0
  62. package/dist/components/ProfileCard/ProfileCard.model.d.ts +279 -0
  63. package/dist/components/ProfileCard/ProfileCard.model.js +244 -0
  64. package/dist/components/ProfileCard/index.d.ts +4 -0
  65. package/dist/components/ProfileCard/index.js +4 -0
  66. package/dist/components/ProgressCard/ProgressCard.chart.d.ts +73 -0
  67. package/dist/components/ProgressCard/ProgressCard.chart.js +373 -0
  68. package/dist/components/ProgressCard/ProgressCard.d.ts +137 -0
  69. package/dist/components/ProgressCard/ProgressCard.js +908 -0
  70. package/dist/components/ProgressCard/ProgressCard.model.d.ts +385 -0
  71. package/dist/components/ProgressCard/ProgressCard.model.js +389 -0
  72. package/dist/components/ProgressCard/index.d.ts +4 -0
  73. package/dist/components/ProgressCard/index.js +4 -0
  74. package/dist/components/ReportCard/ReportCard.chart.d.ts +45 -0
  75. package/dist/components/ReportCard/ReportCard.chart.js +231 -0
  76. package/dist/components/ReportCard/ReportCard.d.ts +153 -0
  77. package/dist/components/ReportCard/ReportCard.js +1118 -0
  78. package/dist/components/ReportCard/ReportCard.model.d.ts +392 -0
  79. package/dist/components/ReportCard/ReportCard.model.js +399 -0
  80. package/dist/components/ReportCard/index.d.ts +4 -0
  81. package/dist/components/ReportCard/index.js +4 -0
  82. package/dist/components/SankeyCard/SankeyCard.chart.d.ts +75 -0
  83. package/dist/components/SankeyCard/SankeyCard.chart.js +249 -0
  84. package/dist/components/SankeyCard/SankeyCard.d.ts +185 -0
  85. package/dist/components/SankeyCard/SankeyCard.js +788 -0
  86. package/dist/components/SankeyCard/SankeyCard.model.d.ts +501 -0
  87. package/dist/components/SankeyCard/SankeyCard.model.js +789 -0
  88. package/dist/components/SankeyCard/index.d.ts +4 -0
  89. package/dist/components/SankeyCard/index.js +4 -0
  90. package/dist/components/StatusCard/StatusCard.chart.d.ts +60 -0
  91. package/dist/components/StatusCard/StatusCard.chart.js +188 -0
  92. package/dist/components/StatusCard/StatusCard.d.ts +176 -0
  93. package/dist/components/StatusCard/StatusCard.js +989 -0
  94. package/dist/components/StatusCard/StatusCard.model.d.ts +555 -0
  95. package/dist/components/StatusCard/StatusCard.model.js +776 -0
  96. package/dist/components/StatusCard/index.d.ts +4 -0
  97. package/dist/components/StatusCard/index.js +4 -0
  98. package/dist/components/TableCard/TableCard.chart.d.ts +53 -0
  99. package/dist/components/TableCard/TableCard.chart.js +192 -0
  100. package/dist/components/TableCard/TableCard.d.ts +140 -0
  101. package/dist/components/TableCard/TableCard.js +811 -0
  102. package/dist/components/TableCard/TableCard.model.d.ts +381 -0
  103. package/dist/components/TableCard/TableCard.model.js +475 -0
  104. package/dist/components/TableCard/index.d.ts +4 -0
  105. package/dist/components/TableCard/index.js +4 -0
  106. package/dist/components/TargetCard/TargetCard.chart.d.ts +52 -0
  107. package/dist/components/TargetCard/TargetCard.chart.js +273 -0
  108. package/dist/components/TargetCard/TargetCard.d.ts +143 -0
  109. package/dist/components/TargetCard/TargetCard.js +910 -0
  110. package/dist/components/TargetCard/TargetCard.model.d.ts +468 -0
  111. package/dist/components/TargetCard/TargetCard.model.js +581 -0
  112. package/dist/components/TargetCard/index.d.ts +4 -0
  113. package/dist/components/TargetCard/index.js +4 -0
  114. package/dist/components/TreeCard/TreeCard.chart.d.ts +80 -0
  115. package/dist/components/TreeCard/TreeCard.chart.js +178 -0
  116. package/dist/components/TreeCard/TreeCard.d.ts +182 -0
  117. package/dist/components/TreeCard/TreeCard.js +1187 -0
  118. package/dist/components/TreeCard/TreeCard.model.d.ts +330 -0
  119. package/dist/components/TreeCard/TreeCard.model.js +401 -0
  120. package/dist/components/TreeCard/index.d.ts +4 -0
  121. package/dist/components/TreeCard/index.js +4 -0
  122. package/dist/components/TrendCard/TrendCard.chart.d.ts +75 -0
  123. package/dist/components/TrendCard/TrendCard.chart.js +393 -0
  124. package/dist/components/TrendCard/TrendCard.d.ts +224 -0
  125. package/dist/components/TrendCard/TrendCard.js +1053 -0
  126. package/dist/components/TrendCard/TrendCard.model.d.ts +545 -0
  127. package/dist/components/TrendCard/TrendCard.model.js +623 -0
  128. package/dist/components/TrendCard/index.d.ts +4 -0
  129. package/dist/components/TrendCard/index.js +4 -0
  130. package/dist/index.d.ts +76 -0
  131. package/dist/index.js +57 -0
  132. package/dist/lib/vega/ArcVegaChart.d.ts +24 -0
  133. package/dist/lib/vega/ArcVegaChart.js +42 -0
  134. package/dist/lib/vega/ArcVegaSurface.d.ts +13 -0
  135. package/dist/lib/vega/ArcVegaSurface.js +38 -0
  136. package/dist/lib/vega/axisTicks.js +156 -0
  137. package/dist/lib/vega/config.d.ts +29 -0
  138. package/dist/lib/vega/config.js +113 -0
  139. package/dist/lib/vega/embed.d.ts +29 -0
  140. package/dist/lib/vega/embed.js +29 -0
  141. package/dist/lib/vega/engine.d.ts +10 -0
  142. package/dist/lib/vega/engine.js +6 -0
  143. package/dist/lib/vega/formatters.d.ts +125 -0
  144. package/dist/lib/vega/formatters.js +277 -0
  145. package/dist/lib/vega/index.d.ts +11 -0
  146. package/dist/lib/vega/load.d.ts +13 -0
  147. package/dist/lib/vega/load.js +21 -0
  148. package/dist/lib/vega/time.d.ts +45 -0
  149. package/dist/lib/vega/time.js +105 -0
  150. package/dist/lib/vega/tokens.d.ts +73 -0
  151. package/dist/lib/vega/tokens.js +137 -0
  152. package/dist/lib/vega/tooltip.d.ts +45 -0
  153. package/dist/lib/vega/tooltip.js +124 -0
  154. package/dist/lib/vega/useArcVega.d.ts +43 -0
  155. package/dist/lib/vega/useArcVega.js +121 -0
  156. package/package.json +60 -0
@@ -0,0 +1,660 @@
1
+ import { AXIS_LABEL_LIMIT_EXPR } from "../../lib/vega/axisTicks.js";
2
+ import { arcVegaConfig } from "../../lib/vega/config.js";
3
+ //#region src/components/HighlightCard/HighlightCard.chart.ts
4
+ /** Context plot: every reading, with `hl` and the window's `tone`. */
5
+ const HIGHLIGHT_TABLE_DATASET = "table";
6
+ /** Context plot: the readings outside the window with a `seg` of `before` or `after` — the gray runs. */
7
+ const HIGHLIGHT_OUTSIDE_DATASET = "outside";
8
+ /** Context plot: the readings inside the window — the coloured segment. */
9
+ const HIGHLIGHT_INSIDE_DATASET = "inside";
10
+ /** Context plot: the window's start and end readings — the two dots. */
11
+ const HIGHLIGHT_ENDPOINTS_DATASET = "endpoints";
12
+ /** Context plot: one row `{ start, end, tone }` — the band wash and the axis anchors. */
13
+ const HIGHLIGHT_BAND_DATASET = "band";
14
+ /** Peer strip: one row per compared window, `{ change, isHighlight, … }`. */
15
+ const HIGHLIGHT_PEERS_DATASET = "peers";
16
+ /** Peer strip: one row `{ low, high }` — the typical-range wash. */
17
+ const HIGHLIGHT_TYPICAL_DATASET = "typical";
18
+ /** Peer strip and drivers: one row `{ value: 0 }` — the hairline at no change. */
19
+ const HIGHLIGHT_ZERO_DATASET = "zero";
20
+ /** Drivers: one row per contributor, `{ key, label, value, tone, role }`. */
21
+ const HIGHLIGHT_DRIVERS_DATASET = "drivers";
22
+ /** Context plot: the nearest-reading hover selection. */
23
+ const HIGHLIGHT_HOVER_PARAM = "hover";
24
+ /** Peer strip: the hovered window. */
25
+ const HIGHLIGHT_PEER_HOVER_PARAM = "peer_hover";
26
+ /** Drivers: the hovered bar. */
27
+ const HIGHLIGHT_DRIVER_HOVER_PARAM = "driver_hover";
28
+ /** Context plot: responsive x tick values, recomputed by Vega when the domain or width changes. */
29
+ const HIGHLIGHT_X_TICKS_PARAM = "highlight_x_ticks";
30
+ /** Context plot: the window's snapped bounds, read from the `band` dataset — the x axis labels them. */
31
+ const HIGHLIGHT_START_PARAM = "highlight_start";
32
+ const HIGHLIGHT_END_PARAM = "highlight_end";
33
+ const POINT_SIZE = 64;
34
+ const BAR_WIDTH_EXPR = "min(24, bandwidth('x') * 0.7)";
35
+ /** Bars stay ≤ 24px however tall the rows are. */
36
+ const MAX_DRIVER_BAR_HEIGHT = 24;
37
+ const PLOT_PADDING = 6;
38
+ const BAND_OPACITY = .08;
39
+ const TYPICAL_OPACITY = .14;
40
+ const PEER_OPACITY = .45;
41
+ const RESTING_OPACITY = .75;
42
+ const PX_PER_Y_TICK = 48;
43
+ const MIN_Y_TICKS = 2;
44
+ const DISCRETE_DOMAIN_EXPR = `pluck(data('${HIGHLIGHT_TABLE_DATASET}'), 'x')`;
45
+ const DRIVER_DOMAIN_EXPR = `pluck(data('${HIGHLIGHT_DRIVERS_DATASET}'), 'key')`;
46
+ /**
47
+ * A mark colour that follows a row's polarity — the diverging ends when the
48
+ * move means good or bad (lightness-matched, ≥ 3:1 on both surfaces), the
49
+ * emphasis hue when it is neutral — and `fallback` for rows carrying none
50
+ * (`null`). Kept in the spec as three token values, so the spec stays
51
+ * structural while the data decides.
52
+ *
53
+ * `field` is the row property holding it: the context and driver rows call it
54
+ * `tone`, and a peer row calls it `polarity` because that row is also public
55
+ * API. A mismatch here paints every mark the fallback hue, so the spec tests
56
+ * assert the diverging values are present on each plot.
57
+ */
58
+ function toneColor(tokens, fallback, field = "tone") {
59
+ return {
60
+ condition: [
61
+ {
62
+ test: `datum.${field} === 'positive'`,
63
+ value: tokens.divergingPositive
64
+ },
65
+ {
66
+ test: `datum.${field} === 'negative'`,
67
+ value: tokens.divergingNegative
68
+ },
69
+ {
70
+ test: `datum.${field} === 'neutral'`,
71
+ value: tokens.emphasis
72
+ }
73
+ ],
74
+ value: fallback
75
+ };
76
+ }
77
+ /**
78
+ * The window inside the whole series: a quiet band washes its extent, the
79
+ * readings outside it draw in the context gray, the window itself draws in its
80
+ * polarity hue, its start and end are dotted, and the x axis labels the
81
+ * window's bounds before the domain's ends. Lines may crop (`scale: "auto"`);
82
+ * areas and bars keep a zero baseline whatever `scale` says — proportional ink
83
+ * is not negotiable. Gaps stay gaps: Vega-Lite's default `invalid` handling
84
+ * breaks the path at a null reading.
85
+ */
86
+ function buildHighlightContextSpec(options, tokens) {
87
+ const { mark, scale, xType, height, axes, tooltip, xTitle, yTitle, valueFormat, timeFormat, axisTimeFormat } = options;
88
+ const zero = mark !== "line" || scale === "zero";
89
+ const discreteX = mark === "bar" || xType === "ordinal";
90
+ const xTickFormat = xType === "temporal" ? axisTimeFormat : "compact";
91
+ const xTickKind = xType === "temporal" ? "time" : xType === "quantitative" ? "number" : "text";
92
+ const axisArgs = `domain('x'), width, ${discreteX}, ${JSON.stringify(xTickFormat)}, ${JSON.stringify(xTickKind)}`;
93
+ const anchorsArg = `, [${HIGHLIGHT_START_PARAM}, ${HIGHLIGHT_END_PARAM}]`;
94
+ const yTicks = Math.max(MIN_Y_TICKS, Math.round(height / PX_PER_Y_TICK));
95
+ const xAxisLabels = xType === "temporal" ? {
96
+ format: axisTimeFormat,
97
+ formatType: "arcTime"
98
+ } : xType === "quantitative" ? {
99
+ format: "compact",
100
+ formatType: "arcNumber"
101
+ } : {};
102
+ const xAxis = axes ? {
103
+ title: null,
104
+ orient: "bottom",
105
+ domain: true,
106
+ ticks: false,
107
+ grid: false,
108
+ values: { expr: HIGHLIGHT_X_TICKS_PARAM },
109
+ labelAngle: 0,
110
+ labelAlign: { expr: `arcAxisLabelAlign(datum.value, ${axisArgs}${anchorsArg})` },
111
+ labelFlush: false,
112
+ labelOverlap: false,
113
+ labelLimit: { expr: AXIS_LABEL_LIMIT_EXPR },
114
+ labelPadding: 4,
115
+ ...xAxisLabels
116
+ } : null;
117
+ const yAxis = axes ? {
118
+ title: null,
119
+ orient: "left",
120
+ domain: false,
121
+ ticks: false,
122
+ grid: true,
123
+ tickCount: yTicks,
124
+ labelOverlap: true,
125
+ labelPadding: 6,
126
+ format: valueFormat,
127
+ formatType: "arcNumber"
128
+ } : null;
129
+ const discreteScale = { scale: { domain: { expr: DISCRETE_DOMAIN_EXPR } } };
130
+ const xField = mark === "bar" ? {
131
+ field: "x",
132
+ type: "ordinal",
133
+ sort: null,
134
+ axis: xAxis,
135
+ ...discreteScale
136
+ } : {
137
+ field: "x",
138
+ type: xType,
139
+ axis: xAxis,
140
+ ...xType === "ordinal" ? {
141
+ sort: null,
142
+ ...discreteScale
143
+ } : { scale: {
144
+ nice: false,
145
+ ...xType === "quantitative" ? { zero: false } : {}
146
+ } }
147
+ };
148
+ const yField = {
149
+ field: "y",
150
+ type: "quantitative",
151
+ axis: yAxis,
152
+ scale: {
153
+ zero,
154
+ nice: axes
155
+ }
156
+ };
157
+ const tooltipChannel = [xType === "temporal" ? {
158
+ field: "x",
159
+ type: "temporal",
160
+ title: xTitle,
161
+ format: timeFormat,
162
+ formatType: "arcTime"
163
+ } : xType === "quantitative" ? {
164
+ field: "x",
165
+ type: "quantitative",
166
+ title: xTitle,
167
+ format: "number",
168
+ formatType: "arcNumber"
169
+ } : {
170
+ field: "x",
171
+ type: "nominal",
172
+ title: xTitle
173
+ }, {
174
+ field: "y",
175
+ type: "quantitative",
176
+ title: yTitle,
177
+ format: valueFormat,
178
+ formatType: "arcNumber"
179
+ }];
180
+ const layers = [{
181
+ data: { name: HIGHLIGHT_BAND_DATASET },
182
+ mark: {
183
+ type: "rect",
184
+ opacity: BAND_OPACITY,
185
+ aria: false
186
+ },
187
+ encoding: {
188
+ x: {
189
+ ...xField,
190
+ field: "start",
191
+ ...discreteX ? { bandPosition: 0 } : {}
192
+ },
193
+ x2: {
194
+ field: "end",
195
+ ...discreteX ? { bandPosition: 1 } : {}
196
+ },
197
+ fill: toneColor(tokens, tokens.emphasis)
198
+ }
199
+ }];
200
+ if (mark === "bar") layers.push({
201
+ ...tooltip ? { params: [{
202
+ name: HIGHLIGHT_HOVER_PARAM,
203
+ select: {
204
+ type: "point",
205
+ on: "pointerover",
206
+ clear: "pointerout",
207
+ encodings: ["x"]
208
+ }
209
+ }] } : {},
210
+ mark: {
211
+ type: "bar",
212
+ cornerRadiusEnd: 2,
213
+ width: { expr: BAR_WIDTH_EXPR }
214
+ },
215
+ encoding: {
216
+ x: xField,
217
+ y: yField,
218
+ fill: toneColor(tokens, tokens.context),
219
+ ...tooltip ? {
220
+ opacity: {
221
+ condition: {
222
+ param: HIGHLIGHT_HOVER_PARAM,
223
+ empty: false,
224
+ value: 1
225
+ },
226
+ value: RESTING_OPACITY
227
+ },
228
+ tooltip: tooltipChannel
229
+ } : {}
230
+ }
231
+ });
232
+ else {
233
+ const outsideEncoding = {
234
+ x: xField,
235
+ y: yField,
236
+ detail: {
237
+ field: "seg",
238
+ type: "nominal"
239
+ }
240
+ };
241
+ if (mark === "area") layers.push({
242
+ data: { name: HIGHLIGHT_OUTSIDE_DATASET },
243
+ mark: {
244
+ type: "area",
245
+ fill: tokens.context,
246
+ fillOpacity: .12,
247
+ line: false,
248
+ interpolate: "linear"
249
+ },
250
+ encoding: outsideEncoding
251
+ });
252
+ layers.push({
253
+ data: { name: HIGHLIGHT_OUTSIDE_DATASET },
254
+ mark: {
255
+ type: "line",
256
+ stroke: tokens.context,
257
+ strokeWidth: 2,
258
+ strokeCap: "round",
259
+ strokeJoin: "round",
260
+ interpolate: "linear"
261
+ },
262
+ encoding: outsideEncoding
263
+ });
264
+ if (mark === "area") layers.push({
265
+ data: { name: HIGHLIGHT_INSIDE_DATASET },
266
+ mark: {
267
+ type: "area",
268
+ fillOpacity: .12,
269
+ line: false,
270
+ interpolate: "linear"
271
+ },
272
+ encoding: {
273
+ x: xField,
274
+ y: yField,
275
+ fill: toneColor(tokens, tokens.emphasis)
276
+ }
277
+ });
278
+ layers.push({
279
+ data: { name: HIGHLIGHT_INSIDE_DATASET },
280
+ mark: {
281
+ type: "line",
282
+ strokeWidth: 2,
283
+ strokeCap: "round",
284
+ strokeJoin: "round",
285
+ interpolate: "linear"
286
+ },
287
+ encoding: {
288
+ x: xField,
289
+ y: yField,
290
+ stroke: toneColor(tokens, tokens.emphasis)
291
+ }
292
+ });
293
+ const dot = {
294
+ type: "point",
295
+ filled: true,
296
+ size: POINT_SIZE,
297
+ stroke: tokens.background,
298
+ strokeWidth: 1.5,
299
+ opacity: 1,
300
+ aria: false
301
+ };
302
+ layers.push({
303
+ data: { name: HIGHLIGHT_ENDPOINTS_DATASET },
304
+ mark: dot,
305
+ encoding: {
306
+ x: xField,
307
+ y: yField,
308
+ fill: toneColor(tokens, tokens.emphasis)
309
+ }
310
+ });
311
+ if (tooltip) layers.push({
312
+ params: [{
313
+ name: HIGHLIGHT_HOVER_PARAM,
314
+ select: {
315
+ type: "point",
316
+ on: "pointermove",
317
+ nearest: true,
318
+ clear: "pointerout",
319
+ encodings: ["x"]
320
+ }
321
+ }],
322
+ mark: {
323
+ type: "point",
324
+ filled: true,
325
+ size: POINT_SIZE,
326
+ stroke: tokens.background,
327
+ strokeWidth: 1.5,
328
+ aria: false
329
+ },
330
+ encoding: {
331
+ x: xField,
332
+ y: yField,
333
+ fill: toneColor(tokens, tokens.context),
334
+ opacity: {
335
+ condition: {
336
+ param: HIGHLIGHT_HOVER_PARAM,
337
+ empty: false,
338
+ value: 1
339
+ },
340
+ value: 0
341
+ },
342
+ tooltip: tooltipChannel
343
+ }
344
+ });
345
+ }
346
+ const params = [{
347
+ name: HIGHLIGHT_START_PARAM,
348
+ expr: `length(data('${HIGHLIGHT_BAND_DATASET}')) ? data('${HIGHLIGHT_BAND_DATASET}')[0].start : null`
349
+ }, {
350
+ name: HIGHLIGHT_END_PARAM,
351
+ expr: `length(data('${HIGHLIGHT_BAND_DATASET}')) ? data('${HIGHLIGHT_BAND_DATASET}')[0].end : null`
352
+ }];
353
+ if (axes) params.push({
354
+ name: HIGHLIGHT_X_TICKS_PARAM,
355
+ expr: `arcAxisTicks(${axisArgs}${anchorsArg})`
356
+ });
357
+ return {
358
+ $schema: "https://vega.github.io/schema/vega-lite/v6.json",
359
+ width: 360,
360
+ height,
361
+ autosize: {
362
+ type: "fit",
363
+ contains: "padding"
364
+ },
365
+ padding: PLOT_PADDING,
366
+ background: "transparent",
367
+ data: { name: HIGHLIGHT_TABLE_DATASET },
368
+ params,
369
+ layer: layers,
370
+ config: arcVegaConfig(tokens, {
371
+ locale: options.locale,
372
+ timeZone: options.timeZone
373
+ })
374
+ };
375
+ }
376
+ /**
377
+ * Every comparable window's change on ONE shared position scale, as a strip
378
+ * plot: the typical range as a quiet wash, a hairline at no change, one thin
379
+ * tick per compared window in the context gray, and the highlighted window as
380
+ * a solid dot in its polarity hue.
381
+ *
382
+ * A strip plot, not a summary statistic, because showing the peers is the
383
+ * honest way to say "unusual" — the reader sees the spread they are being
384
+ * asked to accept, the crowd near zero and the tail this window sits in.
385
+ * Every tick is also a row in the panel's table, so nothing lives only here.
386
+ */
387
+ function buildHighlightPeersSpec(options, tokens) {
388
+ const { height, tooltip, windowTitle, changeTitle, changeFormat, typicalTitle } = options;
389
+ const xField = {
390
+ field: "change",
391
+ type: "quantitative",
392
+ axis: {
393
+ title: null,
394
+ orient: "bottom",
395
+ domain: false,
396
+ ticks: false,
397
+ grid: true,
398
+ tickCount: 4,
399
+ labelOverlap: true,
400
+ labelPadding: 4,
401
+ format: changeFormat,
402
+ formatType: "arcNumber"
403
+ },
404
+ scale: {
405
+ zero: true,
406
+ nice: true
407
+ }
408
+ };
409
+ const tooltipChannel = [{
410
+ field: "rangeText",
411
+ type: "nominal",
412
+ title: windowTitle
413
+ }, {
414
+ field: "change",
415
+ type: "quantitative",
416
+ title: changeTitle,
417
+ format: changeFormat,
418
+ formatType: "arcNumber"
419
+ }];
420
+ const layers = [
421
+ {
422
+ data: { name: HIGHLIGHT_TYPICAL_DATASET },
423
+ mark: {
424
+ type: "rect",
425
+ fill: tokens.brush,
426
+ opacity: TYPICAL_OPACITY,
427
+ aria: false
428
+ },
429
+ encoding: {
430
+ x: {
431
+ ...xField,
432
+ field: "low"
433
+ },
434
+ x2: { field: "high" },
435
+ ...tooltip ? { tooltip: [{
436
+ field: "low",
437
+ type: "quantitative",
438
+ title: typicalTitle,
439
+ format: changeFormat,
440
+ formatType: "arcNumber"
441
+ }, {
442
+ field: "high",
443
+ type: "quantitative",
444
+ title: "",
445
+ format: changeFormat,
446
+ formatType: "arcNumber"
447
+ }] } : {}
448
+ }
449
+ },
450
+ {
451
+ data: { name: HIGHLIGHT_ZERO_DATASET },
452
+ mark: {
453
+ type: "rule",
454
+ stroke: tokens.reference,
455
+ strokeWidth: 1,
456
+ opacity: .8,
457
+ aria: false
458
+ },
459
+ encoding: { x: {
460
+ ...xField,
461
+ field: "value"
462
+ } }
463
+ },
464
+ {
465
+ ...tooltip ? { params: [{
466
+ name: HIGHLIGHT_PEER_HOVER_PARAM,
467
+ select: {
468
+ type: "point",
469
+ on: "pointerover",
470
+ clear: "pointerout",
471
+ nearest: true
472
+ }
473
+ }] } : {},
474
+ data: { name: HIGHLIGHT_PEERS_DATASET },
475
+ transform: [{ filter: "!datum.isHighlight" }],
476
+ mark: {
477
+ type: "tick",
478
+ thickness: 1.5,
479
+ size: height * .5,
480
+ stroke: tokens.context,
481
+ ariaRoleDescription: "window"
482
+ },
483
+ encoding: {
484
+ x: xField,
485
+ ...tooltip ? {
486
+ opacity: {
487
+ condition: {
488
+ param: HIGHLIGHT_PEER_HOVER_PARAM,
489
+ empty: false,
490
+ value: 1
491
+ },
492
+ value: PEER_OPACITY
493
+ },
494
+ tooltip: tooltipChannel
495
+ } : { opacity: { value: PEER_OPACITY } }
496
+ }
497
+ },
498
+ {
499
+ data: { name: HIGHLIGHT_PEERS_DATASET },
500
+ transform: [{ filter: "datum.isHighlight" }],
501
+ mark: {
502
+ type: "point",
503
+ filled: true,
504
+ size: 88,
505
+ stroke: tokens.background,
506
+ strokeWidth: 1.5,
507
+ opacity: 1,
508
+ ariaRoleDescription: "highlighted window"
509
+ },
510
+ encoding: {
511
+ x: xField,
512
+ fill: toneColor(tokens, tokens.emphasis, "polarity"),
513
+ ...tooltip ? { tooltip: tooltipChannel } : {}
514
+ }
515
+ }
516
+ ];
517
+ return {
518
+ $schema: "https://vega.github.io/schema/vega-lite/v6.json",
519
+ width: 360,
520
+ height,
521
+ autosize: {
522
+ type: "fit",
523
+ contains: "padding"
524
+ },
525
+ padding: PLOT_PADDING,
526
+ background: "transparent",
527
+ data: { name: HIGHLIGHT_PEERS_DATASET },
528
+ layer: layers,
529
+ config: arcVegaConfig(tokens, {
530
+ locale: options.locale,
531
+ timeZone: options.timeZone
532
+ })
533
+ };
534
+ }
535
+ /**
536
+ * The window's change decomposed: one horizontal bar per contributor from a
537
+ * shared zero, positive to the right and negative to the left, in the
538
+ * diverging polarity hues. Sorted by absolute contribution upstream, so the
539
+ * biggest mover is the first row.
540
+ *
541
+ * Bars only — the names, amounts and shares are DOM text beside the plot, so
542
+ * every band has no padding and the bar centers line up with the rows that
543
+ * carry the text. A hairline at zero is always drawn: these values are signed
544
+ * by nature, and the reader must see which side of no-change each one is on.
545
+ */
546
+ function buildHighlightDriversSpec(options, tokens) {
547
+ const { barHeight, height, tooltip, driverTitle, contributionTitle, shareTitle, valueFormat } = options;
548
+ const xField = {
549
+ field: "value",
550
+ type: "quantitative",
551
+ axis: null,
552
+ scale: {
553
+ zero: true,
554
+ nice: false
555
+ }
556
+ };
557
+ const yField = {
558
+ field: "key",
559
+ type: "nominal",
560
+ sort: null,
561
+ axis: null,
562
+ scale: {
563
+ domain: { expr: DRIVER_DOMAIN_EXPR },
564
+ paddingInner: 0,
565
+ paddingOuter: 0
566
+ }
567
+ };
568
+ const tooltipChannel = [
569
+ {
570
+ field: "label",
571
+ type: "nominal",
572
+ title: driverTitle
573
+ },
574
+ {
575
+ field: "value",
576
+ type: "quantitative",
577
+ title: contributionTitle,
578
+ format: valueFormat,
579
+ formatType: "arcNumber"
580
+ },
581
+ {
582
+ field: "share",
583
+ type: "quantitative",
584
+ title: shareTitle,
585
+ format: "percent:0",
586
+ formatType: "arcNumber"
587
+ }
588
+ ];
589
+ const layers = [{
590
+ ...tooltip ? { params: [{
591
+ name: HIGHLIGHT_DRIVER_HOVER_PARAM,
592
+ select: {
593
+ type: "point",
594
+ on: "pointerover",
595
+ clear: "pointerout",
596
+ encodings: ["y"]
597
+ }
598
+ }] } : {},
599
+ mark: {
600
+ type: "bar",
601
+ height: barHeight,
602
+ cornerRadiusEnd: 2
603
+ },
604
+ encoding: {
605
+ x: xField,
606
+ y: yField,
607
+ fill: toneColor(tokens, tokens.emphasis),
608
+ fillOpacity: {
609
+ condition: {
610
+ test: "datum.role === 'residual'",
611
+ value: .35
612
+ },
613
+ value: 1
614
+ },
615
+ ...tooltip ? {
616
+ opacity: {
617
+ condition: {
618
+ param: HIGHLIGHT_DRIVER_HOVER_PARAM,
619
+ empty: false,
620
+ value: 1
621
+ },
622
+ value: RESTING_OPACITY
623
+ },
624
+ tooltip: tooltipChannel
625
+ } : {}
626
+ }
627
+ }, {
628
+ data: { name: HIGHLIGHT_ZERO_DATASET },
629
+ mark: {
630
+ type: "rule",
631
+ stroke: tokens.axis,
632
+ strokeWidth: 1,
633
+ opacity: .9,
634
+ aria: false
635
+ },
636
+ encoding: { x: {
637
+ ...xField,
638
+ field: "value"
639
+ } }
640
+ }];
641
+ return {
642
+ $schema: "https://vega.github.io/schema/vega-lite/v6.json",
643
+ width: 240,
644
+ height,
645
+ autosize: {
646
+ type: "fit",
647
+ contains: "padding"
648
+ },
649
+ padding: 0,
650
+ background: "transparent",
651
+ data: { name: HIGHLIGHT_DRIVERS_DATASET },
652
+ layer: layers,
653
+ config: arcVegaConfig(tokens, {
654
+ locale: options.locale,
655
+ timeZone: options.timeZone
656
+ })
657
+ };
658
+ }
659
+ //#endregion
660
+ export { HIGHLIGHT_BAND_DATASET, HIGHLIGHT_DRIVERS_DATASET, HIGHLIGHT_DRIVER_HOVER_PARAM, HIGHLIGHT_ENDPOINTS_DATASET, HIGHLIGHT_END_PARAM, HIGHLIGHT_HOVER_PARAM, HIGHLIGHT_INSIDE_DATASET, HIGHLIGHT_OUTSIDE_DATASET, HIGHLIGHT_PEERS_DATASET, HIGHLIGHT_PEER_HOVER_PARAM, HIGHLIGHT_START_PARAM, HIGHLIGHT_TABLE_DATASET, HIGHLIGHT_TYPICAL_DATASET, HIGHLIGHT_X_TICKS_PARAM, HIGHLIGHT_ZERO_DATASET, MAX_DRIVER_BAR_HEIGHT, buildHighlightContextSpec, buildHighlightDriversSpec, buildHighlightPeersSpec };