Skip to content

Commit

Permalink
fix: mixed element voronoi
Browse files Browse the repository at this point in the history
  • Loading branch information
tannerlinsley committed Aug 3, 2021
1 parent 6830ffd commit c8a5867
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 19 deletions.
2 changes: 1 addition & 1 deletion examples/simple/src/ResizableBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "react-resizable/css/styles.css";

export default function ResizableBox({
children,
width = 500,
width = 600,
height = 300,
resizable = true,
style = {},
Expand Down
4 changes: 2 additions & 2 deletions examples/simple/src/components/MultipleAxes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { AxisOptions, Chart } from "react-charts";

export default function MultipleAxes() {
const { data, randomizeData } = useDemoConfig({
series: 10,
series: 6,
dataType: "time",
});

// @ts-ignore
data.forEach((d, i) => (d.secondaryAxisId = i % 3 === 0 ? "2" : undefined));
data.forEach((d, i) => (d.secondaryAxisId = i > 2 ? "2" : undefined));

const primaryAxis = React.useMemo<
AxisOptions<typeof data[number]["data"][number]>
Expand Down
11 changes: 11 additions & 0 deletions src/components/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ function ChartInner<TDatum>({
const series = React.useMemo(() => {
const series: Series<TDatum>[] = []

const indicesByAxisId: Record<string, number> = {}

for (
let seriesIndex = 0;
seriesIndex < options.data.length;
Expand All @@ -392,6 +394,12 @@ function ChartInner<TDatum>({
const originalDatums = originalSeries.data
const datums = []

indicesByAxisId[`${secondaryAxisId}`] =
indicesByAxisId[`${secondaryAxisId}`] ?? 0
const seriesIndexPerAxis = indicesByAxisId[`${secondaryAxisId}`]

indicesByAxisId[`${secondaryAxisId}`]++

for (
let datumIndex = 0;
datumIndex < originalDatums.length;
Expand All @@ -401,6 +409,7 @@ function ChartInner<TDatum>({
datums[datumIndex] = {
originalSeries,
seriesIndex,
seriesIndexPerAxis,
seriesId,
seriesLabel,
secondaryAxisId,
Expand All @@ -414,6 +423,7 @@ function ChartInner<TDatum>({
index: seriesIndex,
id: seriesId,
label: seriesLabel,
indexPerAxis: seriesIndexPerAxis,
secondaryAxisId,
datums,
}
Expand Down Expand Up @@ -528,6 +538,7 @@ function ChartInner<TDatum>({
}, [
allDatums,
options.interactionMode,
primaryAxis,
secondaryAxes,
tooltipOptions.groupingMode,
])
Expand Down
40 changes: 26 additions & 14 deletions src/components/Voronoi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ function PrimaryVoronoi<TDatum>({

const stackedVoronoi = secondaryAxes.length === 1 && secondaryAxes[0].stacked

const useBarPx = secondaryAxes.every(
d => d.elementType === 'bar' && !d.stacked
)

return React.useMemo(() => {
let preColumns = Array.from(datumsByInteractionGroup.entries())
.map(([_, datums]) => datums)
Expand All @@ -86,8 +90,8 @@ function PrimaryVoronoi<TDatum>({
const aAxis = secondaryAxes.find(d => d.id === a[0].secondaryAxisId)!
const bAxis = secondaryAxes.find(d => d.id === b[0].secondaryAxisId)!

const aPx = getPrimary(a[0], primaryAxis, aAxis)
const bPx = getPrimary(b[0], primaryAxis, bAxis)
const aPx = getPrimary(a[0], primaryAxis, aAxis, useBarPx)
const bPx = getPrimary(b[0], primaryAxis, bAxis, useBarPx)

return aPx - bPx
})
Expand All @@ -105,7 +109,7 @@ function PrimaryVoronoi<TDatum>({
const secondaryAxis = secondaryAxes.find(
d => d.id === datum.secondaryAxisId
)!
const primaryPx = getPrimary(datum, primaryAxis, secondaryAxis)
const primaryPx = getPrimary(datum, primaryAxis, secondaryAxis, useBarPx)

let range = primaryAxis?.scale.range() ?? [0, 0]

Expand All @@ -115,15 +119,15 @@ function PrimaryVoronoi<TDatum>({
const secondaryAxis = secondaryAxes.find(
d => d.id === prev[0].secondaryAxisId
)!
const prevPx = getPrimary(prev[0], primaryAxis, secondaryAxis)
const prevPx = getPrimary(prev[0], primaryAxis, secondaryAxis, useBarPx)
primaryStart = primaryPx - (primaryPx - prevPx) / 2
}

if (next) {
const secondaryAxis = secondaryAxes.find(
d => d.id === next[0].secondaryAxisId
)!
const nextPx = getPrimary(next[0], primaryAxis, secondaryAxis)
const nextPx = getPrimary(next[0], primaryAxis, secondaryAxis, useBarPx)
primaryEnd = primaryPx + (nextPx - primaryPx) / 2
}

Expand Down Expand Up @@ -283,10 +287,11 @@ function PrimaryVoronoi<TDatum>({
)
}, [
datumsByInteractionGroup,
primaryAxis,
gridDimensions.left,
gridDimensions.top,
secondaryAxes,
primaryAxis,
useBarPx,
stackedVoronoi,
handleFocus,
getOptions,
Expand All @@ -313,6 +318,10 @@ function SingleVoronoi<TDatum>({

const voronoiData: { x: number; y: number; datum: Datum<TDatum> }[] = []

const useBarPx = secondaryAxes.every(
d => d.elementType === 'bar' && !d.stacked
)

series.forEach(serie => {
serie.datums
.filter(datum => {
Expand All @@ -329,8 +338,8 @@ function SingleVoronoi<TDatum>({
const secondaryAxis = secondaryAxes.find(
d => d.id === datum.secondaryAxisId
)
const x = getX(datum, primaryAxis, secondaryAxis!)
const y = getY(datum, primaryAxis, secondaryAxis!)
const x = getX(datum, primaryAxis, secondaryAxis!, useBarPx)
const y = getY(datum, primaryAxis, secondaryAxis!, useBarPx)

if (
typeof x !== 'number' ||
Expand Down Expand Up @@ -403,31 +412,34 @@ function SingleVoronoi<TDatum>({
function getX<TDatum>(
datum: Datum<TDatum>,
primaryAxis: Axis<TDatum>,
secondaryAxis: Axis<TDatum>
secondaryAxis: Axis<TDatum>,
useBarPx: boolean
): number {
return primaryAxis.isVertical
? getSecondary(datum, secondaryAxis)
: getPrimary(datum, primaryAxis, secondaryAxis)
: getPrimary(datum, primaryAxis, secondaryAxis, useBarPx)
}

function getY<TDatum>(
datum: Datum<TDatum>,
primaryAxis: Axis<TDatum>,
secondaryAxis: Axis<TDatum>
secondaryAxis: Axis<TDatum>,
useBarPx: boolean
): number {
return primaryAxis.isVertical
? getPrimary(datum, primaryAxis, secondaryAxis)
? getPrimary(datum, primaryAxis, secondaryAxis, useBarPx)
: getSecondary(datum, secondaryAxis)
}

function getPrimary<TDatum>(
datum: Datum<TDatum>,
primaryAxis: Axis<TDatum>,
secondaryAxis: Axis<TDatum>
secondaryAxis: Axis<TDatum>,
useBarPx: boolean
): number {
let primary = primaryAxis.scale(datum.primaryValue) ?? NaN

if (secondaryAxis.elementType === 'bar') {
if (useBarPx && secondaryAxis.elementType === 'bar') {
if (!secondaryAxis.stacked) {
primary += primaryAxis.seriesBandScale!(datum.seriesIndex) ?? NaN
primary += getPrimaryLength(datum, primaryAxis, secondaryAxis) / 2
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ export type UserSerie<TDatum> = {
export type Series<TDatum> = {
originalSeries: UserSerie<TDatum>
index: number
indexPerAxis: number
id: string
label: string
secondaryAxisId?: string
Expand All @@ -451,6 +452,7 @@ export type Datum<TDatum> = {
index: number
originalDatum: TDatum
secondaryAxisId?: string
seriesIndexPerAxis: number
primaryValue?: any
secondaryValue?: any
stackData?: StackDatum<TDatum>
Expand Down
11 changes: 9 additions & 2 deletions src/utils/buildAxis.linear.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ function buildBandAxis<TDatum>(
range: [number, number],
outerRange: [number, number]
): AxisBand<TDatum> {
series = series.filter(d => d.secondaryAxisId === options.id)

const domain = Array.from(
new Set(
series
Expand Down Expand Up @@ -524,7 +526,9 @@ function buildSeriesBandScale<TDatum>(
primaryBandScale: ScaleBand<number>,
series: Series<TDatum>[]
) {
const bandDomain = d3Range(series.length)
const bandDomain = d3Range(
series.filter(d => d.secondaryAxisId === options.id).length
)

const seriesBandScale = scaleBand(bandDomain, [
0,
Expand All @@ -540,5 +544,8 @@ function buildSeriesBandScale<TDatum>(
(options.innerBandPadding ? options.innerBandPadding / 2 : 0)
)

return seriesBandScale
const scale = (seriesIndex: number) =>
seriesBandScale(series.find(d => d.index === seriesIndex)!?.indexPerAxis)

return Object.assign(scale, seriesBandScale)
}

1 comment on commit c8a5867

@vercel
Copy link

@vercel vercel bot commented on c8a5867 Aug 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.