@mui/x-charts 9.3.0 → 9.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/BarChart/BarElement.d.mts +3 -2
- package/BarChart/BarElement.d.ts +3 -2
- package/BarChart/BarLabel/BarLabelItem.d.mts +3 -2
- package/BarChart/BarLabel/BarLabelItem.d.ts +3 -2
- package/BarChart/seriesConfig/bar/extremums.js +7 -2
- package/BarChart/seriesConfig/bar/extremums.mjs +7 -2
- package/CHANGELOG.md +296 -0
- package/ChartsContainer/ChartsContainer.js +21 -0
- package/ChartsContainer/ChartsContainer.mjs +21 -0
- package/ChartsLabel/ChartsLabelMark.js +1 -21
- package/ChartsLabel/ChartsLabelMark.mjs +0 -20
- package/ChartsLegend/chartsLegend.types.d.mts +3 -2
- package/ChartsLegend/chartsLegend.types.d.ts +3 -2
- package/ChartsLegend/piecewiseColorLegendClasses.js +8 -2
- package/ChartsLegend/piecewiseColorLegendClasses.mjs +8 -2
- package/ChartsOverlay/ChartsOverlay.d.mts +5 -4
- package/ChartsOverlay/ChartsOverlay.d.ts +5 -4
- package/ChartsRadialAxisHighlight/index.d.mts +6 -1
- package/ChartsRadialAxisHighlight/index.d.ts +6 -1
- package/ChartsRadialAxisHighlight/index.js +9 -2
- package/ChartsRadialAxisHighlight/index.mjs +8 -1
- package/ChartsRadialDataProvider/ChartsRadialDataProvider.d.mts +1 -1
- package/ChartsRadialDataProvider/ChartsRadialDataProvider.d.ts +1 -1
- package/ChartsRadialDataProvider/ChartsRadialDataProvider.js +1 -1
- package/ChartsRadialDataProvider/ChartsRadialDataProvider.mjs +1 -1
- package/ChartsRadialDataProvider/index.d.mts +5 -0
- package/ChartsRadialDataProvider/index.d.ts +5 -0
- package/ChartsRadialDataProvider/index.js +12 -1
- package/ChartsRadialDataProvider/index.mjs +7 -0
- package/ChartsRadialGrid/index.d.mts +6 -1
- package/ChartsRadialGrid/index.d.ts +6 -1
- package/ChartsRadialGrid/index.js +8 -2
- package/ChartsRadialGrid/index.mjs +8 -1
- package/ChartsRadiusAxis/index.d.mts +6 -1
- package/ChartsRadiusAxis/index.d.ts +6 -1
- package/ChartsRadiusAxis/index.js +10 -2
- package/ChartsRadiusAxis/index.mjs +7 -1
- package/ChartsReferenceLine/ChartsXReferenceLine.js +6 -1
- package/ChartsReferenceLine/ChartsXReferenceLine.mjs +6 -1
- package/ChartsReferenceLine/ChartsYReferenceLine.js +5 -0
- package/ChartsReferenceLine/ChartsYReferenceLine.mjs +5 -0
- package/ChartsRotationAxis/index.d.mts +6 -1
- package/ChartsRotationAxis/index.d.ts +6 -1
- package/ChartsRotationAxis/index.js +10 -2
- package/ChartsRotationAxis/index.mjs +7 -1
- package/ChartsTooltip/ChartTooltip.types.d.mts +3 -2
- package/ChartsTooltip/ChartTooltip.types.d.ts +3 -2
- package/ChartsTooltip/ChartsTooltipContainer.js +11 -4
- package/ChartsTooltip/ChartsTooltipContainer.mjs +11 -4
- package/ChartsTooltip/useAxesTooltip.js +2 -2
- package/ChartsTooltip/useAxesTooltip.mjs +2 -2
- package/ChartsTooltip/useItemTooltip.js +2 -2
- package/ChartsTooltip/useItemTooltip.mjs +2 -2
- package/ChartsXAxis/useAxisTicksProps.d.mts +84 -3
- package/ChartsXAxis/useAxisTicksProps.d.ts +84 -3
- package/ChartsYAxis/useAxisTicksProps.d.mts +84 -3
- package/ChartsYAxis/useAxisTicksProps.d.ts +84 -3
- package/LineChart/AreaElement.d.mts +3 -2
- package/LineChart/AreaElement.d.ts +3 -2
- package/LineChart/AreaElement.js +1 -1
- package/LineChart/AreaElement.mjs +1 -1
- package/LineChart/CircleMarkElement.js +1 -1
- package/LineChart/CircleMarkElement.mjs +1 -1
- package/LineChart/LineElement.d.mts +3 -2
- package/LineChart/LineElement.d.ts +3 -2
- package/LineChart/LineElement.js +1 -1
- package/LineChart/LineElement.mjs +1 -1
- package/LineChart/LineHighlightPlot.d.mts +3 -2
- package/LineChart/LineHighlightPlot.d.ts +3 -2
- package/LineChart/LineHighlightPlot.js +65 -45
- package/LineChart/LineHighlightPlot.mjs +65 -45
- package/LineChart/MarkElement.js +1 -1
- package/LineChart/MarkElement.mjs +1 -1
- package/LineChart/MarkPlot.d.mts +3 -2
- package/LineChart/MarkPlot.d.ts +3 -2
- package/LineChart/seriesConfig/curveEvaluation.js +28 -14
- package/LineChart/seriesConfig/curveEvaluation.mjs +27 -14
- package/LineChart/seriesConfig/extremums.js +5 -1
- package/LineChart/seriesConfig/extremums.mjs +5 -1
- package/LineChart/useMarkPlotData.js +3 -1
- package/LineChart/useMarkPlotData.mjs +3 -1
- package/PieChart/PieArcLabelPlot.d.mts +3 -2
- package/PieChart/PieArcLabelPlot.d.ts +3 -2
- package/PieChart/PieArcPlot.d.mts +3 -2
- package/PieChart/PieArcPlot.d.ts +3 -2
- package/RadarChart/RadarAxis/RadarAxis.utils.d.mts +2 -2
- package/RadarChart/RadarAxis/RadarAxis.utils.d.ts +2 -2
- package/ScatterChart/BatchScatter.d.mts +2 -8
- package/ScatterChart/BatchScatter.d.ts +2 -8
- package/ScatterChart/BatchScatter.js +17 -12
- package/ScatterChart/BatchScatter.mjs +17 -12
- package/ScatterChart/FocusedScatterMark.js +2 -2
- package/ScatterChart/FocusedScatterMark.mjs +2 -2
- package/ScatterChart/HighlightedScatterMark.js +3 -3
- package/ScatterChart/HighlightedScatterMark.mjs +3 -3
- package/ScatterChart/Scatter.d.mts +5 -0
- package/ScatterChart/Scatter.d.ts +5 -0
- package/ScatterChart/Scatter.js +7 -2
- package/ScatterChart/Scatter.mjs +7 -2
- package/ScatterChart/ScatterChart.d.mts +2 -1
- package/ScatterChart/ScatterChart.d.ts +2 -1
- package/ScatterChart/ScatterChart.js +28 -3
- package/ScatterChart/ScatterChart.mjs +28 -3
- package/ScatterChart/ScatterChart.plugins.d.mts +2 -1
- package/ScatterChart/ScatterChart.plugins.d.ts +2 -1
- package/ScatterChart/ScatterChart.plugins.js +2 -1
- package/ScatterChart/ScatterChart.plugins.mjs +2 -1
- package/ScatterChart/ScatterMarker.types.d.mts +3 -2
- package/ScatterChart/ScatterMarker.types.d.ts +3 -2
- package/ScatterChart/ScatterPlot.d.mts +7 -4
- package/ScatterChart/ScatterPlot.d.ts +7 -4
- package/ScatterChart/ScatterPlot.js +31 -4
- package/ScatterChart/ScatterPlot.mjs +31 -4
- package/ScatterChart/async/ScatterAsync.d.mts +9 -0
- package/ScatterChart/async/ScatterAsync.d.ts +9 -0
- package/ScatterChart/async/ScatterAsync.js +71 -0
- package/ScatterChart/async/ScatterAsync.mjs +67 -0
- package/ScatterChart/async/ScatterAsyncBatch.d.mts +24 -0
- package/ScatterChart/async/ScatterAsyncBatch.d.ts +24 -0
- package/ScatterChart/async/ScatterAsyncBatch.js +112 -0
- package/ScatterChart/async/ScatterAsyncBatch.mjs +106 -0
- package/ScatterChart/async/scatterRenderData.selectors.d.mts +38 -0
- package/ScatterChart/async/scatterRenderData.selectors.d.ts +38 -0
- package/ScatterChart/async/scatterRenderData.selectors.js +93 -0
- package/ScatterChart/async/scatterRenderData.selectors.mjs +87 -0
- package/ScatterChart/seriesConfig/extremums.js +6 -0
- package/ScatterChart/seriesConfig/extremums.mjs +6 -0
- package/ScatterChart/seriesConfig/getColor.js +1 -1
- package/ScatterChart/seriesConfig/getColor.mjs +1 -1
- package/ScatterChart/seriesConfig/getMarkerSize.d.mts +18 -0
- package/ScatterChart/seriesConfig/getMarkerSize.d.ts +18 -0
- package/ScatterChart/seriesConfig/getMarkerSize.js +43 -0
- package/ScatterChart/seriesConfig/getMarkerSize.mjs +37 -0
- package/ScatterChart/seriesConfig/seriesProcessor.js +23 -8
- package/ScatterChart/seriesConfig/seriesProcessor.mjs +23 -8
- package/ScatterChart/useScatterItemPosition.d.mts +4 -0
- package/ScatterChart/useScatterItemPosition.d.ts +4 -0
- package/ScatterChart/useScatterItemPosition.js +9 -0
- package/ScatterChart/useScatterItemPosition.mjs +8 -0
- package/SparkLineChart/SparkLineChart.js +2 -1
- package/SparkLineChart/SparkLineChart.mjs +2 -1
- package/Toolbar/Toolbar.types.d.mts +3 -2
- package/Toolbar/Toolbar.types.d.ts +3 -2
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/internals/animation/animation.d.mts +1 -2
- package/internals/animation/animation.d.ts +1 -2
- package/internals/commonNextFocusItem.d.mts +10 -2
- package/internals/commonNextFocusItem.d.ts +10 -2
- package/internals/commonNextFocusItem.js +12 -4
- package/internals/commonNextFocusItem.mjs +12 -4
- package/internals/createCommonKeyboardFocusHandler.d.mts +1 -1
- package/internals/createCommonKeyboardFocusHandler.d.ts +1 -1
- package/internals/createCommonKeyboardFocusHandler.js +3 -3
- package/internals/createCommonKeyboardFocusHandler.mjs +3 -3
- package/internals/getSeriesColorFn.d.mts +5 -5
- package/internals/getSeriesColorFn.d.ts +5 -5
- package/internals/incompleteDatasetKeysError.d.mts +1 -0
- package/internals/incompleteDatasetKeysError.d.ts +1 -0
- package/internals/incompleteDatasetKeysError.js +11 -0
- package/internals/incompleteDatasetKeysError.mjs +4 -0
- package/internals/index.d.mts +3 -0
- package/internals/index.d.ts +3 -0
- package/internals/index.js +36 -0
- package/internals/index.mjs +3 -0
- package/internals/plugins/allPlugins.d.mts +4 -3
- package/internals/plugins/allPlugins.d.ts +4 -3
- package/internals/plugins/allPlugins.js +2 -1
- package/internals/plugins/allPlugins.mjs +2 -1
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.d.mts +12 -3
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.d.ts +12 -3
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.js +10 -1
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.selectors.mjs +10 -1
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.d.mts +15 -1
- package/internals/plugins/corePlugins/useChartExperimentalFeature/useChartExperimentalFeature.types.d.ts +15 -1
- package/internals/plugins/featurePlugins/useChartCartesianAxis/createZoomLookup.js +3 -2
- package/internals/plugins/featurePlugins/useChartCartesianAxis/createZoomLookup.mjs +4 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeAxis.js +2 -2
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeAxis.mjs +3 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.d.mts +10 -1
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.d.ts +10 -1
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.js +18 -1
- package/internals/plugins/featurePlugins/useChartCartesianAxis/defaultizeZoom.mjs +16 -0
- package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisScale.js +27 -2
- package/internals/plugins/featurePlugins/useChartCartesianAxis/getAxisScale.mjs +27 -2
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.js +1 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxis.mjs +1 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.mts +11 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.d.ts +11 -3
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.js +24 -5
- package/internals/plugins/featurePlugins/useChartCartesianAxis/useChartCartesianAxisRendering.selectors.mjs +24 -5
- package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.d.mts +1 -1
- package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.d.ts +1 -1
- package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.js +46 -2
- package/internals/plugins/featurePlugins/useChartClosestPoint/findClosestPoints.mjs +47 -2
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.js +46 -11
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.mjs +46 -11
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.types.d.mts +2 -1
- package/internals/plugins/featurePlugins/useChartClosestPoint/useChartClosestPoint.types.d.ts +2 -1
- package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.js +3 -2
- package/internals/plugins/featurePlugins/useChartHighlight/useChartHighlight.mjs +3 -2
- package/internals/plugins/featurePlugins/useChartPolarAxis/coordinateTransformation.d.mts +4 -0
- package/internals/plugins/featurePlugins/useChartPolarAxis/coordinateTransformation.d.ts +4 -0
- package/internals/plugins/featurePlugins/useChartPolarAxis/coordinateTransformation.js +3 -1
- package/internals/plugins/featurePlugins/useChartPolarAxis/coordinateTransformation.mjs +1 -0
- package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.js +5 -3
- package/internals/plugins/featurePlugins/useChartPolarAxis/useChartPolarAxis.mjs +7 -5
- package/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.js +17 -3
- package/internals/plugins/featurePlugins/useChartZAxis/useChartZAxis.mjs +17 -3
- package/internals/plugins/featurePlugins/useProgressiveRendering/index.d.mts +3 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/index.d.ts +3 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/index.js +27 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/index.mjs +2 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.d.mts +13 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.d.ts +13 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.js +136 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.mjs +128 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.selectors.d.mts +42 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.selectors.d.ts +42 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.selectors.js +166 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.selectors.mjs +159 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.d.mts +34 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.d.ts +34 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.js +5 -0
- package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.mjs +1 -0
- package/internals/scales/scaleBand.js +70 -43
- package/internals/scales/scaleBand.mjs +71 -44
- package/internals/sizeScale.d.mts +6 -0
- package/internals/sizeScale.d.ts +6 -0
- package/internals/sizeScale.js +46 -0
- package/internals/sizeScale.mjs +38 -0
- package/models/axis.d.mts +18 -12
- package/models/axis.d.ts +18 -12
- package/models/chartsSlotsComponentsProps.d.mts +25 -0
- package/models/chartsSlotsComponentsProps.d.ts +25 -0
- package/models/chartsSlotsComponentsProps.js +5 -0
- package/models/chartsSlotsComponentsProps.mjs +1 -0
- package/models/index.d.mts +1 -0
- package/models/index.d.ts +1 -0
- package/models/index.js +11 -0
- package/models/index.mjs +1 -0
- package/models/seriesType/bar.d.mts +1 -1
- package/models/seriesType/bar.d.ts +1 -1
- package/models/seriesType/common.d.mts +4 -4
- package/models/seriesType/common.d.ts +4 -4
- package/models/seriesType/config.d.mts +3 -3
- package/models/seriesType/config.d.ts +3 -3
- package/models/seriesType/line.d.mts +6 -3
- package/models/seriesType/line.d.ts +6 -3
- package/models/seriesType/pie.d.mts +1 -1
- package/models/seriesType/pie.d.ts +1 -1
- package/models/seriesType/radar.d.mts +1 -1
- package/models/seriesType/radar.d.ts +1 -1
- package/models/seriesType/scatter.d.mts +35 -3
- package/models/seriesType/scatter.d.ts +35 -3
- package/models/sizeMapping.d.mts +64 -0
- package/models/sizeMapping.d.ts +64 -0
- package/models/sizeMapping.js +5 -0
- package/models/sizeMapping.mjs +1 -0
- package/models/slots/chartsBaseSlots.d.mts +6 -5
- package/models/slots/chartsBaseSlots.d.ts +6 -5
- package/models/z-axis.d.mts +10 -1
- package/models/z-axis.d.ts +10 -1
- package/package.json +5 -5
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sameSeriesIds = sameSeriesIds;
|
|
7
|
+
exports.selectorShouldUseProgressiveRenderer = exports.selectorProgressiveTotalRounds = exports.selectorProgressiveSeriesRevealedBatches = exports.selectorProgressiveRevealedRounds = exports.selectorProgressivePlans = exports.selectorProgressiveBatchSize = exports.selectorProgressiveAggregate = void 0;
|
|
8
|
+
var _store = require("@mui/x-internals/store");
|
|
9
|
+
var _useChartSeries = require("../../corePlugins/useChartSeries");
|
|
10
|
+
var _useChartExperimentalFeature = require("../../corePlugins/useChartExperimentalFeature");
|
|
11
|
+
/**
|
|
12
|
+
* Total point count above which the auto (`renderer` unset) mode switches to
|
|
13
|
+
* the progressive renderer. Below it the synchronous renderer is used, since
|
|
14
|
+
* the progressive paint's overhead is not worth it for small datasets.
|
|
15
|
+
*/
|
|
16
|
+
const PROGRESSIVE_POINT_THRESHOLD = 20000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Target number of reveal commits. Each commit repaints every already-painted
|
|
20
|
+
* circle, so the total progressive wall time is roughly `(C + 1) / 2` times a
|
|
21
|
+
* single synchronous render (where `C` is the number of commits). Targeting
|
|
22
|
+
* `5` commits keeps the progressive paint at roughly 2–3× the sync render time.
|
|
23
|
+
*/
|
|
24
|
+
const TARGET_PROGRESSIVE_COMMITS = 5;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Lower bound for the per-tick reveal budget (total points across every
|
|
28
|
+
* series). Prevents tiny commits whose React overhead would dominate.
|
|
29
|
+
*/
|
|
30
|
+
const MIN_BATCH_TOTAL = 1000;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Upper bound for the per-tick reveal budget (total points across every
|
|
34
|
+
* series). Prevents a single commit from blocking the main thread for too
|
|
35
|
+
* long; very large datasets simply use more commits.
|
|
36
|
+
*/
|
|
37
|
+
const MAX_BATCH_TOTAL = 10000;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Per-series points revealed per tick, derived from the total point count
|
|
41
|
+
* across visible series and the number of visible series. The total per-tick
|
|
42
|
+
* budget aims for {@link TARGET_PROGRESSIVE_COMMITS} commits, clamped by
|
|
43
|
+
* {@link MIN_BATCH_TOTAL} / {@link MAX_BATCH_TOTAL}, then split evenly across
|
|
44
|
+
* the visible series so every series progresses together.
|
|
45
|
+
*/
|
|
46
|
+
const getEffectiveBatchSize = (nSeries, totalPoints) => {
|
|
47
|
+
const safeSeries = Math.max(1, nSeries);
|
|
48
|
+
const safePoints = Math.max(1, totalPoints);
|
|
49
|
+
const totalPerTick = Math.min(MAX_BATCH_TOTAL, Math.max(MIN_BATCH_TOTAL, Math.ceil(safePoints / TARGET_PROGRESSIVE_COMMITS)));
|
|
50
|
+
return Math.max(1, Math.floor(totalPerTick / safeSeries));
|
|
51
|
+
};
|
|
52
|
+
const selectorProgressiveState = state => state.progressiveRendering;
|
|
53
|
+
|
|
54
|
+
/** Map of registered plots → their set of series ids. */
|
|
55
|
+
const selectorProgressivePlans = exports.selectorProgressivePlans = (0, _store.createSelector)(selectorProgressiveState, s => s?.plans);
|
|
56
|
+
|
|
57
|
+
/** Total number of rounds revealed across all plots so far. */
|
|
58
|
+
const selectorProgressiveRevealedRounds = exports.selectorProgressiveRevealedRounds = (0, _store.createSelector)(selectorProgressiveState, s => s?.revealedRounds ?? 0);
|
|
59
|
+
|
|
60
|
+
/** Point count of a series, looked up across every processed series type. */
|
|
61
|
+
function getSeriesPointCount(processedSeries, seriesId) {
|
|
62
|
+
for (const type in processedSeries) {
|
|
63
|
+
if (!Object.hasOwn(processedSeries, type)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const item = processedSeries[type]?.series[seriesId];
|
|
67
|
+
if (item) {
|
|
68
|
+
return Array.isArray(item.data) ? item.data.length : 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Aggregated view of every registered plan: the per-series batch counts, the
|
|
76
|
+
* total number of rounds, and the per-series batch size (so every consumer
|
|
77
|
+
* sizes its batches the same way). Point counts are read straight from the
|
|
78
|
+
* processed series rather than carried by the registration.
|
|
79
|
+
*/
|
|
80
|
+
const selectorProgressiveAggregate = exports.selectorProgressiveAggregate = (0, _store.createSelectorMemoized)(selectorProgressivePlans, _useChartSeries.selectorChartSeriesProcessed, function selectorProgressiveAggregate(plans, processedSeries) {
|
|
81
|
+
const nBatchesBySeries = new Map();
|
|
82
|
+
if (!plans || plans.size === 0) {
|
|
83
|
+
return {
|
|
84
|
+
nBatchesBySeries,
|
|
85
|
+
totalRounds: 0,
|
|
86
|
+
batchSize: MIN_BATCH_TOTAL
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
let nSeries = 0;
|
|
90
|
+
let totalPoints = 0;
|
|
91
|
+
const pointCounts = new Map();
|
|
92
|
+
plans.forEach(seriesIds => {
|
|
93
|
+
seriesIds.forEach(seriesId => {
|
|
94
|
+
const nPoints = getSeriesPointCount(processedSeries, seriesId);
|
|
95
|
+
pointCounts.set(seriesId, nPoints);
|
|
96
|
+
nSeries += 1;
|
|
97
|
+
totalPoints += nPoints;
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
const batchSize = getEffectiveBatchSize(nSeries, totalPoints);
|
|
101
|
+
let totalRounds = 0;
|
|
102
|
+
pointCounts.forEach((nPoints, seriesId) => {
|
|
103
|
+
const n = Math.max(1, Math.ceil(nPoints / batchSize));
|
|
104
|
+
nBatchesBySeries.set(seriesId, n);
|
|
105
|
+
if (n > totalRounds) {
|
|
106
|
+
totalRounds = n;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
nBatchesBySeries,
|
|
111
|
+
totalRounds,
|
|
112
|
+
batchSize
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
const selectorProgressiveBatchSize = exports.selectorProgressiveBatchSize = (0, _store.createSelector)(selectorProgressiveAggregate, a => a.batchSize);
|
|
116
|
+
const selectorProgressiveTotalRounds = exports.selectorProgressiveTotalRounds = (0, _store.createSelector)(selectorProgressiveAggregate, a => a.totalRounds);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* How many of `seriesId`'s own batches are revealed so far. Capped at that
|
|
120
|
+
* series' total batch count, so series with fewer batches simply stop
|
|
121
|
+
* progressing while longer ones keep filling in.
|
|
122
|
+
*/
|
|
123
|
+
const selectorProgressiveSeriesRevealedBatches = exports.selectorProgressiveSeriesRevealedBatches = (0, _store.createSelector)(selectorProgressiveAggregate, selectorProgressiveRevealedRounds, function selectorProgressiveSeriesRevealedBatches(agg, revealed, seriesId) {
|
|
124
|
+
return Math.min(revealed, agg.nBatchesBySeries.get(seriesId) ?? 0);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Whether `seriesIds` should be rendered progressively given the requested
|
|
129
|
+
* `renderer`:
|
|
130
|
+
* - `svg-single` / `svg-batch`: never (those are non-progressive renderers).
|
|
131
|
+
* - `svg-progressive`: always.
|
|
132
|
+
* - unset (auto): only when the `progressiveRendering` experimental feature is
|
|
133
|
+
* enabled and the total point count is above
|
|
134
|
+
* {@link PROGRESSIVE_POINT_THRESHOLD}. The flag keeps the auto behavior
|
|
135
|
+
* opt-in so the default (`svg-single`) stays non-breaking.
|
|
136
|
+
*/
|
|
137
|
+
const selectorProgressiveRenderingEnabled = state => (0, _useChartExperimentalFeature.selectorChartExperimentalFeaturesState)(state, 'progressiveRendering');
|
|
138
|
+
const selectorShouldUseProgressiveRenderer = exports.selectorShouldUseProgressiveRenderer = (0, _store.createSelector)(_useChartSeries.selectorChartSeriesProcessed, selectorProgressiveRenderingEnabled, (processedSeries, progressiveRenderingEnabled, seriesIds, renderer) => {
|
|
139
|
+
if (renderer === 'svg-single' || renderer === 'svg-batch') {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (renderer === 'svg-progressive') {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
if (!progressiveRenderingEnabled) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
let totalPoints = 0;
|
|
149
|
+
for (const seriesId of seriesIds) {
|
|
150
|
+
totalPoints += getSeriesPointCount(processedSeries, seriesId);
|
|
151
|
+
}
|
|
152
|
+
return totalPoints > PROGRESSIVE_POINT_THRESHOLD;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
/** Order-sensitive equality between two registered series-id sets. */
|
|
156
|
+
function sameSeriesIds(a, b) {
|
|
157
|
+
if (!a || a.length !== b.length) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
161
|
+
if (a[i] !== b[i]) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { createSelector, createSelectorMemoized } from '@mui/x-internals/store';
|
|
2
|
+
import { selectorChartSeriesProcessed } from "../../corePlugins/useChartSeries/index.mjs";
|
|
3
|
+
import { selectorChartExperimentalFeaturesState } from "../../corePlugins/useChartExperimentalFeature/index.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Total point count above which the auto (`renderer` unset) mode switches to
|
|
6
|
+
* the progressive renderer. Below it the synchronous renderer is used, since
|
|
7
|
+
* the progressive paint's overhead is not worth it for small datasets.
|
|
8
|
+
*/
|
|
9
|
+
const PROGRESSIVE_POINT_THRESHOLD = 20000;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Target number of reveal commits. Each commit repaints every already-painted
|
|
13
|
+
* circle, so the total progressive wall time is roughly `(C + 1) / 2` times a
|
|
14
|
+
* single synchronous render (where `C` is the number of commits). Targeting
|
|
15
|
+
* `5` commits keeps the progressive paint at roughly 2–3× the sync render time.
|
|
16
|
+
*/
|
|
17
|
+
const TARGET_PROGRESSIVE_COMMITS = 5;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Lower bound for the per-tick reveal budget (total points across every
|
|
21
|
+
* series). Prevents tiny commits whose React overhead would dominate.
|
|
22
|
+
*/
|
|
23
|
+
const MIN_BATCH_TOTAL = 1000;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Upper bound for the per-tick reveal budget (total points across every
|
|
27
|
+
* series). Prevents a single commit from blocking the main thread for too
|
|
28
|
+
* long; very large datasets simply use more commits.
|
|
29
|
+
*/
|
|
30
|
+
const MAX_BATCH_TOTAL = 10000;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Per-series points revealed per tick, derived from the total point count
|
|
34
|
+
* across visible series and the number of visible series. The total per-tick
|
|
35
|
+
* budget aims for {@link TARGET_PROGRESSIVE_COMMITS} commits, clamped by
|
|
36
|
+
* {@link MIN_BATCH_TOTAL} / {@link MAX_BATCH_TOTAL}, then split evenly across
|
|
37
|
+
* the visible series so every series progresses together.
|
|
38
|
+
*/
|
|
39
|
+
const getEffectiveBatchSize = (nSeries, totalPoints) => {
|
|
40
|
+
const safeSeries = Math.max(1, nSeries);
|
|
41
|
+
const safePoints = Math.max(1, totalPoints);
|
|
42
|
+
const totalPerTick = Math.min(MAX_BATCH_TOTAL, Math.max(MIN_BATCH_TOTAL, Math.ceil(safePoints / TARGET_PROGRESSIVE_COMMITS)));
|
|
43
|
+
return Math.max(1, Math.floor(totalPerTick / safeSeries));
|
|
44
|
+
};
|
|
45
|
+
const selectorProgressiveState = state => state.progressiveRendering;
|
|
46
|
+
|
|
47
|
+
/** Map of registered plots → their set of series ids. */
|
|
48
|
+
export const selectorProgressivePlans = createSelector(selectorProgressiveState, s => s?.plans);
|
|
49
|
+
|
|
50
|
+
/** Total number of rounds revealed across all plots so far. */
|
|
51
|
+
export const selectorProgressiveRevealedRounds = createSelector(selectorProgressiveState, s => s?.revealedRounds ?? 0);
|
|
52
|
+
|
|
53
|
+
/** Point count of a series, looked up across every processed series type. */
|
|
54
|
+
function getSeriesPointCount(processedSeries, seriesId) {
|
|
55
|
+
for (const type in processedSeries) {
|
|
56
|
+
if (!Object.hasOwn(processedSeries, type)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const item = processedSeries[type]?.series[seriesId];
|
|
60
|
+
if (item) {
|
|
61
|
+
return Array.isArray(item.data) ? item.data.length : 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Aggregated view of every registered plan: the per-series batch counts, the
|
|
69
|
+
* total number of rounds, and the per-series batch size (so every consumer
|
|
70
|
+
* sizes its batches the same way). Point counts are read straight from the
|
|
71
|
+
* processed series rather than carried by the registration.
|
|
72
|
+
*/
|
|
73
|
+
export const selectorProgressiveAggregate = createSelectorMemoized(selectorProgressivePlans, selectorChartSeriesProcessed, function selectorProgressiveAggregate(plans, processedSeries) {
|
|
74
|
+
const nBatchesBySeries = new Map();
|
|
75
|
+
if (!plans || plans.size === 0) {
|
|
76
|
+
return {
|
|
77
|
+
nBatchesBySeries,
|
|
78
|
+
totalRounds: 0,
|
|
79
|
+
batchSize: MIN_BATCH_TOTAL
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
let nSeries = 0;
|
|
83
|
+
let totalPoints = 0;
|
|
84
|
+
const pointCounts = new Map();
|
|
85
|
+
plans.forEach(seriesIds => {
|
|
86
|
+
seriesIds.forEach(seriesId => {
|
|
87
|
+
const nPoints = getSeriesPointCount(processedSeries, seriesId);
|
|
88
|
+
pointCounts.set(seriesId, nPoints);
|
|
89
|
+
nSeries += 1;
|
|
90
|
+
totalPoints += nPoints;
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
const batchSize = getEffectiveBatchSize(nSeries, totalPoints);
|
|
94
|
+
let totalRounds = 0;
|
|
95
|
+
pointCounts.forEach((nPoints, seriesId) => {
|
|
96
|
+
const n = Math.max(1, Math.ceil(nPoints / batchSize));
|
|
97
|
+
nBatchesBySeries.set(seriesId, n);
|
|
98
|
+
if (n > totalRounds) {
|
|
99
|
+
totalRounds = n;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
nBatchesBySeries,
|
|
104
|
+
totalRounds,
|
|
105
|
+
batchSize
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
export const selectorProgressiveBatchSize = createSelector(selectorProgressiveAggregate, a => a.batchSize);
|
|
109
|
+
export const selectorProgressiveTotalRounds = createSelector(selectorProgressiveAggregate, a => a.totalRounds);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* How many of `seriesId`'s own batches are revealed so far. Capped at that
|
|
113
|
+
* series' total batch count, so series with fewer batches simply stop
|
|
114
|
+
* progressing while longer ones keep filling in.
|
|
115
|
+
*/
|
|
116
|
+
export const selectorProgressiveSeriesRevealedBatches = createSelector(selectorProgressiveAggregate, selectorProgressiveRevealedRounds, function selectorProgressiveSeriesRevealedBatches(agg, revealed, seriesId) {
|
|
117
|
+
return Math.min(revealed, agg.nBatchesBySeries.get(seriesId) ?? 0);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Whether `seriesIds` should be rendered progressively given the requested
|
|
122
|
+
* `renderer`:
|
|
123
|
+
* - `svg-single` / `svg-batch`: never (those are non-progressive renderers).
|
|
124
|
+
* - `svg-progressive`: always.
|
|
125
|
+
* - unset (auto): only when the `progressiveRendering` experimental feature is
|
|
126
|
+
* enabled and the total point count is above
|
|
127
|
+
* {@link PROGRESSIVE_POINT_THRESHOLD}. The flag keeps the auto behavior
|
|
128
|
+
* opt-in so the default (`svg-single`) stays non-breaking.
|
|
129
|
+
*/
|
|
130
|
+
const selectorProgressiveRenderingEnabled = state => selectorChartExperimentalFeaturesState(state, 'progressiveRendering');
|
|
131
|
+
export const selectorShouldUseProgressiveRenderer = createSelector(selectorChartSeriesProcessed, selectorProgressiveRenderingEnabled, (processedSeries, progressiveRenderingEnabled, seriesIds, renderer) => {
|
|
132
|
+
if (renderer === 'svg-single' || renderer === 'svg-batch') {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (renderer === 'svg-progressive') {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
if (!progressiveRenderingEnabled) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
let totalPoints = 0;
|
|
142
|
+
for (const seriesId of seriesIds) {
|
|
143
|
+
totalPoints += getSeriesPointCount(processedSeries, seriesId);
|
|
144
|
+
}
|
|
145
|
+
return totalPoints > PROGRESSIVE_POINT_THRESHOLD;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/** Order-sensitive equality between two registered series-id sets. */
|
|
149
|
+
export function sameSeriesIds(a, b) {
|
|
150
|
+
if (!a || a.length !== b.length) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
154
|
+
if (a[i] !== b[i]) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.d.mts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type SeriesId } from "../../../../models/seriesType/common.mjs";
|
|
2
|
+
import type { RendererType } from "../../../../ScatterChart/index.mjs";
|
|
3
|
+
import { type ChartPluginSignature } from "../../models/index.mjs";
|
|
4
|
+
export interface UseProgressiveRenderingState {
|
|
5
|
+
progressiveRendering: {
|
|
6
|
+
/**
|
|
7
|
+
* Per-plot sets of series ids that should be progressively revealed, keyed
|
|
8
|
+
* by an opaque plot id. Each plot (e.g. a separate `ScatterPlot` composed
|
|
9
|
+
* into the same chart) registers its own set. The scheduler aggregates
|
|
10
|
+
* them and reads point counts straight from the processed series.
|
|
11
|
+
*/
|
|
12
|
+
plans: ReadonlyMap<string, readonly SeriesId[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Number of *rounds* revealed so far. A round adds one batch in every
|
|
15
|
+
* registered series simultaneously, so every series progresses together.
|
|
16
|
+
*/
|
|
17
|
+
revealedRounds: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface UseProgressiveRenderingInstance {
|
|
21
|
+
/**
|
|
22
|
+
* Register the set of series ids that `plotId` wants progressively revealed,
|
|
23
|
+
* and return a cleanup function that unregisters them. Designed to be called
|
|
24
|
+
* from a `React.useEffect`: returning the unregister function makes the
|
|
25
|
+
* effect's cleanup tear the registration down on unmount or before the next
|
|
26
|
+
* call. Re-calling with the same `plotId` replaces the previous set; a no-op
|
|
27
|
+
* when the set is unchanged.
|
|
28
|
+
*/
|
|
29
|
+
registerProgressivePlan(plotId: string, seriesIds: readonly SeriesId[], renderer: RendererType | 'svg-progressive' | undefined): (() => void) | undefined;
|
|
30
|
+
}
|
|
31
|
+
export type UseProgressiveRenderingSignature = ChartPluginSignature<{
|
|
32
|
+
state: UseProgressiveRenderingState;
|
|
33
|
+
instance: UseProgressiveRenderingInstance;
|
|
34
|
+
}>;
|
package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type SeriesId } from "../../../../models/seriesType/common.js";
|
|
2
|
+
import type { RendererType } from "../../../../ScatterChart/index.js";
|
|
3
|
+
import { type ChartPluginSignature } from "../../models/index.js";
|
|
4
|
+
export interface UseProgressiveRenderingState {
|
|
5
|
+
progressiveRendering: {
|
|
6
|
+
/**
|
|
7
|
+
* Per-plot sets of series ids that should be progressively revealed, keyed
|
|
8
|
+
* by an opaque plot id. Each plot (e.g. a separate `ScatterPlot` composed
|
|
9
|
+
* into the same chart) registers its own set. The scheduler aggregates
|
|
10
|
+
* them and reads point counts straight from the processed series.
|
|
11
|
+
*/
|
|
12
|
+
plans: ReadonlyMap<string, readonly SeriesId[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Number of *rounds* revealed so far. A round adds one batch in every
|
|
15
|
+
* registered series simultaneously, so every series progresses together.
|
|
16
|
+
*/
|
|
17
|
+
revealedRounds: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface UseProgressiveRenderingInstance {
|
|
21
|
+
/**
|
|
22
|
+
* Register the set of series ids that `plotId` wants progressively revealed,
|
|
23
|
+
* and return a cleanup function that unregisters them. Designed to be called
|
|
24
|
+
* from a `React.useEffect`: returning the unregister function makes the
|
|
25
|
+
* effect's cleanup tear the registration down on unmount or before the next
|
|
26
|
+
* call. Re-calling with the same `plotId` replaces the previous set; a no-op
|
|
27
|
+
* when the set is unchanged.
|
|
28
|
+
*/
|
|
29
|
+
registerProgressivePlan(plotId: string, seriesIds: readonly SeriesId[], renderer: RendererType | 'svg-progressive' | undefined): (() => void) | undefined;
|
|
30
|
+
}
|
|
31
|
+
export type UseProgressiveRenderingSignature = ChartPluginSignature<{
|
|
32
|
+
state: UseProgressiveRenderingState;
|
|
33
|
+
instance: UseProgressiveRenderingInstance;
|
|
34
|
+
}>;
|
package/internals/plugins/featurePlugins/useProgressiveRendering/useProgressiveRendering.types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -21,60 +21,57 @@ function keyof(value) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* The generic corresponds to the data type of domain elements.
|
|
29
|
-
*
|
|
30
|
-
* @param range A two-element array of numeric values.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Constructs a new band scale with the specified domain and range, no padding, no rounding and center alignment.
|
|
35
|
-
*
|
|
36
|
-
* The generic corresponds to the data type of domain elements.
|
|
37
|
-
*
|
|
38
|
-
* @param domain Array of domain values.
|
|
39
|
-
* @param range A two-element array of numeric values.
|
|
24
|
+
* The internal state shared when copying a scale. The domain index (`InternMap`) is the expensive
|
|
25
|
+
* part to build — `O(domain)` — and is immutable once set (the domain setter replaces it rather than
|
|
26
|
+
* mutating it), so a copy can share the same reference instead of rebuilding it. This makes `copy()`
|
|
27
|
+
* `O(1)`, which matters because zooming copies the scale on every frame to apply a new range.
|
|
40
28
|
*/
|
|
41
29
|
|
|
42
|
-
function
|
|
30
|
+
function createScaleBand(seed) {
|
|
43
31
|
// @ts-expect-error, InternMap accepts two arguments, but its types are set as Map, which doesn't.
|
|
44
|
-
let index = new _d3Array.InternMap(undefined, keyof);
|
|
45
|
-
let domain = [];
|
|
46
|
-
let
|
|
47
|
-
let
|
|
48
|
-
let
|
|
32
|
+
let index = seed ? seed.index : new _d3Array.InternMap(undefined, keyof);
|
|
33
|
+
let domain = seed ? seed.domain : [];
|
|
34
|
+
let r0 = seed ? seed.r0 : 0;
|
|
35
|
+
let r1 = seed ? seed.r1 : 1;
|
|
36
|
+
let isRound = seed ? seed.isRound : false;
|
|
37
|
+
let paddingInner = seed ? seed.paddingInner : 0;
|
|
38
|
+
let paddingOuter = seed ? seed.paddingOuter : 0;
|
|
39
|
+
let align = seed ? seed.align : 0.5;
|
|
40
|
+
|
|
41
|
+
// Derived on every rescale. Positions are affine in the index, so they are computed on demand in
|
|
42
|
+
// `scale()` rather than materialized into an array — keeping rescale `O(1)` instead of `O(domain)`.
|
|
49
43
|
let step;
|
|
50
44
|
let bandwidth;
|
|
51
|
-
let
|
|
52
|
-
let
|
|
53
|
-
let paddingOuter = 0;
|
|
54
|
-
let align = 0.5;
|
|
45
|
+
let reverse = false;
|
|
46
|
+
let start = 0;
|
|
55
47
|
const scale = d => {
|
|
56
48
|
const i = index.get(d);
|
|
57
49
|
if (i === undefined) {
|
|
58
50
|
return undefined;
|
|
59
51
|
}
|
|
60
|
-
|
|
52
|
+
const n = domain.length;
|
|
53
|
+
if (n === 0) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const k = reverse ? n - 1 - i % n : i % n;
|
|
57
|
+
return start + step * k;
|
|
61
58
|
};
|
|
62
59
|
const rescale = () => {
|
|
63
60
|
const n = domain.length;
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
step = (
|
|
61
|
+
reverse = r1 < r0;
|
|
62
|
+
const lo = reverse ? r1 : r0;
|
|
63
|
+
const hi = reverse ? r0 : r1;
|
|
64
|
+
step = (hi - lo) / Math.max(1, n - paddingInner + paddingOuter * 2);
|
|
68
65
|
if (isRound) {
|
|
69
66
|
step = Math.floor(step);
|
|
70
67
|
}
|
|
71
|
-
|
|
68
|
+
let adjustedStart = lo + (hi - lo - step * (n - paddingInner)) * align;
|
|
72
69
|
bandwidth = step * (1 - paddingInner);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
if (isRound) {
|
|
71
|
+
adjustedStart = Math.round(adjustedStart);
|
|
72
|
+
bandwidth = Math.round(bandwidth);
|
|
73
|
+
}
|
|
74
|
+
start = adjustedStart;
|
|
78
75
|
return scale;
|
|
79
76
|
};
|
|
80
77
|
scale.domain = function (_) {
|
|
@@ -149,19 +146,49 @@ function scaleBand(...args) {
|
|
|
149
146
|
align = Math.max(0, Math.min(1, _));
|
|
150
147
|
return rescale();
|
|
151
148
|
};
|
|
152
|
-
scale.copy = () => {
|
|
153
|
-
return scaleBand(domain, [r0, r1]).round(isRound).paddingInner(paddingInner).paddingOuter(paddingOuter).align(align);
|
|
154
|
-
};
|
|
155
149
|
|
|
156
|
-
//
|
|
150
|
+
// Shares the immutable domain index with the copy, so copying does not rebuild it.
|
|
151
|
+
scale.copy = () => createScaleBand({
|
|
152
|
+
index,
|
|
153
|
+
domain,
|
|
154
|
+
r0,
|
|
155
|
+
r1,
|
|
156
|
+
isRound,
|
|
157
|
+
paddingInner,
|
|
158
|
+
paddingOuter,
|
|
159
|
+
align
|
|
160
|
+
});
|
|
161
|
+
rescale();
|
|
162
|
+
return scale;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Constructs a new band scale with the specified range, no padding, no rounding and center alignment.
|
|
167
|
+
* The domain defaults to the empty domain.
|
|
168
|
+
* If range is not specified, it defaults to the unit range [0, 1].
|
|
169
|
+
*
|
|
170
|
+
* The generic corresponds to the data type of domain elements.
|
|
171
|
+
*
|
|
172
|
+
* @param range A two-element array of numeric values.
|
|
173
|
+
*/
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Constructs a new band scale with the specified domain and range, no padding, no rounding and center alignment.
|
|
177
|
+
*
|
|
178
|
+
* The generic corresponds to the data type of domain elements.
|
|
179
|
+
*
|
|
180
|
+
* @param domain Array of domain values.
|
|
181
|
+
* @param range A two-element array of numeric values.
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
function scaleBand(...args) {
|
|
185
|
+
const scale = createScaleBand();
|
|
157
186
|
const [arg0, arg1] = args;
|
|
158
187
|
if (args.length > 1) {
|
|
159
188
|
scale.domain(arg0);
|
|
160
189
|
scale.range(arg1);
|
|
161
190
|
} else if (arg0) {
|
|
162
191
|
scale.range(arg0);
|
|
163
|
-
} else {
|
|
164
|
-
rescale();
|
|
165
192
|
}
|
|
166
193
|
return scale;
|
|
167
194
|
}
|