Skip to content

Commit

Permalink
Add element to prevent unnecessary computation
Browse files Browse the repository at this point in the history
  • Loading branch information
JCQuintas committed May 3, 2024
1 parent 8610ff1 commit eb70e5a
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 31 deletions.
2 changes: 2 additions & 0 deletions packages/x-charts/src/BarChart/BarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ const BarChart = React.forwardRef(function BarChart(props: BarChartProps, ref) {
slots,
slotProps,
loading,
showLabels,
} = props;

const id = useId();
Expand Down Expand Up @@ -195,6 +196,7 @@ const BarChart = React.forwardRef(function BarChart(props: BarChartProps, ref) {
slotProps={slotProps}
skipAnimation={skipAnimation}
onItemClick={onItemClick}
showLabels={showLabels}
/>
<ChartsOverlay loading={loading} slots={slots} slotProps={slotProps} />
</g>
Expand Down
74 changes: 74 additions & 0 deletions packages/x-charts/src/BarChart/BarElementLabelPlot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as React from 'react';

import { to, useTransition } from '@react-spring/web';
import type { CompletedBarData } from './BarPlot';
import { BarElementLabel } from './BarElementLabel';

const getOutStyle = ({ layout, yOrigin, x, width, y, xOrigin, height }: CompletedBarData) => ({
...(layout === 'vertical'
? {
y: yOrigin,
x,
height: 0,
width,
}
: {
y,
x: xOrigin,
height,
width: 0,
}),
});

const getInStyle = ({ x, width, y, height }: CompletedBarData) => ({
y,
x,
height,
width,
});

type BarElementLabelPlotProps = {
bars: CompletedBarData[];
skipAnimation?: boolean;
};

/**
* @ignore - internal component.
*/
function BarElementLabelPlot(props: BarElementLabelPlotProps) {
const { bars, skipAnimation, ...other } = props;

const barLabelTransition = useTransition(bars, {
keys: (bar) => `${bar.seriesId}-${bar.dataIndex}`,
from: getOutStyle,
leave: null,
enter: getInStyle,
update: getInStyle,
immediate: skipAnimation,
});

return (
<React.Fragment>
{barLabelTransition((style, { seriesId, dataIndex, color, value, width, height }) => (
<BarElementLabel
seriesId={seriesId}
dataIndex={dataIndex}
color={color}
width={width}
height={height}
{...other}
style={
{
...style,
x: to([(style as any).x, (style as any).width], (x, w) => (x ?? 0) + w / 2),
y: to([(style as any).y, (style as any).height], (y, w) => (y ?? 0) + w / 2),
} as any
}
labelText={value ? value.toString() : null}
/>
))}
</React.Fragment>
);
}

export { BarElementLabelPlot };
53 changes: 22 additions & 31 deletions packages/x-charts/src/BarChart/BarPlot.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { to, useTransition } from '@react-spring/web';
import { useTransition } from '@react-spring/web';
import { SeriesContext } from '../context/SeriesContextProvider';
import { CartesianContext } from '../context/CartesianContextProvider';
import { BarElement, BarElementSlotProps, BarElementSlots } from './BarElement';
Expand All @@ -11,7 +11,8 @@ import { BarItemIdentifier, BarSeriesType } from '../models';
import { DEFAULT_X_AXIS_KEY, DEFAULT_Y_AXIS_KEY } from '../constants';
import { SeriesId } from '../models/seriesType/common';
import getColor from './getColor';
import { BarElementLabel, BarElementLabelSlotProps, BarElementLabelSlots } from './BarElementLabel';
import { BarElementLabelSlotProps, BarElementLabelSlots } from './BarElementLabel';
import { BarElementLabelPlot } from './BarElementLabelPlot';

/**
* Solution of the equations
Expand Down Expand Up @@ -49,7 +50,7 @@ export interface BarPlotSlots extends BarElementSlots, BarElementLabelSlots {}

export interface BarPlotSlotProps extends BarElementSlotProps, BarElementLabelSlotProps {}

export interface BarPlotProps extends BarPlotSlotProps {
export interface BarPlotProps {
/**
* If `true`, animations are skipped.
* @default false
Expand All @@ -64,6 +65,20 @@ export interface BarPlotProps extends BarPlotSlotProps {
event: React.MouseEvent<SVGElement, MouseEvent>,
barItemIdentifier: BarItemIdentifier,
) => void;
/**
* If `true`, displays the value labels on the bars.
*/
showLabels?: boolean;
/**
* The props used for each component slot.
* @default {}
*/
slotProps?: BarPlotSlotProps;
/**
* Overridable component slots.
* @default {}
*/
slots?: BarPlotSlots;
}

export interface CompletedBarData {
Expand Down Expand Up @@ -246,7 +261,7 @@ const getInStyle = ({ x, width, y, height }: CompletedBarData) => ({
*/
function BarPlot(props: BarPlotProps) {
const completedData = useAggregatedData();
const { skipAnimation, onItemClick, ...other } = props;
const { skipAnimation, onItemClick, showLabels, ...other } = props;

const transition = useTransition(completedData, {
keys: (bar) => `${bar.seriesId}-${bar.dataIndex}`,
Expand All @@ -257,15 +272,6 @@ function BarPlot(props: BarPlotProps) {
immediate: skipAnimation,
});

const barLabelTransition = useTransition(completedData, {
keys: (bar) => `${bar.seriesId}-${bar.dataIndex}`,
from: getOutStyle,
leave: null,
enter: getInStyle,
update: getInStyle,
immediate: skipAnimation,
});

return (
<React.Fragment>
{transition((style, { seriesId, dataIndex, color, highlightScope }) => (
Expand All @@ -284,24 +290,9 @@ function BarPlot(props: BarPlotProps) {
style={style}
/>
))}
{barLabelTransition((style, { seriesId, dataIndex, color, value, width, height }) => (
<BarElementLabel
seriesId={seriesId}
dataIndex={dataIndex}
color={color}
width={width}
height={height}
{...other}
style={
{
...style,
x: to([(style as any).x, (style as any).width], (x, w) => (x ?? 0) + w / 2),
y: to([(style as any).y, (style as any).height], (y, w) => (y ?? 0) + w / 2),
} as any
}
labelText={value ? value.toString() : null}
/>
))}
{showLabels && (
<BarElementLabelPlot bars={completedData} skipAnimation={skipAnimation} {...other} />
)}
</React.Fragment>
);
}
Expand Down

0 comments on commit eb70e5a

Please sign in to comment.