diff --git a/packages/x-charts/package.json b/packages/x-charts/package.json index c87bd66a53e91..d03e5ef8e5c5b 100644 --- a/packages/x-charts/package.json +++ b/packages/x-charts/package.json @@ -45,12 +45,14 @@ "@mui/utils": "^5.15.14", "@react-spring/rafz": "^9.7.3", "@react-spring/web": "^9.7.3", + "@types/d3-time": "^3.0.3", "clsx": "^2.1.1", "d3-color": "^3.1.0", "d3-delaunay": "^6.0.4", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", "prop-types": "^15.8.1" }, "peerDependencies": { diff --git a/packages/x-charts/src/BarChart/BarPlot.tsx b/packages/x-charts/src/BarChart/BarPlot.tsx index 7ff1e8999a573..0d94922fed3ca 100644 --- a/packages/x-charts/src/BarChart/BarPlot.tsx +++ b/packages/x-charts/src/BarChart/BarPlot.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { useTransition } from '@react-spring/web'; +import { scaleBand } from 'd3-scale'; +import { timeDay } from 'd3-time'; import { CartesianContext } from '../context/CartesianContextProvider'; import { BarElement, BarElementSlotProps, BarElementSlots } from './BarElement'; import { AxisDefaultized } from '../models/axis'; @@ -12,7 +14,6 @@ import { AnimationData, CompletedBarData, MaskData } from './types'; import { BarClipPath } from './BarClipPath'; import { BarLabelItemProps, BarLabelSlotProps, BarLabelSlots } from './BarLabel/BarLabelItem'; import { BarLabelPlot } from './BarLabel/BarLabelPlot'; -import { checkScaleErrors } from './checkScaleErrors'; import { useBarSeries } from '../hooks/useSeries'; /** @@ -109,24 +110,33 @@ const useAggregatedData = (): { const verticalLayout = series[seriesId].layout === 'vertical'; - checkScaleErrors(verticalLayout, seriesId, xAxisKey, xAxis, yAxisKey, yAxis); + // checkScaleErrors(verticalLayout, seriesId, xAxisKey, xAxis, yAxisKey, yAxis); - const baseScaleConfig = ( - verticalLayout ? xAxisConfig : yAxisConfig - ) as AxisDefaultized<'band'>; + const baseScaleConfig = verticalLayout ? xAxisConfig : yAxisConfig; const xScale = xAxisConfig.scale; const yScale = yAxisConfig.scale; const colorGetter = getColor(series[seriesId], xAxis[xAxisKey], yAxis[yAxisKey]); - const bandWidth = baseScaleConfig.scale.bandwidth(); + const bandWidth = + ((baseScaleConfig as AxisDefaultized<'band'>).scale?.bandwidth?.() || + scaleBand( + // @ts-expect-error, domain can be fed into range. + timeDay.range(...baseScaleConfig.scale.domain()), + baseScaleConfig?.scale?.range(), + ).bandwidth()) - 1; + + const numberOfGroups = stackingGroups.length; const { barWidth, offset } = getBandSize({ bandWidth, - numberOfGroups: stackingGroups.length, - gapRatio: baseScaleConfig.barGapRatio, + numberOfGroups, + gapRatio: + baseScaleConfig.scaleType === 'time' || baseScaleConfig.scaleType === 'utc' + ? 0 + : (baseScaleConfig as AxisDefaultized<'band'>).barGapRatio ?? 0.1, }); - const barOffset = groupIndex * (barWidth + offset); + const barOffset = groupIndex * (barWidth + 1); const { stackedData } = series[seriesId]; @@ -137,21 +147,25 @@ const useAggregatedData = (): { const maxValueCoord = Math.round(Math.max(...valueCoordinates)); const stackId = series[seriesId].stack; + const height = verticalLayout ? maxValueCoord - minValueCoord : barWidth; + const width = verticalLayout ? barWidth : maxValueCoord - minValueCoord; const result = { seriesId, dataIndex, layout: series[seriesId].layout, x: verticalLayout - ? xScale(xAxis[xAxisKey].data?.[dataIndex])! + barOffset - : minValueCoord, + ? xScale(xAxis[xAxisKey].data?.[dataIndex])! + barOffset - (width * numberOfGroups) / 2 + : minValueCoord - (height * numberOfGroups) / 2, y: verticalLayout ? minValueCoord - : yScale(yAxis[yAxisKey].data?.[dataIndex])! + barOffset, + : yScale(yAxis[yAxisKey].data?.[dataIndex])! + + barOffset - + (height * numberOfGroups) / 2, xOrigin: xScale(0)!, yOrigin: yScale(0)!, - height: verticalLayout ? maxValueCoord - minValueCoord : barWidth, - width: verticalLayout ? barWidth : maxValueCoord - minValueCoord, + height, + width, color: colorGetter(dataIndex), value: series[seriesId].data[dataIndex], maskId: `${chartId}_${stackId || seriesId}_${groupIndex}_${dataIndex}`, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c68df9bee1291..ffd602ab74b81 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -720,6 +720,9 @@ importers: '@react-spring/web': specifier: ^9.7.3 version: 9.7.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/d3-time': + specifier: ^3.0.3 + version: 3.0.3 clsx: specifier: ^2.1.1 version: 2.1.1 @@ -738,6 +741,9 @@ importers: d3-shape: specifier: ^3.2.0 version: 3.2.0 + d3-time: + specifier: ^3.1.0 + version: 3.1.0 prop-types: specifier: ^15.8.1 version: 15.8.1