Skip to content

Commit

Permalink
fix(swarmplot): make it compile after TS conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
wyze committed Jun 22, 2021
1 parent 73a0812 commit 46ddb27
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 43 deletions.
2 changes: 1 addition & 1 deletion packages/swarmplot/src/Circles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const Circles = <RawDatum,>({
opacity: number
}
>(nodes, {
key: node => node.id,
keys: node => node.id,
initial: transitionPhases.update,
from: transitionPhases.enter,
enter: transitionPhases.update,
Expand Down
5 changes: 4 additions & 1 deletion packages/swarmplot/src/SwarmPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const InnerSwarmPlot = <RawDatum,>({
partialMargin
)

const { nodes, xScale, yScale } = useSwarmPlot<RawDatum>({
const { nodes, ...props } = useSwarmPlot<RawDatum>({
width: innerWidth,
height: innerHeight,
data,
Expand All @@ -85,6 +85,9 @@ const InnerSwarmPlot = <RawDatum,>({
simulationIterations,
})

const xScale = props.xScale as Exclude<typeof props.xScale, ComputedDatum<RawDatum>[]>
const yScale = props.yScale as Exclude<typeof props.yScale, ComputedDatum<RawDatum>[]>

const layerById: Record<SwarmPlotLayerId, ReactNode> = {
grid: null,
axes: null,
Expand Down
58 changes: 33 additions & 25 deletions packages/swarmplot/src/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@ import isNumber from 'lodash/isNumber'
import isPlainObject from 'lodash/isPlainObject'
import isString from 'lodash/isString'
import get from 'lodash/get'
import { ScaleLinear, scaleLinear, ScaleOrdinal, scaleOrdinal } from 'd3-scale'
import { scaleLinear, ScaleOrdinal, scaleOrdinal } from 'd3-scale'
import { forceSimulation, forceX, forceY, forceCollide, ForceX, ForceY } from 'd3-force'
import {
// @ts-ignore
computeScale,
// @ts-ignore
createDateNormalizer,
// @ts-ignore
generateSeriesAxis,
Scale,
TimeScaleFormatted,
ScaleLinear,
ScaleLinearSpec,
ScaleTime,
ScaleTimeSpec,
} from '@nivo/scales'
import { ComputedDatum, PreSimulationDatum, SizeSpec, SimulationForces } from './types'

export const getParsedValue = (scaleSpec: Scale) => {
if (scaleSpec.type === 'linear') {
return parseFloat
} else if (scaleSpec.type === 'time' && (scaleSpec as TimeScaleFormatted).format !== 'native') {
return createDateNormalizer(scaleSpec)
} else {
return (x: number | string | Date) => x
const getParsedValue = (scaleSpec: ScaleLinearSpec | ScaleTimeSpec) => {
if (scaleSpec.type === 'time' && scaleSpec.format !== 'native') {
return createDateNormalizer(scaleSpec) as <T>(value: T) => T
}

return <T>(value: T) => value
}

export const computeOrdinalScale = ({
Expand Down Expand Up @@ -68,23 +65,32 @@ export const computeValueScale = <RawDatum>({
width: number
height: number
axis: 'x' | 'y'
getValue: (datum: RawDatum) => number
scale: Scale
getValue: (datum: RawDatum) => number | Date
scale: ScaleLinearSpec | ScaleTimeSpec
data: RawDatum[]
}) => {
const values = data.map(getValue)

if (scale.type === 'time') {
const series = [{ data: values.map(p => ({ data: { [axis]: p } })) }]
const series = [
{ data: values.map(value => ({ data: { x: null, y: null, [axis]: value } })) },
]
const axes = generateSeriesAxis(series, axis, scale)

return computeScale({ ...scale, axis }, { [axis]: axes }, width, height)
return computeScale(scale, axes, axis === 'x' ? width : height, axis) as ScaleTime<
Date | string
>
}

const min = Math.min(...values)
const max = Math.max(...values)
const min = Math.min(...(values as number[]))
const max = Math.max(...(values as number[]))

return computeScale({ ...scale, axis }, { [axis]: { min, max } }, width, height)
return computeScale(
scale,
{ all: values, min, max },
axis === 'x' ? width : height,
axis
) as ScaleLinear<number>
}

export const getSizeGenerator = <RawDatum>(size: SizeSpec<RawDatum>) => {
Expand Down Expand Up @@ -134,7 +140,7 @@ export const computeForces = <RawDatum>({
forceStrength,
}: {
axis: 'x' | 'y'
valueScale: ScaleLinear<number, number>
valueScale: ScaleLinear<number> | ScaleTime<string | Date>
ordinalScale: ScaleOrdinal<string, number>
spacing: number
forceStrength: number
Expand Down Expand Up @@ -176,24 +182,26 @@ export const computeNodes = <RawDatum>({
data: RawDatum[]
getId: (datum: RawDatum) => string
layout: 'vertical' | 'horizontal'
getValue: (datum: RawDatum) => number
valueScale: ScaleLinear<number, number>
getValue: (datum: RawDatum) => number | Date
valueScale: ScaleLinear<number> | ScaleTime<string | Date>
getGroup: (datum: RawDatum) => string
ordinalScale: ScaleOrdinal<string, number>
getSize: (datum: RawDatum) => number
forces: SimulationForces<RawDatum>
simulationIterations: number
valueScaleConfig: Scale
valueScaleConfig: ScaleLinearSpec | ScaleTimeSpec
}) => {
const config = {
horizontal: ['x', 'y'],
vertical: ['y', 'x'],
}

const parseValue = getParsedValue(valueScaleConfig)

const simulatedNodes: PreSimulationDatum<RawDatum>[] = data.map(d => ({
id: getId(d),
group: getGroup(d),
value: getParsedValue(valueScaleConfig)(getValue(d)),
value: parseValue(getValue(d)),
size: getSize(d),
data: { ...d },
}))
Expand Down
12 changes: 6 additions & 6 deletions packages/swarmplot/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useMemo } from 'react'
import { ScaleLinear, ScaleOrdinal } from 'd3-scale'
import { ScaleOrdinal } from 'd3-scale'
import { usePropertyAccessor, useValueFormatter } from '@nivo/core'
import { useOrdinalColorScale } from '@nivo/colors'
import { AnnotationMatcher, useAnnotations } from '@nivo/annotations'
import { Scale } from '@nivo/scales'
import { ScaleLinear, ScaleLinearSpec, ScaleTime, ScaleTimeSpec } from '@nivo/scales'
import {
computeValueScale,
computeOrdinalScale,
Expand All @@ -24,8 +24,8 @@ export const useValueScale = <RawDatum>({
width: number
height: number
axis: 'x' | 'y'
getValue: (datum: RawDatum) => number
scale: Scale
getValue: (datum: RawDatum) => number | Date
scale: ScaleLinearSpec | ScaleTimeSpec
data: RawDatum[]
}) =>
useMemo(
Expand Down Expand Up @@ -73,7 +73,7 @@ export const useForces = <RawDatum>({
forceStrength,
}: {
axis: 'x' | 'y'
valueScale: ScaleLinear<number, number>
valueScale: ScaleLinear<number> | ScaleTime<string | Date>
ordinalScale: ScaleOrdinal<string, number>
spacing: number
forceStrength: number
Expand Down Expand Up @@ -130,7 +130,7 @@ export const useSwarmPlot = <RawDatum>({
const axis = layout === 'horizontal' ? 'x' : 'y'

const getId = usePropertyAccessor<RawDatum, string>(id)
const getValue = usePropertyAccessor<RawDatum, number>(value)
const getValue = usePropertyAccessor(value)
const formatValue = useValueFormatter(valueFormat)
const getGroup = usePropertyAccessor<RawDatum, string>(groupBy)
const getSize = useSize<RawDatum>(size)
Expand Down
4 changes: 2 additions & 2 deletions packages/swarmplot/src/props.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Scale } from '@nivo/scales'
import { ScaleLinearSpec } from '@nivo/scales'
import { SwarmPlotLayerId } from './types'
import { SwarmPlotTooltip } from './SwarmPlotTooltip'

export const defaultProps = {
id: 'id',
value: 'value',
valueScale: { type: 'linear', min: 0, max: 'auto' } as Scale,
valueScale: { type: 'linear', min: 0, max: 'auto' } as ScaleLinearSpec,
// label: 'id',
groupBy: 'group',
size: 6,
Expand Down
16 changes: 8 additions & 8 deletions packages/swarmplot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { ForceX, ForceY, ForceCollide } from 'd3-force'
import { PropertyAccessor, ValueFormat, Theme, ModernMotionProps, Box, Margin } from '@nivo/core'
import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors'
import { GridValues, AxisProps } from '@nivo/axes'
import { Scale } from '@nivo/scales'
import { ScaleLinear, ScaleLinearSpec, ScaleTime, ScaleTimeSpec } from '@nivo/scales'
import { AnnotationMatcher } from '@nivo/annotations'
import { ScaleLinear, ScaleOrdinal } from 'd3-scale'
import { ScaleOrdinal } from 'd3-scale'

export interface ComputedDatum<RawDatum> {
id: string
index: number
group: string
value: number
value: number | Date
formattedValue: string
x: number
y: number
Expand All @@ -37,8 +37,8 @@ export type SwarmPlotLayerId = 'grid' | 'axes' | 'circles' | 'annotations' | 'me

export interface SwarmPlotCustomLayerProps<RawDatum> {
nodes: ComputedDatum<RawDatum>[]
xScale: ScaleLinear<number | string | Date, number> | ScaleOrdinal<string, number>
yScale: ScaleLinear<number | string | Date, number> | ScaleOrdinal<string, number>
xScale: ScaleLinear<number> | ScaleTime<string | Date> | ScaleOrdinal<string, number>
yScale: ScaleLinear<number> | ScaleTime<string | Date> | ScaleOrdinal<string, number>
innerWidth: number
innerHeight: number
outerWidth: number
Expand Down Expand Up @@ -81,9 +81,9 @@ export type SwarmPlotCommonProps<RawDatum> = {
groups: string[]
id: PropertyAccessor<RawDatum, string>
label: PropertyAccessor<ComputedDatum<RawDatum>, string>
value: PropertyAccessor<RawDatum, number>
valueScale: Scale
valueFormat: ValueFormat<number>
value: PropertyAccessor<RawDatum, number | Date>
valueScale: ScaleLinearSpec | ScaleTimeSpec
valueFormat: ValueFormat<number | Date>
groupBy: PropertyAccessor<RawDatum, string>
size: SizeSpec<RawDatum>
spacing: number
Expand Down

0 comments on commit 46ddb27

Please sign in to comment.