diff --git a/src/components/Chart.tsx b/src/components/Chart.tsx index ae91329e..de01081d 100644 --- a/src/components/Chart.tsx +++ b/src/components/Chart.tsx @@ -25,7 +25,7 @@ import { materializeStyles, getSeriesStatus, getDatumStatus, - sortDatums, + sortDatumsBySecondaryPx, } from '../utils/Utils' import buildAxisLinear from '../utils/buildAxis.linear' import { ChartContextProvider } from '../utils/chartContext' @@ -70,7 +70,7 @@ function defaultChartOptions( getSeriesOrder: options.getSeriesOrder ?? ((series: Series[]) => series), interactionMode: options.interactionMode ?? 'primary', - showVoronoi: options.showVoronoi ?? false, + showVoronoi: options.showVoronoi ?? true, defaultColors: options.defaultColors ?? defaultColorScheme, useIntersectionObserver: options.useIntersectionObserver ?? true, intersectionObserverRootMargin: @@ -269,7 +269,10 @@ function ChartInner({ optionsWithScaleType.stacked = true } - return { position: !i ? 'left' : 'right', ...optionsWithScaleType } + return { + position: !i ? 'left' : 'right', + ...optionsWithScaleType, + } } ) }, [options.data, options.secondaryAxes, primaryAxisOptions]) @@ -491,11 +494,17 @@ function ChartInner({ }) datumsByInteractionGroup.forEach((value, key) => { - datumsByInteractionGroup.set(key, sortDatums(value, secondaryAxes)) + datumsByInteractionGroup.set( + key, + sortDatumsBySecondaryPx(value, secondaryAxes) + ) }) datumsByTooltipGroup.forEach((value, key) => { - datumsByTooltipGroup.set(key, sortDatums(value, secondaryAxes)) + datumsByTooltipGroup.set( + key, + sortDatumsBySecondaryPx(value, secondaryAxes) + ) }) allDatums.forEach(datum => { @@ -506,7 +515,12 @@ function ChartInner({ }) return [datumsByInteractionGroup, datumsByTooltipGroup] - }, [allDatums, options.interactionMode, tooltipOptions.groupingMode]) + }, [ + allDatums, + options.interactionMode, + secondaryAxes, + tooltipOptions.groupingMode, + ]) const getSeriesStatusStyle = React.useCallback( (series: Series, focusedDatum: Datum | null) => { diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx index 3e617247..887bfcac 100644 --- a/src/components/Tooltip.tsx +++ b/src/components/Tooltip.tsx @@ -187,6 +187,7 @@ export default function Tooltip(): React.ReactPortal | null { getOptions, focusedDatum: latestFocusedDatum, primaryAxis, + secondaryAxes, secondaryAxis, getDatumStyle: (datum: Datum) => getDatumStatusStyle(datum, focusedDatum), diff --git a/src/components/TooltipRenderer.tsx b/src/components/TooltipRenderer.tsx index 3eb15247..cbc6e9e0 100644 --- a/src/components/TooltipRenderer.tsx +++ b/src/components/TooltipRenderer.tsx @@ -25,6 +25,7 @@ export type TooltipRendererProps = { focusedDatum: Datum | null getOptions: () => ResolvedChartOptions primaryAxis: Axis + secondaryAxes: Axis[] secondaryAxis: Axis getDatumStyle: (datum: Datum) => CSSProperties anchor: ReturnType @@ -325,47 +326,58 @@ function TooltipRenderer(props: TooltipRendererProps) { ) : null} - {secondaryAxis.stacked && - (focusedDatum.tooltipGroup ?? []).length > 1 ? ( - - -
- - - Total:   - - - {/* {secondaryAxis.format( + {(focusedDatum.tooltipGroup ?? []).length > 1 + ? props.secondaryAxes + .filter(d => d.stacked) + .map((secondaryAxis, i) => { + return ( + + +
+ + + {props.secondaryAxes.length > 1 + ? secondaryAxis.id ?? `Axis ${i + 1} ` + : ''} + Total:   + + + {/* {secondaryAxis.format( [...focusedDatum.group].reverse()[0].totalValue, -1 )} */} - {(secondaryAxis as AxisLinear).formatters.scale( - sum(focusedDatum.tooltipGroup ?? [], d => d.secondaryValue) - )} - - - ) : null} + {(secondaryAxis as AxisLinear).formatters.scale( + sum( + focusedDatum.tooltipGroup ?? [], + d => d.secondaryValue + ) + )} + + + ) + }) + : null}
diff --git a/src/components/Voronoi.tsx b/src/components/Voronoi.tsx index cafa6df9..c7869864 100644 --- a/src/components/Voronoi.tsx +++ b/src/components/Voronoi.tsx @@ -3,7 +3,13 @@ import { Delaunay } from 'd3-delaunay' // import { Datum } from '../types' -import { getPrimary, getX, getY, sortDatums, translate } from '../utils/Utils' +import { + getPrimary, + getX, + getY, + sortDatumsBySecondaryPx, + translate, +} from '../utils/Utils' import useChartContext from '../utils/chartContext' import { line } from 'd3-shape' @@ -67,6 +73,8 @@ function PrimaryVoronoi({ datumsByInteractionGroup, } = useChartContext() + const stackedVoronoi = secondaryAxes.length === 1 && secondaryAxes[0].stacked + return React.useMemo(() => { const columns = series[0].datums .filter(datum => { @@ -115,7 +123,7 @@ function PrimaryVoronoi({ d => d.id === datum.secondaryAxisId ) - if (secondaryAxis?.stacked) { + if (stackedVoronoi) { let range = secondaryAxis?.scale.range() ?? [0, 0] let stackData = [datum.stackData?.[0], datum.stackData?.[1]] @@ -144,7 +152,12 @@ function PrimaryVoronoi({ } } - const value = secondaryAxis?.scale(datum.secondaryValue) ?? NaN + const value = + secondaryAxis?.scale( + secondaryAxis.stacked + ? datum.stackData?.[1] + : datum.secondaryValue + ) ?? NaN let range = secondaryAxis?.scale.range() ?? [0, 0] @@ -158,7 +171,10 @@ function PrimaryVoronoi({ const prevAxis = secondaryAxes.find( d => d.id === prev?.secondaryAxisId ) - const prevValue = prevAxis?.scale(prev.secondaryValue) ?? NaN + const prevValue = + prevAxis?.scale( + prevAxis.stacked ? prev.stackData?.[1] : prev.secondaryValue + ) ?? NaN secondaryStart = value - (value - prevValue) / 2 } @@ -166,7 +182,10 @@ function PrimaryVoronoi({ const nextAxis = secondaryAxes.find( d => d.id === next?.secondaryAxisId ) - const nextValue = nextAxis?.scale(next.secondaryValue) ?? NaN + const nextValue = + nextAxis?.scale( + nextAxis.stacked ? next.stackData?.[1] : next.secondaryValue + ) ?? NaN secondaryEnd = value + (nextValue - value) / 2 } @@ -241,14 +260,15 @@ function PrimaryVoronoi({ ) }, [ - getOptions, + series, gridDimensions.left, gridDimensions.top, - datumsByInteractionGroup, - handleFocus, primaryAxis, + datumsByInteractionGroup, secondaryAxes, - series, + stackedVoronoi, + handleFocus, + getOptions, ]) } diff --git a/src/types.ts b/src/types.ts index 0535a7f6..4fc8aeb5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -249,7 +249,7 @@ export type AxisOptionsBase = { show?: boolean stacked?: boolean stackOffset?: typeof stackOffsetNone - id?: string + id?: string | number styles?: CSSProperties & { line?: CSSProperties tick?: CSSProperties diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index e657abe0..ac8143f6 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -267,7 +267,7 @@ export function getTickPx(scale: Axis['scale'], value: any) { return px } -export function sortDatums( +export function sortDatumsBySecondaryPx( datums: Datum[], secondaryAxes: Axis[] ) { @@ -277,6 +277,7 @@ export function sortDatums( const aPx = aAxis?.scale(aAxis.stacked ? a.stackData?.[1] : a.secondaryValue) ?? NaN + const bPx = bAxis?.scale(bAxis.stacked ? b.stackData?.[1] : b.secondaryValue) ?? NaN