Skip to content

Commit

Permalink
fix: vertical voronois, tooltips, min/max
Browse files Browse the repository at this point in the history
  • Loading branch information
tannerlinsley committed Jul 14, 2021
1 parent 91c47d5 commit 2936325
Show file tree
Hide file tree
Showing 12 changed files with 2,101 additions and 1,995 deletions.
56 changes: 56 additions & 0 deletions examples/simple/src/components/BarHorizontal.tsx
@@ -0,0 +1,56 @@
import ResizableBox from "../ResizableBox";
import useDemoConfig from "../useDemoConfig";
import React from "react";
import { AxisOptions, Chart } from "react-charts";

export default function Bar() {
const { data, randomizeData } = useDemoConfig({
series: 10,
dataType: "ordinal",
});

const primaryAxis = React.useMemo<
AxisOptions<typeof data[number]["data"][number]>
>(
() => ({
isPrimary: true,
scaleType: "band",
position: "left",
getValue: (datum) => datum.primary,
}),
[]
);

const secondaryAxes = React.useMemo<
AxisOptions<typeof data[number]["data"][number]>[]
>(
() => [
{
scaleType: "linear",
position: "bottom",
getValue: (datum) => datum.secondary,
elementType: "bar",
stacked: true,
},
],
[]
);

return (
<>
<button onClick={randomizeData}>Randomize Data</button>
<br />
<br />
<ResizableBox>
<Chart
options={{
data,
primaryAxis,
secondaryAxes,
tooltip: true,
}}
/>
</ResizableBox>
</>
);
}
2 changes: 1 addition & 1 deletion examples/simple/src/components/Bubble.tsx
Expand Up @@ -17,7 +17,7 @@ export default function Bubble() {
isPrimary: true,
scaleType: "time",
position: "bottom",
getValue: (datum) => (datum.primary as unknown) as Date,
getValue: (datum) => datum.primary as unknown as Date,
}),
[]
);
Expand Down
2 changes: 2 additions & 0 deletions examples/simple/src/index.tsx
Expand Up @@ -9,6 +9,7 @@ import GroupingModes from "./components/GroupingModes";
import Line from "./components/Line";
import MultipleAxes from "./components/MultipleAxes";
import Steam from "./components/Steam";
import BarHorizontal from "./components/BarHorizontal";
import "./styles.css";
import useLagRadar from "./useLagRadar";
import React from "react";
Expand All @@ -17,6 +18,7 @@ import ReactDOM from "react-dom";
const components = [
["Line", Line],
["Bar", Bar],
["Bar (Horizontal)", BarHorizontal],
["Band", Band],
["Area", Area],
["Bubble", Bubble],
Expand Down
63 changes: 14 additions & 49 deletions src/components/Voronoi.tsx
Expand Up @@ -2,7 +2,7 @@ import React from 'react'

//
import { Datum } from '../types'
import { translate } from '../utils/Utils'
import { getPrimary, translate } from '../utils/Utils'
import useChartContext from '../utils/chartContext'

export default function Voronoi<TDatum>() {
Expand Down Expand Up @@ -74,25 +74,19 @@ function PrimaryVoronoi<TDatum>({
const next = series[0].datums[i + 1]

const primaryValue = primaryAxis.getValue(datum.originalDatum)
const primaryPx = primaryAxis?.scale(primaryValue) ?? NaN
const primaryPx = getPrimary(datum, primaryAxis)

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

if (primaryAxis?.isVertical) {
range.reverse()
}

let [primaryStart, primaryEnd] = range

if (prev) {
const prevPx =
primaryAxis?.scale(primaryAxis.getValue(prev.originalDatum)) ?? NaN
const prevPx = getPrimary(prev, primaryAxis)
primaryStart = primaryPx - (primaryPx - prevPx) / 2
}

if (next) {
const nextPx =
primaryAxis?.scale(primaryAxis.getValue(next.originalDatum)) ?? NaN
const nextPx = getPrimary(next, primaryAxis)
primaryEnd = primaryPx + (nextPx - primaryPx) / 2
}

Expand Down Expand Up @@ -129,20 +123,21 @@ function PrimaryVoronoi<TDatum>({
if (secondaryAxis?.stacked) {
let range = secondaryAxis?.scale.range() ?? [0, 0]

let stackData = [datum.stackData?.[0], datum.stackData?.[1]]

if (secondaryAxis?.isVertical) {
range.reverse()
stackData.reverse()
}

let [secondaryStart, secondaryEnd] = range

if (prev) {
secondaryStart =
secondaryAxis?.scale(datum.stackData?.[1] ?? NaN) ?? NaN
secondaryStart = secondaryAxis?.scale(stackData[0] ?? NaN) ?? NaN
}

if (next) {
secondaryEnd =
secondaryAxis?.scale(datum.stackData?.[0] ?? NaN) ?? NaN
secondaryEnd = secondaryAxis?.scale(stackData[1] ?? NaN) ?? NaN
}

return {
Expand Down Expand Up @@ -237,7 +232,11 @@ function PrimaryVoronoi<TDatum>({
className: 'action-voronoi',
onMouseEnter: () => handleFocus(datumBoundary.datum),
style: {
fill: randomFill(),
fill: getOptions().dark
? '#ffffff33'
: 'rgba(0,0,0,0.2)',
strokeWidth: 1,
stroke: getOptions().dark ? 'white' : 'black',
opacity: getOptions().showVoronoi ? 1 : 0,
},
}}
Expand Down Expand Up @@ -335,37 +334,3 @@ function PrimaryVoronoi<TDatum>({
// </g>
// )
// }

function randomFill() {
const r = randomHue(100, 200)
const g = randomHue(0, r)
const b = randomHue(0, g)

const colors = shuffle([r, g, b])

return `rgba(${colors.join(', ')}, .5)`
}

function randomHue(min = 0, max = 255) {
return Math.floor(min + Math.random() * Math.min(max, 255 - min))
}

function shuffle<T>(array: T[]): T[] {
var currentIndex = array.length,
randomIndex

// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex)
currentIndex--

// And swap it with the current element.
;[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
]
}

return array
}
5 changes: 1 addition & 4 deletions src/hooks/useRect.ts
Expand Up @@ -29,11 +29,8 @@ export default function useRect(
}
})

const initialRectSet = React.useRef(false)

useIsomorphicLayoutEffect(() => {
if (enabled && element && !initialRectSet.current) {
initialRectSet.current = true
if (enabled && element) {
setRect(element.getBoundingClientRect())
}
}, [element, enabled])
Expand Down
33 changes: 9 additions & 24 deletions src/seriesTypes/Area.tsx
Expand Up @@ -2,7 +2,7 @@ import { area, line } from 'd3-shape'
import React from 'react'

import { Axis, Series, Datum } from '../types'
import { translate } from '../utils/Utils'
import { getX, getY, getYStart, translate } from '../utils/Utils'
import useChartContext from '../utils/chartContext'
//
import { monotoneX } from '../utils/curveMonotone'
Expand All @@ -27,21 +27,6 @@ export default function AreaComponent<TDatum>({

const [focusedDatum] = useFocusedDatumAtom()

const xAxis = primaryAxis.isVertical ? secondaryAxis : primaryAxis
const yAxis = !primaryAxis.isVertical ? secondaryAxis : primaryAxis

const getX = (datum: Datum<TDatum>) =>
xAxis.scale(
xAxis.stacked ? datum.stackData?.[1] : xAxis.getValue(datum.originalDatum)
)

const getY = (datum: Datum<TDatum>, isEnd: 0 | 1) =>
yAxis.scale(
yAxis.stacked
? datum.stackData?.[isEnd]
: yAxis.getValue(datum.originalDatum)
)

return (
<g
style={{
Expand All @@ -67,15 +52,15 @@ export default function AreaComponent<TDatum>({

const areaPath =
area<Datum<TDatum>>(
datum => getX(datum) ?? NaN,
datum => getY(datum, 0) ?? NaN,
datum => getY(datum, 1) ?? NaN
datum => getX(datum, primaryAxis, secondaryAxis) ?? NaN,
datum => getYStart(datum, primaryAxis, secondaryAxis) ?? NaN,
datum => getY(datum, primaryAxis, secondaryAxis) ?? NaN
).curve(curve)(series.datums) ?? undefined

const linePath =
line<Datum<TDatum>>(
datum => getX(datum) ?? NaN,
datum => getY(datum, 1) ?? NaN
datum => getX(datum, primaryAxis, secondaryAxis) ?? NaN,
datum => getY(datum, primaryAxis, secondaryAxis) ?? NaN
).curve(curve)(series.datums) ?? undefined

return (
Expand All @@ -92,8 +77,8 @@ export default function AreaComponent<TDatum>({
datum.element = el
}}
r={2}
cx={getX(datum)}
cy={getY(datum, 1) ?? NaN}
cx={getX(datum, primaryAxis, secondaryAxis)}
cy={getY(datum, primaryAxis, secondaryAxis) ?? NaN}
stroke="rgba(33,33,33,0.5)"
style={{
// @ts-ignore
Expand All @@ -102,7 +87,7 @@ export default function AreaComponent<TDatum>({
...style.circle,
...dataStyle,
...dataStyle.circle,
...(!(secondaryAxis.showDatumElements ?? true)
...(!(secondaryAxis.showDatumElements ?? false)
? {
opacity: 0,
}
Expand Down
14 changes: 11 additions & 3 deletions src/seriesTypes/Bar.tsx
@@ -1,7 +1,15 @@
import React from 'react'

import { Axis, Series } from '../types'
import { getHeight, getWidth, getX, getY, translate } from '../utils/Utils'
import {
getHeight,
getWidth,
getX,
getXStart,
getY,
getYStart,
translate,
} from '../utils/Utils'
import useChartContext from '../utils/chartContext'

//
Expand Down Expand Up @@ -44,8 +52,8 @@ export default function BarComponent<TDatum>({
datum.element = el
}}
key={i}
x={getX(datum, primaryAxis, secondaryAxis) ?? NaN}
y={getY(datum, primaryAxis, secondaryAxis) ?? NaN}
x={getXStart(datum, primaryAxis, secondaryAxis) ?? NaN}
y={getYStart(datum, primaryAxis, secondaryAxis) ?? NaN}
width={getWidth(datum, primaryAxis, secondaryAxis) ?? NaN}
height={getHeight(datum, primaryAxis, secondaryAxis) ?? NaN}
style={{
Expand Down
23 changes: 5 additions & 18 deletions src/seriesTypes/Line.tsx
Expand Up @@ -2,7 +2,7 @@ import { line } from 'd3-shape'
import React from 'react'

import { Axis, Series, Datum } from '../types'
import { translate } from '../utils/Utils'
import { getX, getY, translate } from '../utils/Utils'
import useChartContext from '../utils/chartContext'
//
import { monotoneX } from '../utils/curveMonotone'
Expand Down Expand Up @@ -31,19 +31,6 @@ export default function Line<TDatum>({

const [focusedDatum] = useFocusedDatumAtom()

const xAxis = primaryAxis.isVertical ? secondaryAxis : primaryAxis
const yAxis = !primaryAxis.isVertical ? secondaryAxis : primaryAxis

const getX = (datum: Datum<TDatum>) =>
xAxis.scale(
xAxis.stacked ? datum.stackData?.[1] : xAxis.getValue(datum.originalDatum)
)

const getY = (datum: Datum<TDatum>) =>
yAxis.scale(
yAxis.stacked ? datum.stackData?.[1] : yAxis.getValue(datum.originalDatum)
)

return (
<g
style={{
Expand All @@ -62,8 +49,8 @@ export default function Line<TDatum>({

const linePath =
line<Datum<TDatum>>(
datum => getX(datum) ?? NaN,
datum => getY(datum) ?? NaN
datum => getX(datum, primaryAxis, secondaryAxis) ?? NaN,
datum => getY(datum, primaryAxis, secondaryAxis) ?? NaN
).curve(curve)(series.datums) ?? undefined

return (
Expand All @@ -78,8 +65,8 @@ export default function Line<TDatum>({
datum.element = el
}}
r={2}
cx={getX(datum)}
cy={getY(datum)}
cx={getX(datum, primaryAxis, secondaryAxis)}
cy={getY(datum, primaryAxis, secondaryAxis)}
stroke="rgba(33,33,33,0.5)"
fill="transparent"
style={{
Expand Down

0 comments on commit 2936325

Please sign in to comment.