Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[charts] Add Initializable type and behaviour to allow checking if a complex context has been initialized. #13365

Merged
merged 8 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/x-charts/src/BarChart/BarPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { useTransition } from '@react-spring/web';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { BarElement, BarElementSlotProps, BarElementSlots } from './BarElement';
import { AxisDefaultized } from '../models/axis';
Expand All @@ -14,6 +13,7 @@ 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';

/**
* Solution of the equations
Expand Down Expand Up @@ -87,7 +87,7 @@ const useAggregatedData = (): {
masksData: MaskData[];
} => {
const seriesData =
React.useContext(SeriesContext).bar ??
useBarSeries() ??
({ series: {}, stackingGroups: [], seriesOrder: [] } as FormatterResult<'bar'>);
const axisData = React.useContext(CartesianContext);
const chartId = useChartId();
Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/ChartsLegend/ChartsLegend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { useSlotProps } from '@mui/base/utils';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { useThemeProps, useTheme, Theme } from '@mui/material/styles';
import { AnchorPosition, Direction, getSeriesToDisplay } from './utils';
import { SeriesContext } from '../context/SeriesContextProvider';
import { ChartsLegendClasses, getLegendUtilityClass } from './chartsLegendClasses';
import { DefaultizedProps } from '../models/helpers';
import { DefaultChartsLegend, LegendRendererProps } from './DefaultChartsLegend';
import { useDrawingArea } from '../hooks';
import { useSeries } from '../hooks/useSeries';

export interface ChartsLegendSlots {
/**
Expand Down Expand Up @@ -83,7 +83,7 @@ function ChartsLegend(inProps: ChartsLegendProps) {
const classes = useUtilityClasses({ ...props, theme });

const drawingArea = useDrawingArea();
const series = React.useContext(SeriesContext);
const series = useSeries();

const seriesToDisplay = getSeriesToDisplay(series);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { SvgContext } from '../context/DrawingProvider';
import { InteractionContext } from '../context/InteractionProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { SeriesContext } from '../context/SeriesContextProvider';
import { useSeries } from '../hooks/useSeries';
import { useSvgRef } from '../hooks';

type AxisData = {
dataIndex: number;
Expand All @@ -24,8 +24,8 @@ export interface ChartsOnAxisClickHandlerProps {
function ChartsOnAxisClickHandler(props: ChartsOnAxisClickHandlerProps) {
const { onAxisClick } = props;

const svgRef = React.useContext(SvgContext);
const series = React.useContext(SeriesContext);
const svgRef = useSvgRef();
const series = useSeries();
const { axis } = React.useContext(InteractionContext);
const { xAxisIds, xAxis, yAxisIds, yAxis } = React.useContext(CartesianContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { SxProps, Theme } from '@mui/material/styles';
import { useSlotProps } from '@mui/base/utils';
import { AxisInteractionData } from '../context/InteractionProvider';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { ChartSeriesDefaultized, ChartSeriesType } from '../models/seriesType/config';
import { AxisDefaultized } from '../models/axis';
Expand All @@ -12,6 +11,7 @@ import { DefaultChartsAxisTooltipContent } from './DefaultChartsAxisTooltipConte
import { isCartesianSeriesType } from './utils';
import colorGetter from '../internals/colorGetter';
import { ZAxisContext } from '../context/ZAxisContextProvider';
import { useSeries } from '../hooks/useSeries';

type ChartSeriesDefaultizedWithColorGetter = ChartSeriesDefaultized<ChartSeriesType> & {
getColor: (dataIndex: number) => string;
Expand Down Expand Up @@ -61,7 +61,7 @@ function ChartsAxisTooltipContent(props: {

const { xAxisIds, xAxis, yAxisIds, yAxis } = React.useContext(CartesianContext);
const { zAxisIds, zAxis } = React.useContext(ZAxisContext);
const series = React.useContext(SeriesContext);
const series = useSeries();

const USED_AXIS_ID = isXaxis ? xAxisIds[0] : yAxisIds[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import PropTypes from 'prop-types';
import { SxProps, Theme } from '@mui/material/styles';
import { useSlotProps } from '@mui/base/utils';
import { ItemInteractionData } from '../context/InteractionProvider';
import { SeriesContext } from '../context/SeriesContextProvider';
import { ChartSeriesDefaultized, ChartSeriesType } from '../models/seriesType/config';
import { ChartsTooltipClasses } from './chartsTooltipClasses';
import { DefaultChartsItemTooltipContent } from './DefaultChartsItemTooltipContent';
import { CartesianContext } from '../context/CartesianContextProvider';
import colorGetter from '../internals/colorGetter';
import { ZAxisContext } from '../context/ZAxisContextProvider';
import { useSeries } from '../hooks/useSeries';

export type ChartsItemContentProps<T extends ChartSeriesType = ChartSeriesType> = {
/**
Expand Down Expand Up @@ -42,9 +42,7 @@ function ChartsItemTooltipContent<T extends ChartSeriesType>(props: {
}) {
const { content, itemData, sx, classes, contentProps } = props;

const series = React.useContext(SeriesContext)[itemData.type]!.series[
itemData.seriesId
] as ChartSeriesDefaultized<T>;
const series = useSeries()[itemData.type]!.series[itemData.seriesId] as ChartSeriesDefaultized<T>;

const { xAxis, yAxis, xAxisIds, yAxisIds } = React.useContext(CartesianContext);
const { zAxis, zAxisIds } = React.useContext(ZAxisContext);
Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/ChartsTooltip/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as React from 'react';
import { AxisInteractionData, ItemInteractionData } from '../context/InteractionProvider';
import { SvgContext } from '../context/DrawingProvider';
import {
CartesianChartSeriesType,
ChartSeriesDefaultized,
ChartSeriesType,
} from '../models/seriesType/config';
import { useSvgRef } from '../hooks';

export function generateVirtualElement(mousePosition: { x: number; y: number } | null) {
if (mousePosition === null) {
Expand Down Expand Up @@ -41,7 +41,7 @@ export function generateVirtualElement(mousePosition: { x: number; y: number } |
}

export function useMouseTracker() {
const svgRef = React.useContext(SvgContext);
const svgRef = useSvgRef();

// Use a ref to avoid rerendering on every mousemove event.
const [mousePosition, setMousePosition] = React.useState<null | { x: number; y: number }>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { Delaunay } from 'd3-delaunay';
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
import { InteractionContext } from '../context/InteractionProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { SeriesContext } from '../context/SeriesContextProvider';
import { getValueToPositionMapper } from '../hooks/useScale';
import { getSVGPoint } from '../internals/utils';
import { ScatterItemIdentifier } from '../models';
import { SeriesId } from '../models/seriesType/common';
import { useDrawingArea, useSvgRef } from '../hooks';
import { useHighlighted } from '../context';
import { useScatterSeries } from '../hooks/useSeries';

export type ChartsVoronoiHandlerProps = {
/**
Expand All @@ -35,7 +35,7 @@ function ChartsVoronoiHandler(props: ChartsVoronoiHandlerProps) {
const { xAxis, yAxis, xAxisIds, yAxisIds } = React.useContext(CartesianContext);
const { dispatch } = React.useContext(InteractionContext);

const { series, seriesOrder } = React.useContext(SeriesContext).scatter ?? {};
const { series, seriesOrder } = useScatterSeries() ?? {};
const voronoiRef = React.useRef<Record<string, VoronoiSeries>>({});
const delauneyRef = React.useRef<Delaunay<any> | undefined>(undefined);

Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/LineChart/AreaPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { area as d3Area } from 'd3-shape';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import {
AreaElement,
Expand All @@ -14,6 +13,7 @@ import getCurveFactory from '../internals/getCurve';
import { DEFAULT_X_AXIS_KEY } from '../constants';
import { LineItemIdentifier } from '../models/seriesType/line';
import { useChartGradient } from '../internals/components/ChartsAxesGradients';
import { useLineSeries } from '../hooks/useSeries';

export interface AreaPlotSlots extends AreaElementSlots {}

Expand All @@ -34,7 +34,7 @@ export interface AreaPlotProps
}

const useAggregatedData = () => {
const seriesData = React.useContext(SeriesContext).line;
const seriesData = useLineSeries();
const axisData = React.useContext(CartesianContext);

if (seriesData === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/LineChart/LineHighlightPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { LineHighlightElement, LineHighlightElementProps } from './LineHighlightElement';
import { getValueToPositionMapper } from '../hooks/useScale';
import { InteractionContext } from '../context/InteractionProvider';
import { DEFAULT_X_AXIS_KEY } from '../constants';
import getColor from './getColor';
import { useLineSeries } from '../hooks/useSeries';

export interface LineHighlightPlotSlots {
lineHighlight?: React.JSXElementConstructor<LineHighlightElementProps>;
Expand Down Expand Up @@ -42,7 +42,7 @@ export interface LineHighlightPlotProps extends React.SVGAttributes<SVGSVGElemen
function LineHighlightPlot(props: LineHighlightPlotProps) {
const { slots, slotProps, ...other } = props;

const seriesData = React.useContext(SeriesContext).line;
const seriesData = useLineSeries();
const axisData = React.useContext(CartesianContext);
const { axis } = React.useContext(InteractionContext);

Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/LineChart/LinePlot.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { line as d3Line } from 'd3-shape';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import {
LineElement,
Expand All @@ -14,6 +13,7 @@ import getCurveFactory from '../internals/getCurve';
import { DEFAULT_X_AXIS_KEY } from '../constants';
import { LineItemIdentifier } from '../models/seriesType/line';
import { useChartGradient } from '../internals/components/ChartsAxesGradients';
import { useLineSeries } from '../hooks/useSeries';

export interface LinePlotSlots extends LineElementSlots {}

Expand All @@ -34,7 +34,7 @@ export interface LinePlotProps
}

const useAggregatedData = () => {
const seriesData = React.useContext(SeriesContext).line;
const seriesData = useLineSeries();
const axisData = React.useContext(CartesianContext);

if (seriesData === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/LineChart/MarkPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { MarkElement, MarkElementProps } from './MarkElement';
import { getValueToPositionMapper } from '../hooks/useScale';
Expand All @@ -9,6 +8,7 @@ import { DEFAULT_X_AXIS_KEY } from '../constants';
import { LineItemIdentifier } from '../models/seriesType/line';
import { cleanId } from '../internals/utils';
import getColor from './getColor';
import { useLineSeries } from '../hooks/useSeries';

export interface MarkPlotSlots {
mark?: React.JSXElementConstructor<MarkElementProps>;
Expand Down Expand Up @@ -55,7 +55,7 @@ export interface MarkPlotProps
function MarkPlot(props: MarkPlotProps) {
const { slots, slotProps, skipAnimation, onItemClick, ...other } = props;

const seriesData = React.useContext(SeriesContext).line;
const seriesData = useLineSeries();
const axisData = React.useContext(CartesianContext);
const chartId = useChartId();

Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/PieChart/PiePlot.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { SeriesContext } from '../context/SeriesContextProvider';
import { DrawingContext } from '../context/DrawingProvider';
import { PieArcPlot, PieArcPlotProps, PieArcPlotSlotProps, PieArcPlotSlots } from './PieArcPlot';
import { PieArcLabelPlotSlots, PieArcLabelPlotSlotProps, PieArcLabelPlot } from './PieArcLabelPlot';
import { getPercentageValue } from '../internals/utils';
import { getPieCoordinates } from './getPieCoordinates';
import { usePieSeries } from '../hooks/useSeries';

export interface PiePlotSlots extends PieArcPlotSlots, PieArcLabelPlotSlots {}

Expand Down Expand Up @@ -36,7 +36,7 @@ export interface PiePlotProps extends Pick<PieArcPlotProps, 'skipAnimation' | 'o
*/
function PiePlot(props: PiePlotProps) {
const { skipAnimation, slots, slotProps, onItemClick } = props;
const seriesData = React.useContext(SeriesContext).pie;
const seriesData = usePieSeries();
const { left, top, width, height } = React.useContext(DrawingContext);

if (seriesData === undefined) {
Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/ScatterChart/ScatterPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { Scatter, ScatterProps } from './Scatter';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import getColor from './getColor';
import { ZAxisContext } from '../context/ZAxisContextProvider';
import { useScatterSeries } from '../hooks/useSeries';

export interface ScatterPlotSlots {
scatter?: React.JSXElementConstructor<ScatterProps>;
Expand Down Expand Up @@ -39,7 +39,7 @@ export interface ScatterPlotProps extends Pick<ScatterProps, 'onItemClick'> {
*/
function ScatterPlot(props: ScatterPlotProps) {
const { slots, slotProps, onItemClick } = props;
const seriesData = React.useContext(SeriesContext).scatter;
const seriesData = useScatterSeries();
const axisData = React.useContext(CartesianContext);
const { zAxis, zAxisIds } = React.useContext(ZAxisContext);

Expand Down
4 changes: 2 additions & 2 deletions packages/x-charts/src/context/CartesianContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
} from '../LineChart/extremums';
import { AxisConfig, AxisDefaultized, isBandScaleConfig, isPointScaleConfig } from '../models/axis';
import { getScale } from '../internals/getScale';
import { SeriesContext } from './SeriesContextProvider';
import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
import {
CartesianChartSeriesType,
Expand All @@ -28,6 +27,7 @@ import { getTickNumber } from '../hooks/useTicks';
import { useDrawingArea } from '../hooks/useDrawingArea';
import { SeriesId } from '../models/seriesType/common';
import { getColorScale, getOrdinalColorScale } from '../internals/colorScale';
import { useSeries } from '../hooks/useSeries';

export type CartesianContextProviderProps = {
/**
Expand Down Expand Up @@ -99,7 +99,7 @@ if (process.env.NODE_ENV !== 'production') {

function CartesianContextProvider(props: CartesianContextProviderProps) {
const { xAxis: inXAxis, yAxis: inYAxis, dataset, children } = props;
const formattedSeries = React.useContext(SeriesContext);
const formattedSeries = useSeries();
const drawingArea = useDrawingArea();

const xAxis = React.useMemo(
Expand Down
12 changes: 10 additions & 2 deletions packages/x-charts/src/context/DrawingProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import useId from '@mui/utils/useId';
import useChartDimensions from '../hooks/useChartDimensions';
import { LayoutConfig } from '../models/layout';
import { Initializable } from './context.types';

export interface DrawingProviderProps extends LayoutConfig {
children: React.ReactNode;
Expand Down Expand Up @@ -59,7 +60,12 @@ if (process.env.NODE_ENV !== 'production') {
DrawingContext.displayName = 'DrawingContext';
}

export const SvgContext = React.createContext<React.RefObject<SVGSVGElement>>({ current: null });
export type SvgContextState = React.RefObject<SVGSVGElement>;

export const SvgContext = React.createContext<Initializable<SvgContextState>>({
isInitialized: false,
data: { current: null },
});

if (process.env.NODE_ENV !== 'production') {
SvgContext.displayName = 'SvgContext';
Expand All @@ -75,8 +81,10 @@ export function DrawingProvider(props: DrawingProviderProps) {
[chartId, drawingArea],
);

const refValue = React.useMemo(() => ({ isInitialized: true, data: svgRef }), [svgRef]);

return (
<SvgContext.Provider value={svgRef}>
<SvgContext.Provider value={refValue}>
<DrawingContext.Provider value={value}>{children}</DrawingContext.Provider>
</SvgContext.Provider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { SeriesId } from '../../models/seriesType/common';
import { Initializable } from '../context.types';

/**
* The data of the highlighted item.
Expand Down Expand Up @@ -68,12 +69,15 @@ export type HighlightedState = {
isFaded: (input: HighlightItemData) => boolean;
};

export const HighlightedContext = React.createContext<HighlightedState>({
highlightedItem: null,
setHighlighted: () => {},
clearHighlighted: () => {},
isHighlighted: () => false,
isFaded: () => false,
export const HighlightedContext = React.createContext<Initializable<HighlightedState>>({
isInitialized: false,
data: {
highlightedItem: null,
setHighlighted: () => {},
clearHighlighted: () => {},
isHighlighted: () => false,
isFaded: () => false,
},
});

if (process.env.NODE_ENV !== 'production') {
Expand Down
Loading