@classic-homes/charts-core 0.4.2 → 0.5.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/index.cjs +176 -6
- package/dist/index.d.cts +69 -2
- package/dist/index.d.ts +69 -2
- package/dist/index.js +169 -7
- package/dist/types/index.d.cts +36 -0
- package/dist/types/index.d.ts +36 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -424,6 +424,159 @@ function createTooltipFormatter(options = {}) {
|
|
|
424
424
|
};
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
// src/utils/forecast.ts
|
|
428
|
+
var DEFAULT_FORECAST_LABEL = "Forecast";
|
|
429
|
+
function forecastStart(source) {
|
|
430
|
+
const from = source.forecastFrom;
|
|
431
|
+
if (from == null || !Number.isFinite(from)) return void 0;
|
|
432
|
+
const index = Math.max(0, Math.floor(from));
|
|
433
|
+
return index < source.data.length ? index : void 0;
|
|
434
|
+
}
|
|
435
|
+
function hasForecast(series) {
|
|
436
|
+
return !!series?.some((s) => forecastStart(s) !== void 0);
|
|
437
|
+
}
|
|
438
|
+
function forecastTagLookup(series) {
|
|
439
|
+
if (!hasForecast(series)) return void 0;
|
|
440
|
+
return (dataIndex) => {
|
|
441
|
+
for (const s of series) {
|
|
442
|
+
const from = forecastStart(s);
|
|
443
|
+
if (from !== void 0 && dataIndex >= from) return s.forecastLabel || DEFAULT_FORECAST_LABEL;
|
|
444
|
+
}
|
|
445
|
+
return void 0;
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function describeForecast(categories, series) {
|
|
449
|
+
let first;
|
|
450
|
+
for (const s of series) {
|
|
451
|
+
const from = forecastStart(s);
|
|
452
|
+
if (from === void 0 || first && first.index <= from) continue;
|
|
453
|
+
first = { index: from, label: s.forecastLabel || DEFAULT_FORECAST_LABEL };
|
|
454
|
+
}
|
|
455
|
+
if (!first) return void 0;
|
|
456
|
+
const category = categories[first.index] ?? "";
|
|
457
|
+
return `Values from ${category} onward are marked ${first.label.toLowerCase()}`;
|
|
458
|
+
}
|
|
459
|
+
var isPlainObject = (item) => typeof item === "object" && item !== null && !Array.isArray(item);
|
|
460
|
+
function blank(item) {
|
|
461
|
+
if (Array.isArray(item)) return [item[0], null];
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
function bare(item) {
|
|
465
|
+
return isPlainObject(item) && "value" in item ? item.value : item;
|
|
466
|
+
}
|
|
467
|
+
function withItem(item, extra) {
|
|
468
|
+
if (isPlainObject(item) && "value" in item) {
|
|
469
|
+
return {
|
|
470
|
+
...item,
|
|
471
|
+
...extra,
|
|
472
|
+
itemStyle: { ...item.itemStyle, ...extra.itemStyle }
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
return { value: item, ...extra };
|
|
476
|
+
}
|
|
477
|
+
function withForecastPoints(data, source, pointSize = 0) {
|
|
478
|
+
const from = forecastStart(source);
|
|
479
|
+
if (from === void 0) return [...data];
|
|
480
|
+
const size = Math.max(pointSize, 6) + 1;
|
|
481
|
+
return data.map(
|
|
482
|
+
(item, index) => index >= from ? withItem(item, { symbol: "emptyCircle", symbolSize: size }) : item
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
function withForecastBars(data, source, color) {
|
|
486
|
+
const from = forecastStart(source);
|
|
487
|
+
if (from === void 0) return [...data];
|
|
488
|
+
return data.map(
|
|
489
|
+
(item, index) => index >= from ? withItem(item, {
|
|
490
|
+
itemStyle: {
|
|
491
|
+
opacity: 0.45,
|
|
492
|
+
borderColor: color,
|
|
493
|
+
borderWidth: 1.5,
|
|
494
|
+
borderType: "dashed"
|
|
495
|
+
}
|
|
496
|
+
}) : item
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
function withForecastLines(series, sources, { colors: colors3 }) {
|
|
500
|
+
if (!hasForecast(sources)) return series;
|
|
501
|
+
const stackFrom = /* @__PURE__ */ new Map();
|
|
502
|
+
series.forEach((s, index) => {
|
|
503
|
+
const from = forecastStart(sources[index]);
|
|
504
|
+
if (s.stack == null || from === void 0) return;
|
|
505
|
+
stackFrom.set(s.stack, Math.min(stackFrom.get(s.stack) ?? Infinity, from));
|
|
506
|
+
});
|
|
507
|
+
const mains = [];
|
|
508
|
+
const companions = [];
|
|
509
|
+
series.forEach((s, index) => {
|
|
510
|
+
const from = s.stack != null ? stackFrom.get(s.stack) : forecastStart(sources[index]);
|
|
511
|
+
if (from === void 0) {
|
|
512
|
+
mains.push(s);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
const color = colors3[index];
|
|
516
|
+
const itemStyle = { ...s.itemStyle, color };
|
|
517
|
+
if (from === 0) {
|
|
518
|
+
mains.push({
|
|
519
|
+
...s,
|
|
520
|
+
itemStyle,
|
|
521
|
+
lineStyle: { ...s.lineStyle, type: "dashed" },
|
|
522
|
+
...s.areaStyle && { areaStyle: fadedArea(s.areaStyle) }
|
|
523
|
+
});
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const data = s.data ?? [];
|
|
527
|
+
const common = {
|
|
528
|
+
name: s.name,
|
|
529
|
+
type: "line",
|
|
530
|
+
smooth: s.smooth,
|
|
531
|
+
connectNulls: s.connectNulls,
|
|
532
|
+
showSymbol: false,
|
|
533
|
+
symbol: "none",
|
|
534
|
+
silent: true,
|
|
535
|
+
legendHoverLink: false,
|
|
536
|
+
tooltip: { show: false },
|
|
537
|
+
emphasis: { disabled: true },
|
|
538
|
+
itemStyle,
|
|
539
|
+
z: s.z
|
|
540
|
+
};
|
|
541
|
+
companions.push(
|
|
542
|
+
{
|
|
543
|
+
...common,
|
|
544
|
+
data: data.map((item, i) => i < from ? bare(item) : blank(item)),
|
|
545
|
+
stack: s.stack != null ? `${s.stack}\0actual` : void 0,
|
|
546
|
+
lineStyle: s.lineStyle,
|
|
547
|
+
areaStyle: s.areaStyle
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
...common,
|
|
551
|
+
data: data.map((item, i) => i >= from - 1 ? bare(item) : blank(item)),
|
|
552
|
+
stack: s.stack != null ? `${s.stack}\0forecast` : void 0,
|
|
553
|
+
lineStyle: { ...s.lineStyle, type: "dashed" },
|
|
554
|
+
areaStyle: s.areaStyle ? fadedArea(s.areaStyle) : void 0
|
|
555
|
+
}
|
|
556
|
+
);
|
|
557
|
+
mains.push({
|
|
558
|
+
...s,
|
|
559
|
+
itemStyle,
|
|
560
|
+
// Forecast points carry their own size; the rest keep theirs (none
|
|
561
|
+
// when the series hid its points)
|
|
562
|
+
showSymbol: true,
|
|
563
|
+
symbolSize: s.showSymbol === false ? 0 : s.symbolSize ?? 4,
|
|
564
|
+
lineStyle: { ...s.lineStyle, opacity: 0 },
|
|
565
|
+
areaStyle: void 0,
|
|
566
|
+
emphasis: {
|
|
567
|
+
...s.emphasis,
|
|
568
|
+
focus: "none",
|
|
569
|
+
lineStyle: { ...s.emphasis?.lineStyle, opacity: 0 }
|
|
570
|
+
},
|
|
571
|
+
z: (s.z ?? 2) + 1
|
|
572
|
+
});
|
|
573
|
+
});
|
|
574
|
+
return [...mains, ...companions];
|
|
575
|
+
}
|
|
576
|
+
function fadedArea(areaStyle) {
|
|
577
|
+
return { ...areaStyle, opacity: (areaStyle.opacity ?? 0.7) * 0.5 };
|
|
578
|
+
}
|
|
579
|
+
|
|
427
580
|
// src/utils/accessibility.ts
|
|
428
581
|
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
429
582
|
function seriesList(names) {
|
|
@@ -449,6 +602,8 @@ function describeTrends(title, kind, data, format) {
|
|
|
449
602
|
0
|
|
450
603
|
);
|
|
451
604
|
if (missing > 0) description += `. ${missing} values are missing`;
|
|
605
|
+
const forecast = describeForecast(data.categories, data.series);
|
|
606
|
+
if (forecast) description += `. ${forecast}`;
|
|
452
607
|
return description;
|
|
453
608
|
}
|
|
454
609
|
function generateLineChartDescription(title, data, format) {
|
|
@@ -484,6 +639,8 @@ function generateBarChartDescription(title, data, format) {
|
|
|
484
639
|
if (max && min) {
|
|
485
640
|
description += `. Highest value is ${formatValue(max.value, format)} for ${max.category}. Lowest value is ${formatValue(min.value, format)} for ${min.category}`;
|
|
486
641
|
}
|
|
642
|
+
const forecast = describeForecast(data.categories, data.series);
|
|
643
|
+
if (forecast) description += `. ${forecast}`;
|
|
487
644
|
return description;
|
|
488
645
|
}
|
|
489
646
|
function generateDotPlotDescription(title, data, format) {
|
|
@@ -617,7 +774,7 @@ function getReplaceMerge(prev, next, isComponentType) {
|
|
|
617
774
|
}
|
|
618
775
|
return [...types].filter((type) => isComponentType(type));
|
|
619
776
|
}
|
|
620
|
-
function
|
|
777
|
+
function isPlainObject2(value) {
|
|
621
778
|
if (value === null || typeof value !== "object") return false;
|
|
622
779
|
const proto = Object.getPrototypeOf(value);
|
|
623
780
|
return proto === Object.prototype || proto === null;
|
|
@@ -630,7 +787,7 @@ function mergeValue(base, override, topLevel = false) {
|
|
|
630
787
|
const length = Math.max(from.length, to.length);
|
|
631
788
|
return Array.from({ length }, (_, index) => mergeValue(from[index], to[index]));
|
|
632
789
|
}
|
|
633
|
-
if (
|
|
790
|
+
if (isPlainObject2(base) && isPlainObject2(override)) {
|
|
634
791
|
const merged = { ...base };
|
|
635
792
|
for (const key of Object.keys(override)) {
|
|
636
793
|
merged[key] = mergeValue(base[key], override[key]);
|
|
@@ -1038,12 +1195,17 @@ function nameLabelLookup(nodes) {
|
|
|
1038
1195
|
function hasPointLabels(series) {
|
|
1039
1196
|
return series.some((s) => s.labels?.some((text) => text != null && text !== ""));
|
|
1040
1197
|
}
|
|
1041
|
-
function buildTooltip(base, { show, formatter, valueFormatter, getLabel }) {
|
|
1198
|
+
function buildTooltip(base, { show, formatter, valueFormatter, getLabel, forecastTag }) {
|
|
1042
1199
|
if (!show) return void 0;
|
|
1043
|
-
if (formatter === void 0 && valueFormatter === void 0) return base;
|
|
1200
|
+
if (formatter === void 0 && valueFormatter === void 0 && !forecastTag) return base;
|
|
1044
1201
|
const tooltip = { ...base };
|
|
1045
|
-
if (valueFormatter) {
|
|
1046
|
-
|
|
1202
|
+
if (valueFormatter || forecastTag) {
|
|
1203
|
+
const format = (value) => typeof value === "number" ? valueFormatter ? valueFormatter(value) : value.toLocaleString() : String(value ?? "");
|
|
1204
|
+
tooltip.valueFormatter = (value, dataIndex) => {
|
|
1205
|
+
const text = format(value);
|
|
1206
|
+
const tag = dataIndex === void 0 ? void 0 : forecastTag?.(dataIndex);
|
|
1207
|
+
return tag && value != null ? `${text} (${tag})` : text;
|
|
1208
|
+
};
|
|
1047
1209
|
}
|
|
1048
1210
|
if (typeof formatter === "string") {
|
|
1049
1211
|
tooltip.formatter = formatter;
|
|
@@ -1587,6 +1749,7 @@ function downloadCsv(table, filename) {
|
|
|
1587
1749
|
);
|
|
1588
1750
|
}
|
|
1589
1751
|
|
|
1752
|
+
exports.DEFAULT_FORECAST_LABEL = DEFAULT_FORECAST_LABEL;
|
|
1590
1753
|
exports.THEME_DARK = THEME_DARK;
|
|
1591
1754
|
exports.THEME_LIGHT = THEME_LIGHT;
|
|
1592
1755
|
exports.abbreviateNumber = abbreviateNumber;
|
|
@@ -1614,9 +1777,12 @@ exports.computeDelta = computeDelta;
|
|
|
1614
1777
|
exports.createTooltipFormatter = createTooltipFormatter;
|
|
1615
1778
|
exports.darkChartColors = darkChartColors;
|
|
1616
1779
|
exports.darkTheme = darkTheme;
|
|
1780
|
+
exports.describeForecast = describeForecast;
|
|
1617
1781
|
exports.downloadCsv = downloadCsv;
|
|
1618
1782
|
exports.downloadFile = downloadFile;
|
|
1619
1783
|
exports.escapeHtml = escapeHtml;
|
|
1784
|
+
exports.forecastStart = forecastStart;
|
|
1785
|
+
exports.forecastTagLookup = forecastTagLookup;
|
|
1620
1786
|
exports.formatCurrency = formatCurrency;
|
|
1621
1787
|
exports.formatDate = formatDate;
|
|
1622
1788
|
exports.formatNumber = formatNumber;
|
|
@@ -1643,6 +1809,7 @@ exports.getChartColors = getChartColors;
|
|
|
1643
1809
|
exports.getLegendItems = getLegendItems;
|
|
1644
1810
|
exports.getReplaceMerge = getReplaceMerge;
|
|
1645
1811
|
exports.gridInset = gridInset;
|
|
1812
|
+
exports.hasForecast = hasForecast;
|
|
1646
1813
|
exports.hasPointLabels = hasPointLabels;
|
|
1647
1814
|
exports.heatmapTable = heatmapTable;
|
|
1648
1815
|
exports.histogramTable = histogramTable;
|
|
@@ -1674,6 +1841,9 @@ exports.valueLabelFormatter = valueLabelFormatter;
|
|
|
1674
1841
|
exports.waterfallLayout = waterfallLayout;
|
|
1675
1842
|
exports.waterfallTable = waterfallTable;
|
|
1676
1843
|
exports.withEndLabelInset = withEndLabelInset;
|
|
1844
|
+
exports.withForecastBars = withForecastBars;
|
|
1845
|
+
exports.withForecastLines = withForecastLines;
|
|
1846
|
+
exports.withForecastPoints = withForecastPoints;
|
|
1677
1847
|
exports.withPointLabels = withPointLabels;
|
|
1678
1848
|
exports.withReferenceMarks = withReferenceMarks;
|
|
1679
1849
|
exports.withZoomInset = withZoomInset;
|
package/dist/index.d.cts
CHANGED
|
@@ -151,6 +151,71 @@ declare function getReplaceMerge(prev: object | null | undefined, next: object,
|
|
|
151
151
|
*/
|
|
152
152
|
declare function mergeChartOption<T extends object>(generated: T, override: object | undefined): T;
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Forecast stretches: the tail of a series whose values are projections (or a
|
|
156
|
+
* period still in progress, such as the current month). Lines draw it dashed
|
|
157
|
+
* with hollow points, bars draw it faded with a dashed outline, and the
|
|
158
|
+
* tooltip tags its values.
|
|
159
|
+
*/
|
|
160
|
+
type AnyObject$1 = Record<string, any>;
|
|
161
|
+
declare const DEFAULT_FORECAST_LABEL = "Forecast";
|
|
162
|
+
/** The forecast fields a series may carry */
|
|
163
|
+
interface ForecastSource {
|
|
164
|
+
data: readonly unknown[];
|
|
165
|
+
forecastFrom?: number;
|
|
166
|
+
forecastLabel?: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Index of a series' first forecast point, or `undefined` when it has none
|
|
170
|
+
* (no `forecastFrom`, or one past the end of the data).
|
|
171
|
+
*/
|
|
172
|
+
declare function forecastStart(source: ForecastSource): number | undefined;
|
|
173
|
+
/** Whether any series has a forecast stretch */
|
|
174
|
+
declare function hasForecast(series: readonly ForecastSource[] | undefined): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Tooltip tag by data index: the label of the first series forecasting at
|
|
177
|
+
* that index. ECharts' `valueFormatter` only knows the index, so series that
|
|
178
|
+
* share an index share its tag.
|
|
179
|
+
*/
|
|
180
|
+
declare function forecastTagLookup(series: readonly ForecastSource[]): ((dataIndex: number) => string | undefined) | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* The first category where any series' forecast starts, for accessible
|
|
183
|
+
* descriptions
|
|
184
|
+
*/
|
|
185
|
+
declare function describeForecast(categories: readonly string[], series: readonly ForecastSource[]): string | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Line forecast points: hollow, a little larger than the series' own points.
|
|
188
|
+
* Returns the data unchanged when the series has no forecast.
|
|
189
|
+
*/
|
|
190
|
+
declare function withForecastPoints(data: readonly unknown[], source: ForecastSource,
|
|
191
|
+
/** The series' own point size (0 when its points are hidden) */
|
|
192
|
+
pointSize?: number): unknown[];
|
|
193
|
+
/**
|
|
194
|
+
* Bar forecast items: faded, with a dashed outline in the series colour.
|
|
195
|
+
* Returns the data unchanged when the series has no forecast.
|
|
196
|
+
*/
|
|
197
|
+
declare function withForecastBars(data: readonly unknown[], source: ForecastSource, color: string): unknown[];
|
|
198
|
+
interface ForecastLineOptions {
|
|
199
|
+
/** Resolved colour per series (explicit colour, else the theme palette) */
|
|
200
|
+
colors: readonly string[];
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Draw line series' forecast stretches dashed.
|
|
204
|
+
*
|
|
205
|
+
* ECharts styles a line as a whole, so a series with a forecast keeps its
|
|
206
|
+
* full data for the tooltip, points and labels but hides its own line; two
|
|
207
|
+
* silent companions (same name, so the legend toggles them together) draw
|
|
208
|
+
* it: a solid one up to the last actual point, and a dashed one from there
|
|
209
|
+
* to the end. Series stacked together split at the same index (the earliest
|
|
210
|
+
* forecast in the stack) and stack in parallel groups, so the companions'
|
|
211
|
+
* totals match the series'.
|
|
212
|
+
*
|
|
213
|
+
* Series that forecast from their first point are simply dashed. Returns
|
|
214
|
+
* the series unchanged when none has a forecast. Apply reference marks
|
|
215
|
+
* before this, so they attach to the series rather than the companions.
|
|
216
|
+
*/
|
|
217
|
+
declare function withForecastLines<S extends AnyObject$1>(series: S[], sources: readonly ForecastSource[], { colors }: ForecastLineOptions): AnyObject$1[];
|
|
218
|
+
|
|
154
219
|
/**
|
|
155
220
|
* Builders for the label, axis, tooltip and legend parts of a chart option.
|
|
156
221
|
*
|
|
@@ -268,11 +333,13 @@ interface BuildTooltipOptions {
|
|
|
268
333
|
valueFormatter?: (value: number) => string;
|
|
269
334
|
/** Per-point label lookup, exposed to formatter functions as `label` */
|
|
270
335
|
getLabel?: PointLabelLookup;
|
|
336
|
+
/** Tag for forecast values by data index (see `forecastTagLookup`) */
|
|
337
|
+
forecastTag?: (dataIndex: number) => string | undefined;
|
|
271
338
|
}
|
|
272
339
|
/**
|
|
273
340
|
* Build the `tooltip` component. `base` is the chart's default tooltip.
|
|
274
341
|
*/
|
|
275
|
-
declare function buildTooltip(base: AnyObject, { show, formatter, valueFormatter, getLabel }: BuildTooltipOptions): AnyObject | undefined;
|
|
342
|
+
declare function buildTooltip(base: AnyObject, { show, formatter, valueFormatter, getLabel, forecastTag }: BuildTooltipOptions): AnyObject | undefined;
|
|
276
343
|
/**
|
|
277
344
|
* Format a value with `tooltipValueFormatter`, for charts whose default
|
|
278
345
|
* tooltip is custom HTML (where ECharts' `valueFormatter` does not apply)
|
|
@@ -677,4 +744,4 @@ declare function downloadFile(content: string, filename: string, mimeType?: stri
|
|
|
677
744
|
*/
|
|
678
745
|
declare function downloadCsv(table: ChartDataTable, filename: string): void;
|
|
679
746
|
|
|
680
|
-
export { type Accessor, type Aggregate, type AutoHeightOptions, AxisConfig, BarChartData, type BinValuesOptions, BoxPlotStats, type BuildDataLabelOptions, type BuildLegendOptions, type BuildTooltipOptions, BulletItem, CandlestickData, CategoryChartData, CategorySeriesData, ChartDataTable, ChartFormatter, type ChartFormatterOptions, type ChartFormatters, ChartLegendConfig, type Delta, type FromRecordsOptions, HeatmapData, HistogramBin, HistogramBucket, LabelFormatterParams, LegendItem, LineChartData, PieSliceData, type PointLabelLookup, RadarChartData, RadarIndicator, ReferenceBand, ReferenceLine, type ReferenceMarkOptions, SankeyData, ScatterChartData, type StackTotalOptions, type ToSliceDataOptions, TooltipFormatterParams, TreemapNode, ValueFormat, type WaterfallBar, WaterfallStep, abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, downloadCsv, downloadFile, escapeHtml, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withPointLabels, withReferenceMarks, withZoomInset };
|
|
747
|
+
export { type Accessor, type Aggregate, type AutoHeightOptions, AxisConfig, BarChartData, type BinValuesOptions, BoxPlotStats, type BuildDataLabelOptions, type BuildLegendOptions, type BuildTooltipOptions, BulletItem, CandlestickData, CategoryChartData, CategorySeriesData, ChartDataTable, ChartFormatter, type ChartFormatterOptions, type ChartFormatters, ChartLegendConfig, DEFAULT_FORECAST_LABEL, type Delta, type ForecastLineOptions, type ForecastSource, type FromRecordsOptions, HeatmapData, HistogramBin, HistogramBucket, LabelFormatterParams, LegendItem, LineChartData, PieSliceData, type PointLabelLookup, RadarChartData, RadarIndicator, ReferenceBand, ReferenceLine, type ReferenceMarkOptions, SankeyData, ScatterChartData, type StackTotalOptions, type ToSliceDataOptions, TooltipFormatterParams, TreemapNode, ValueFormat, type WaterfallBar, WaterfallStep, abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, describeForecast, downloadCsv, downloadFile, escapeHtml, forecastStart, forecastTagLookup, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasForecast, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withForecastBars, withForecastLines, withForecastPoints, withPointLabels, withReferenceMarks, withZoomInset };
|
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,71 @@ declare function getReplaceMerge(prev: object | null | undefined, next: object,
|
|
|
151
151
|
*/
|
|
152
152
|
declare function mergeChartOption<T extends object>(generated: T, override: object | undefined): T;
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Forecast stretches: the tail of a series whose values are projections (or a
|
|
156
|
+
* period still in progress, such as the current month). Lines draw it dashed
|
|
157
|
+
* with hollow points, bars draw it faded with a dashed outline, and the
|
|
158
|
+
* tooltip tags its values.
|
|
159
|
+
*/
|
|
160
|
+
type AnyObject$1 = Record<string, any>;
|
|
161
|
+
declare const DEFAULT_FORECAST_LABEL = "Forecast";
|
|
162
|
+
/** The forecast fields a series may carry */
|
|
163
|
+
interface ForecastSource {
|
|
164
|
+
data: readonly unknown[];
|
|
165
|
+
forecastFrom?: number;
|
|
166
|
+
forecastLabel?: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Index of a series' first forecast point, or `undefined` when it has none
|
|
170
|
+
* (no `forecastFrom`, or one past the end of the data).
|
|
171
|
+
*/
|
|
172
|
+
declare function forecastStart(source: ForecastSource): number | undefined;
|
|
173
|
+
/** Whether any series has a forecast stretch */
|
|
174
|
+
declare function hasForecast(series: readonly ForecastSource[] | undefined): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Tooltip tag by data index: the label of the first series forecasting at
|
|
177
|
+
* that index. ECharts' `valueFormatter` only knows the index, so series that
|
|
178
|
+
* share an index share its tag.
|
|
179
|
+
*/
|
|
180
|
+
declare function forecastTagLookup(series: readonly ForecastSource[]): ((dataIndex: number) => string | undefined) | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* The first category where any series' forecast starts, for accessible
|
|
183
|
+
* descriptions
|
|
184
|
+
*/
|
|
185
|
+
declare function describeForecast(categories: readonly string[], series: readonly ForecastSource[]): string | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Line forecast points: hollow, a little larger than the series' own points.
|
|
188
|
+
* Returns the data unchanged when the series has no forecast.
|
|
189
|
+
*/
|
|
190
|
+
declare function withForecastPoints(data: readonly unknown[], source: ForecastSource,
|
|
191
|
+
/** The series' own point size (0 when its points are hidden) */
|
|
192
|
+
pointSize?: number): unknown[];
|
|
193
|
+
/**
|
|
194
|
+
* Bar forecast items: faded, with a dashed outline in the series colour.
|
|
195
|
+
* Returns the data unchanged when the series has no forecast.
|
|
196
|
+
*/
|
|
197
|
+
declare function withForecastBars(data: readonly unknown[], source: ForecastSource, color: string): unknown[];
|
|
198
|
+
interface ForecastLineOptions {
|
|
199
|
+
/** Resolved colour per series (explicit colour, else the theme palette) */
|
|
200
|
+
colors: readonly string[];
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Draw line series' forecast stretches dashed.
|
|
204
|
+
*
|
|
205
|
+
* ECharts styles a line as a whole, so a series with a forecast keeps its
|
|
206
|
+
* full data for the tooltip, points and labels but hides its own line; two
|
|
207
|
+
* silent companions (same name, so the legend toggles them together) draw
|
|
208
|
+
* it: a solid one up to the last actual point, and a dashed one from there
|
|
209
|
+
* to the end. Series stacked together split at the same index (the earliest
|
|
210
|
+
* forecast in the stack) and stack in parallel groups, so the companions'
|
|
211
|
+
* totals match the series'.
|
|
212
|
+
*
|
|
213
|
+
* Series that forecast from their first point are simply dashed. Returns
|
|
214
|
+
* the series unchanged when none has a forecast. Apply reference marks
|
|
215
|
+
* before this, so they attach to the series rather than the companions.
|
|
216
|
+
*/
|
|
217
|
+
declare function withForecastLines<S extends AnyObject$1>(series: S[], sources: readonly ForecastSource[], { colors }: ForecastLineOptions): AnyObject$1[];
|
|
218
|
+
|
|
154
219
|
/**
|
|
155
220
|
* Builders for the label, axis, tooltip and legend parts of a chart option.
|
|
156
221
|
*
|
|
@@ -268,11 +333,13 @@ interface BuildTooltipOptions {
|
|
|
268
333
|
valueFormatter?: (value: number) => string;
|
|
269
334
|
/** Per-point label lookup, exposed to formatter functions as `label` */
|
|
270
335
|
getLabel?: PointLabelLookup;
|
|
336
|
+
/** Tag for forecast values by data index (see `forecastTagLookup`) */
|
|
337
|
+
forecastTag?: (dataIndex: number) => string | undefined;
|
|
271
338
|
}
|
|
272
339
|
/**
|
|
273
340
|
* Build the `tooltip` component. `base` is the chart's default tooltip.
|
|
274
341
|
*/
|
|
275
|
-
declare function buildTooltip(base: AnyObject, { show, formatter, valueFormatter, getLabel }: BuildTooltipOptions): AnyObject | undefined;
|
|
342
|
+
declare function buildTooltip(base: AnyObject, { show, formatter, valueFormatter, getLabel, forecastTag }: BuildTooltipOptions): AnyObject | undefined;
|
|
276
343
|
/**
|
|
277
344
|
* Format a value with `tooltipValueFormatter`, for charts whose default
|
|
278
345
|
* tooltip is custom HTML (where ECharts' `valueFormatter` does not apply)
|
|
@@ -677,4 +744,4 @@ declare function downloadFile(content: string, filename: string, mimeType?: stri
|
|
|
677
744
|
*/
|
|
678
745
|
declare function downloadCsv(table: ChartDataTable, filename: string): void;
|
|
679
746
|
|
|
680
|
-
export { type Accessor, type Aggregate, type AutoHeightOptions, AxisConfig, BarChartData, type BinValuesOptions, BoxPlotStats, type BuildDataLabelOptions, type BuildLegendOptions, type BuildTooltipOptions, BulletItem, CandlestickData, CategoryChartData, CategorySeriesData, ChartDataTable, ChartFormatter, type ChartFormatterOptions, type ChartFormatters, ChartLegendConfig, type Delta, type FromRecordsOptions, HeatmapData, HistogramBin, HistogramBucket, LabelFormatterParams, LegendItem, LineChartData, PieSliceData, type PointLabelLookup, RadarChartData, RadarIndicator, ReferenceBand, ReferenceLine, type ReferenceMarkOptions, SankeyData, ScatterChartData, type StackTotalOptions, type ToSliceDataOptions, TooltipFormatterParams, TreemapNode, ValueFormat, type WaterfallBar, WaterfallStep, abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, downloadCsv, downloadFile, escapeHtml, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withPointLabels, withReferenceMarks, withZoomInset };
|
|
747
|
+
export { type Accessor, type Aggregate, type AutoHeightOptions, AxisConfig, BarChartData, type BinValuesOptions, BoxPlotStats, type BuildDataLabelOptions, type BuildLegendOptions, type BuildTooltipOptions, BulletItem, CandlestickData, CategoryChartData, CategorySeriesData, ChartDataTable, ChartFormatter, type ChartFormatterOptions, type ChartFormatters, ChartLegendConfig, DEFAULT_FORECAST_LABEL, type Delta, type ForecastLineOptions, type ForecastSource, type FromRecordsOptions, HeatmapData, HistogramBin, HistogramBucket, LabelFormatterParams, LegendItem, LineChartData, PieSliceData, type PointLabelLookup, RadarChartData, RadarIndicator, ReferenceBand, ReferenceLine, type ReferenceMarkOptions, SankeyData, ScatterChartData, type StackTotalOptions, type ToSliceDataOptions, TooltipFormatterParams, TreemapNode, ValueFormat, type WaterfallBar, WaterfallStep, abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, describeForecast, downloadCsv, downloadFile, escapeHtml, forecastStart, forecastTagLookup, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasForecast, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withForecastBars, withForecastLines, withForecastPoints, withPointLabels, withReferenceMarks, withZoomInset };
|
package/dist/index.js
CHANGED
|
@@ -103,6 +103,159 @@ function createTooltipFormatter(options = {}) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
// src/utils/forecast.ts
|
|
107
|
+
var DEFAULT_FORECAST_LABEL = "Forecast";
|
|
108
|
+
function forecastStart(source) {
|
|
109
|
+
const from = source.forecastFrom;
|
|
110
|
+
if (from == null || !Number.isFinite(from)) return void 0;
|
|
111
|
+
const index = Math.max(0, Math.floor(from));
|
|
112
|
+
return index < source.data.length ? index : void 0;
|
|
113
|
+
}
|
|
114
|
+
function hasForecast(series) {
|
|
115
|
+
return !!series?.some((s) => forecastStart(s) !== void 0);
|
|
116
|
+
}
|
|
117
|
+
function forecastTagLookup(series) {
|
|
118
|
+
if (!hasForecast(series)) return void 0;
|
|
119
|
+
return (dataIndex) => {
|
|
120
|
+
for (const s of series) {
|
|
121
|
+
const from = forecastStart(s);
|
|
122
|
+
if (from !== void 0 && dataIndex >= from) return s.forecastLabel || DEFAULT_FORECAST_LABEL;
|
|
123
|
+
}
|
|
124
|
+
return void 0;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function describeForecast(categories, series) {
|
|
128
|
+
let first;
|
|
129
|
+
for (const s of series) {
|
|
130
|
+
const from = forecastStart(s);
|
|
131
|
+
if (from === void 0 || first && first.index <= from) continue;
|
|
132
|
+
first = { index: from, label: s.forecastLabel || DEFAULT_FORECAST_LABEL };
|
|
133
|
+
}
|
|
134
|
+
if (!first) return void 0;
|
|
135
|
+
const category = categories[first.index] ?? "";
|
|
136
|
+
return `Values from ${category} onward are marked ${first.label.toLowerCase()}`;
|
|
137
|
+
}
|
|
138
|
+
var isPlainObject = (item) => typeof item === "object" && item !== null && !Array.isArray(item);
|
|
139
|
+
function blank(item) {
|
|
140
|
+
if (Array.isArray(item)) return [item[0], null];
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
function bare(item) {
|
|
144
|
+
return isPlainObject(item) && "value" in item ? item.value : item;
|
|
145
|
+
}
|
|
146
|
+
function withItem(item, extra) {
|
|
147
|
+
if (isPlainObject(item) && "value" in item) {
|
|
148
|
+
return {
|
|
149
|
+
...item,
|
|
150
|
+
...extra,
|
|
151
|
+
itemStyle: { ...item.itemStyle, ...extra.itemStyle }
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return { value: item, ...extra };
|
|
155
|
+
}
|
|
156
|
+
function withForecastPoints(data, source, pointSize = 0) {
|
|
157
|
+
const from = forecastStart(source);
|
|
158
|
+
if (from === void 0) return [...data];
|
|
159
|
+
const size = Math.max(pointSize, 6) + 1;
|
|
160
|
+
return data.map(
|
|
161
|
+
(item, index) => index >= from ? withItem(item, { symbol: "emptyCircle", symbolSize: size }) : item
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
function withForecastBars(data, source, color) {
|
|
165
|
+
const from = forecastStart(source);
|
|
166
|
+
if (from === void 0) return [...data];
|
|
167
|
+
return data.map(
|
|
168
|
+
(item, index) => index >= from ? withItem(item, {
|
|
169
|
+
itemStyle: {
|
|
170
|
+
opacity: 0.45,
|
|
171
|
+
borderColor: color,
|
|
172
|
+
borderWidth: 1.5,
|
|
173
|
+
borderType: "dashed"
|
|
174
|
+
}
|
|
175
|
+
}) : item
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
function withForecastLines(series, sources, { colors }) {
|
|
179
|
+
if (!hasForecast(sources)) return series;
|
|
180
|
+
const stackFrom = /* @__PURE__ */ new Map();
|
|
181
|
+
series.forEach((s, index) => {
|
|
182
|
+
const from = forecastStart(sources[index]);
|
|
183
|
+
if (s.stack == null || from === void 0) return;
|
|
184
|
+
stackFrom.set(s.stack, Math.min(stackFrom.get(s.stack) ?? Infinity, from));
|
|
185
|
+
});
|
|
186
|
+
const mains = [];
|
|
187
|
+
const companions = [];
|
|
188
|
+
series.forEach((s, index) => {
|
|
189
|
+
const from = s.stack != null ? stackFrom.get(s.stack) : forecastStart(sources[index]);
|
|
190
|
+
if (from === void 0) {
|
|
191
|
+
mains.push(s);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const color = colors[index];
|
|
195
|
+
const itemStyle = { ...s.itemStyle, color };
|
|
196
|
+
if (from === 0) {
|
|
197
|
+
mains.push({
|
|
198
|
+
...s,
|
|
199
|
+
itemStyle,
|
|
200
|
+
lineStyle: { ...s.lineStyle, type: "dashed" },
|
|
201
|
+
...s.areaStyle && { areaStyle: fadedArea(s.areaStyle) }
|
|
202
|
+
});
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const data = s.data ?? [];
|
|
206
|
+
const common = {
|
|
207
|
+
name: s.name,
|
|
208
|
+
type: "line",
|
|
209
|
+
smooth: s.smooth,
|
|
210
|
+
connectNulls: s.connectNulls,
|
|
211
|
+
showSymbol: false,
|
|
212
|
+
symbol: "none",
|
|
213
|
+
silent: true,
|
|
214
|
+
legendHoverLink: false,
|
|
215
|
+
tooltip: { show: false },
|
|
216
|
+
emphasis: { disabled: true },
|
|
217
|
+
itemStyle,
|
|
218
|
+
z: s.z
|
|
219
|
+
};
|
|
220
|
+
companions.push(
|
|
221
|
+
{
|
|
222
|
+
...common,
|
|
223
|
+
data: data.map((item, i) => i < from ? bare(item) : blank(item)),
|
|
224
|
+
stack: s.stack != null ? `${s.stack}\0actual` : void 0,
|
|
225
|
+
lineStyle: s.lineStyle,
|
|
226
|
+
areaStyle: s.areaStyle
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
...common,
|
|
230
|
+
data: data.map((item, i) => i >= from - 1 ? bare(item) : blank(item)),
|
|
231
|
+
stack: s.stack != null ? `${s.stack}\0forecast` : void 0,
|
|
232
|
+
lineStyle: { ...s.lineStyle, type: "dashed" },
|
|
233
|
+
areaStyle: s.areaStyle ? fadedArea(s.areaStyle) : void 0
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
mains.push({
|
|
237
|
+
...s,
|
|
238
|
+
itemStyle,
|
|
239
|
+
// Forecast points carry their own size; the rest keep theirs (none
|
|
240
|
+
// when the series hid its points)
|
|
241
|
+
showSymbol: true,
|
|
242
|
+
symbolSize: s.showSymbol === false ? 0 : s.symbolSize ?? 4,
|
|
243
|
+
lineStyle: { ...s.lineStyle, opacity: 0 },
|
|
244
|
+
areaStyle: void 0,
|
|
245
|
+
emphasis: {
|
|
246
|
+
...s.emphasis,
|
|
247
|
+
focus: "none",
|
|
248
|
+
lineStyle: { ...s.emphasis?.lineStyle, opacity: 0 }
|
|
249
|
+
},
|
|
250
|
+
z: (s.z ?? 2) + 1
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
return [...mains, ...companions];
|
|
254
|
+
}
|
|
255
|
+
function fadedArea(areaStyle) {
|
|
256
|
+
return { ...areaStyle, opacity: (areaStyle.opacity ?? 0.7) * 0.5 };
|
|
257
|
+
}
|
|
258
|
+
|
|
106
259
|
// src/utils/accessibility.ts
|
|
107
260
|
var isNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
108
261
|
function seriesList(names) {
|
|
@@ -128,6 +281,8 @@ function describeTrends(title, kind, data, format) {
|
|
|
128
281
|
0
|
|
129
282
|
);
|
|
130
283
|
if (missing > 0) description += `. ${missing} values are missing`;
|
|
284
|
+
const forecast = describeForecast(data.categories, data.series);
|
|
285
|
+
if (forecast) description += `. ${forecast}`;
|
|
131
286
|
return description;
|
|
132
287
|
}
|
|
133
288
|
function generateLineChartDescription(title, data, format) {
|
|
@@ -163,6 +318,8 @@ function generateBarChartDescription(title, data, format) {
|
|
|
163
318
|
if (max && min) {
|
|
164
319
|
description += `. Highest value is ${formatValue(max.value, format)} for ${max.category}. Lowest value is ${formatValue(min.value, format)} for ${min.category}`;
|
|
165
320
|
}
|
|
321
|
+
const forecast = describeForecast(data.categories, data.series);
|
|
322
|
+
if (forecast) description += `. ${forecast}`;
|
|
166
323
|
return description;
|
|
167
324
|
}
|
|
168
325
|
function generateDotPlotDescription(title, data, format) {
|
|
@@ -296,7 +453,7 @@ function getReplaceMerge(prev, next, isComponentType) {
|
|
|
296
453
|
}
|
|
297
454
|
return [...types].filter((type) => isComponentType(type));
|
|
298
455
|
}
|
|
299
|
-
function
|
|
456
|
+
function isPlainObject2(value) {
|
|
300
457
|
if (value === null || typeof value !== "object") return false;
|
|
301
458
|
const proto = Object.getPrototypeOf(value);
|
|
302
459
|
return proto === Object.prototype || proto === null;
|
|
@@ -309,7 +466,7 @@ function mergeValue(base, override, topLevel = false) {
|
|
|
309
466
|
const length = Math.max(from.length, to.length);
|
|
310
467
|
return Array.from({ length }, (_, index) => mergeValue(from[index], to[index]));
|
|
311
468
|
}
|
|
312
|
-
if (
|
|
469
|
+
if (isPlainObject2(base) && isPlainObject2(override)) {
|
|
313
470
|
const merged = { ...base };
|
|
314
471
|
for (const key of Object.keys(override)) {
|
|
315
472
|
merged[key] = mergeValue(base[key], override[key]);
|
|
@@ -717,12 +874,17 @@ function nameLabelLookup(nodes) {
|
|
|
717
874
|
function hasPointLabels(series) {
|
|
718
875
|
return series.some((s) => s.labels?.some((text) => text != null && text !== ""));
|
|
719
876
|
}
|
|
720
|
-
function buildTooltip(base, { show, formatter, valueFormatter, getLabel }) {
|
|
877
|
+
function buildTooltip(base, { show, formatter, valueFormatter, getLabel, forecastTag }) {
|
|
721
878
|
if (!show) return void 0;
|
|
722
|
-
if (formatter === void 0 && valueFormatter === void 0) return base;
|
|
879
|
+
if (formatter === void 0 && valueFormatter === void 0 && !forecastTag) return base;
|
|
723
880
|
const tooltip = { ...base };
|
|
724
|
-
if (valueFormatter) {
|
|
725
|
-
|
|
881
|
+
if (valueFormatter || forecastTag) {
|
|
882
|
+
const format = (value) => typeof value === "number" ? valueFormatter ? valueFormatter(value) : value.toLocaleString() : String(value ?? "");
|
|
883
|
+
tooltip.valueFormatter = (value, dataIndex) => {
|
|
884
|
+
const text = format(value);
|
|
885
|
+
const tag = dataIndex === void 0 ? void 0 : forecastTag?.(dataIndex);
|
|
886
|
+
return tag && value != null ? `${text} (${tag})` : text;
|
|
887
|
+
};
|
|
726
888
|
}
|
|
727
889
|
if (typeof formatter === "string") {
|
|
728
890
|
tooltip.formatter = formatter;
|
|
@@ -1266,4 +1428,4 @@ function downloadCsv(table, filename) {
|
|
|
1266
1428
|
);
|
|
1267
1429
|
}
|
|
1268
1430
|
|
|
1269
|
-
export { abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, downloadCsv, downloadFile, escapeHtml, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withPointLabels, withReferenceMarks, withZoomInset };
|
|
1431
|
+
export { DEFAULT_FORECAST_LABEL, abbreviateNumber, allSeriesEmpty, anchorCenterGraphic, barCornerRadius, binValues, boxPlotTable, boxplotStats, buildAxis, buildDataLabel, buildDataZoom, buildLegend, buildMarkArea, buildMarkLine, buildStackTotalSeries, buildTooltip, bulletTable, candlestickTable, categoryTable, chartFilename, chartFormatters, computeDelta, createTooltipFormatter, describeForecast, downloadCsv, downloadFile, escapeHtml, forecastStart, forecastTagLookup, formatCurrency, formatDate, formatNumber, formatPercent, formatTableCell, formatTooltipValue, formatValue, fromRecords, generateAreaChartDescription, generateBarChartDescription, generateBoxPlotDescription, generateBulletDescription, generateComboChartDescription, generateDataTable, generateDotPlotDescription, generateHistogramDescription, generateLineChartDescription, generatePieChartDescription, generateScatterChartDescription, generateWaterfallDescription, getLegendItems, getReplaceMerge, gridInset, hasForecast, hasPointLabels, heatmapTable, histogramTable, itemLabelLookup, legendCenter, mergeChartOption, nameLabelLookup, niceStep, pairWithCategories, pointLabel, quantile, radarTable, resolveChartHeight, resolveValueFormatter, sankeyTable, scatterTable, seriesLabelLookup, sliceTable, stackTotals, tableToCsv, toPercentStack, toSliceData, treemapTable, trendLine, valueAxisConfig, valueLabelFormatter, waterfallLayout, waterfallTable, withEndLabelInset, withForecastBars, withForecastLines, withForecastPoints, withPointLabels, withReferenceMarks, withZoomInset };
|
package/dist/types/index.d.cts
CHANGED
|
@@ -24,6 +24,15 @@ interface LineSeriesData {
|
|
|
24
24
|
* chart's `stacked` prop for this series.
|
|
25
25
|
*/
|
|
26
26
|
stack?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
29
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
30
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
31
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
32
|
+
*/
|
|
33
|
+
forecastFrom?: number;
|
|
34
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
35
|
+
forecastLabel?: string;
|
|
27
36
|
}
|
|
28
37
|
interface BarChartData {
|
|
29
38
|
/** Category labels */
|
|
@@ -45,6 +54,15 @@ interface BarSeriesData {
|
|
|
45
54
|
* chart's `stacked` prop for this series.
|
|
46
55
|
*/
|
|
47
56
|
stack?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
59
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
60
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
61
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
62
|
+
*/
|
|
63
|
+
forecastFrom?: number;
|
|
64
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
65
|
+
forecastLabel?: string;
|
|
48
66
|
}
|
|
49
67
|
interface PieSliceData {
|
|
50
68
|
/** Slice name (shown in legend/tooltip) */
|
|
@@ -76,6 +94,15 @@ interface AreaSeriesData {
|
|
|
76
94
|
* chart's `stacked` prop for this series.
|
|
77
95
|
*/
|
|
78
96
|
stack?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
99
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
100
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
101
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
102
|
+
*/
|
|
103
|
+
forecastFrom?: number;
|
|
104
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
105
|
+
forecastLabel?: string;
|
|
79
106
|
}
|
|
80
107
|
interface ScatterChartData {
|
|
81
108
|
/** Data series */
|
|
@@ -216,6 +243,15 @@ interface CategorySeriesData {
|
|
|
216
243
|
labels?: (string | null | undefined)[];
|
|
217
244
|
/** Stack group id */
|
|
218
245
|
stack?: string;
|
|
246
|
+
/**
|
|
247
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
248
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
249
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
250
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
251
|
+
*/
|
|
252
|
+
forecastFrom?: number;
|
|
253
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
254
|
+
forecastLabel?: string;
|
|
219
255
|
}
|
|
220
256
|
interface ComboChartData {
|
|
221
257
|
/** Category labels */
|
package/dist/types/index.d.ts
CHANGED
|
@@ -24,6 +24,15 @@ interface LineSeriesData {
|
|
|
24
24
|
* chart's `stacked` prop for this series.
|
|
25
25
|
*/
|
|
26
26
|
stack?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
29
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
30
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
31
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
32
|
+
*/
|
|
33
|
+
forecastFrom?: number;
|
|
34
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
35
|
+
forecastLabel?: string;
|
|
27
36
|
}
|
|
28
37
|
interface BarChartData {
|
|
29
38
|
/** Category labels */
|
|
@@ -45,6 +54,15 @@ interface BarSeriesData {
|
|
|
45
54
|
* chart's `stacked` prop for this series.
|
|
46
55
|
*/
|
|
47
56
|
stack?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
59
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
60
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
61
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
62
|
+
*/
|
|
63
|
+
forecastFrom?: number;
|
|
64
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
65
|
+
forecastLabel?: string;
|
|
48
66
|
}
|
|
49
67
|
interface PieSliceData {
|
|
50
68
|
/** Slice name (shown in legend/tooltip) */
|
|
@@ -76,6 +94,15 @@ interface AreaSeriesData {
|
|
|
76
94
|
* chart's `stacked` prop for this series.
|
|
77
95
|
*/
|
|
78
96
|
stack?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
99
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
100
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
101
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
102
|
+
*/
|
|
103
|
+
forecastFrom?: number;
|
|
104
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
105
|
+
forecastLabel?: string;
|
|
79
106
|
}
|
|
80
107
|
interface ScatterChartData {
|
|
81
108
|
/** Data series */
|
|
@@ -216,6 +243,15 @@ interface CategorySeriesData {
|
|
|
216
243
|
labels?: (string | null | undefined)[];
|
|
217
244
|
/** Stack group id */
|
|
218
245
|
stack?: string;
|
|
246
|
+
/**
|
|
247
|
+
* Index of the first forecast point: from here to the end of the series the
|
|
248
|
+
* values are projections (or a period still in progress). Lines draw that
|
|
249
|
+
* stretch dashed with hollow points, bars draw those bars faded with a
|
|
250
|
+
* dashed outline, and the tooltip tags those values with `forecastLabel`.
|
|
251
|
+
*/
|
|
252
|
+
forecastFrom?: number;
|
|
253
|
+
/** Tooltip tag for forecast values (defaults to 'Forecast') */
|
|
254
|
+
forecastLabel?: string;
|
|
219
255
|
}
|
|
220
256
|
interface ComboChartData {
|
|
221
257
|
/** Category labels */
|