@mui/x-charts
Version:
The community edition of MUI X Charts components.
94 lines (93 loc) • 3.46 kB
JavaScript
import { createSelector } from '@mui/x-internals/store';
import { selectorChartXAxis, selectorChartYAxis } from "./useChartCartesianAxisRendering.selectors.mjs";
import { selectorChartSeriesProcessed } from "../../corePlugins/useChartSeries/index.mjs";
import { getBandSize } from "../../../getBandSize.mjs";
import { isBandScale } from "../../../scaleGuards.mjs";
import { getDataIndexForOrdinalScaleValue } from "../../../invertScale.mjs";
export function getBandIndex(bandAxis, stackConfig, coordinate) {
if (!isBandScale(bandAxis.scale)) {
return -1;
}
const dataIndex = getDataIndexForOrdinalScaleValue(bandAxis.scale, coordinate);
const {
barWidth,
offset
} = getBandSize(bandAxis.scale.bandwidth(), stackConfig.groupNumber, bandAxis.barGapRatio);
const barOffset = stackConfig.groupIndex * (barWidth + offset);
const bandValue = bandAxis.data?.[dataIndex];
if (bandValue == null) {
return -1;
}
const bandStart = bandAxis.scale(bandValue);
if (bandStart == null) {
return -1;
}
const bandBarStart = bandStart + barOffset;
const bandBarEnd = bandBarStart + barWidth;
const bandBarMin = Math.min(bandBarStart, bandBarEnd);
const bandBarMax = Math.max(bandBarStart, bandBarEnd);
if (coordinate >= bandBarMin && coordinate <= bandBarMax) {
return dataIndex;
}
return -1;
}
export const selectorBarItemAtPosition = createSelector(selectorChartXAxis, selectorChartYAxis, selectorChartSeriesProcessed, function selectorBarItemAtPosition({
axis: xAxes,
axisIds: xAxisIds
}, {
axis: yAxes,
axisIds: yAxisIds
}, processedSeries, svgPoint) {
const {
series,
stackingGroups = []
} = processedSeries?.bar ?? {};
const defaultXAxisId = xAxisIds[0];
const defaultYAxisId = yAxisIds[0];
let item = undefined;
for (let stackIndex = 0; stackIndex < stackingGroups.length; stackIndex += 1) {
const group = stackingGroups[stackIndex];
const seriesIds = group.ids;
for (const seriesId of seriesIds) {
const aSeries = (series ?? {})[seriesId];
const xAxisId = aSeries.xAxisId ?? defaultXAxisId;
const yAxisId = aSeries.yAxisId ?? defaultYAxisId;
const xAxis = xAxes[xAxisId];
const yAxis = yAxes[yAxisId];
const bandAxis = aSeries.layout === 'horizontal' ? yAxis : xAxis;
const continuousAxis = aSeries.layout === 'horizontal' ? xAxis : yAxis;
const svgBandCoordinate = aSeries.layout === 'horizontal' ? svgPoint.y : svgPoint.x;
const svgValueCoordinate = aSeries.layout === 'horizontal' ? svgPoint.x : svgPoint.y;
const dataIndex = getBandIndex(bandAxis, {
groupNumber: stackingGroups.length,
groupIndex: stackIndex
}, svgBandCoordinate);
if (dataIndex === -1) {
continue;
}
// The point is inside the band for this series
const bar = aSeries.visibleStackedData[dataIndex];
const start = continuousAxis.scale(bar[0]);
const end = continuousAxis.scale(bar[1]);
if (start == null || end == null) {
continue;
}
const continuousMin = Math.min(start, end);
const continuousMax = Math.max(start, end);
if (svgValueCoordinate >= continuousMin && svgValueCoordinate <= continuousMax) {
item = {
seriesId,
dataIndex
};
}
}
}
if (item) {
return {
type: 'bar',
seriesId: item.seriesId,
dataIndex: item.dataIndex
};
}
return undefined;
});