Skip to content

Commit

Permalink
feat(core): add typings for d3 curve factories
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Sep 7, 2021
1 parent 062ab4e commit bdb231c
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 27 deletions.
58 changes: 58 additions & 0 deletions packages/core/index.d.ts
@@ -1,5 +1,6 @@
import * as React from 'react'
import { Interpolation, SpringConfig } from '@react-spring/web'
import { CurveFactory } from 'd3-shape'

declare module '@nivo/core' {
export type DatumValue = string | number | Date
Expand Down Expand Up @@ -437,4 +438,61 @@ declare module '@nivo/core' {
props: CartesianMarkersProps<X, Y>
) => JSX.Element
export const CartesianMarkers: CartesianMarkersType

export type CurveFactoryId =
| 'basis'
| 'basisClosed'
| 'basisOpen'
| 'bundle'
| 'cardinal'
| 'cardinalClosed'
| 'cardinalOpen'
| 'catmullRom'
| 'catmullRomClosed'
| 'catmullRomOpen'
| 'linear'
| 'linearClosed'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'

// Curve factories compatible d3 line shape generator
export type LineCurveFactoryId =
| 'basis'
| 'cardinal'
| 'catmullRom'
| 'linear'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'

// Curve factories compatible d3 area shape generator
export type AreaCurveFactoryId =
| 'basis'
| 'cardinal'
| 'catmullRom'
| 'linear'
| 'monotoneX'
| 'monotoneY'
| 'natural'
| 'step'
| 'stepAfter'
| 'stepBefore'

export type ClosedCurveFactoryId =
| 'basisClosed'
| 'cardinalClosed'
| 'catmullRomClosed'
| 'linearClosed'
export const closedCurvePropKeys: ClosedCurveFactoryId[]

export const curveFromProp: (interpolation: CurveFactoryId) => CurveFactory

export const useCurveInterpolation: (interpolation: CurveFactoryId) => CurveFactory
}
3 changes: 2 additions & 1 deletion packages/core/package.json
Expand Up @@ -34,7 +34,8 @@
"resize-observer-polyfill": "^1.5.1"
},
"devDependencies": {
"@nivo/tooltip": "0.73.0"
"@nivo/tooltip": "0.73.0",
"@types/d3-shape": "^2.0.0"
},
"peerDependencies": {
"@nivo/tooltip": "0.73.0",
Expand Down
4 changes: 0 additions & 4 deletions packages/core/src/props/curve.js
Expand Up @@ -48,8 +48,6 @@ export const curvePropType = PropTypes.oneOf(curvePropKeys)

export const closedCurvePropKeys = curvePropKeys.filter(c => c.endsWith('Closed'))

export const closedCurvePropType = PropTypes.oneOf(closedCurvePropKeys)

// Safe curves to be used with d3 area shape generator
export const areaCurvePropKeys = without(
curvePropKeys,
Expand All @@ -63,8 +61,6 @@ export const areaCurvePropKeys = without(
'linearClosed'
)

export const areaCurvePropType = PropTypes.oneOf(areaCurvePropKeys)

// Safe curves to be used with d3 line shape generator
export const lineCurvePropKeys = without(
curvePropKeys,
Expand Down
4 changes: 2 additions & 2 deletions packages/radar/src/Radar.tsx
Expand Up @@ -66,7 +66,7 @@ const InnerRadar = <D extends Record<string, unknown>>({
centerX,
centerY,
angleStep,
curveInterpolator,
curveFactory,
legendData,
} = useRadar<D>({
data,
Expand Down Expand Up @@ -113,7 +113,7 @@ const InnerRadar = <D extends Record<string, unknown>>({
colorByKey={colorByKey}
radiusScale={radiusScale}
angleStep={angleStep}
curveInterpolator={curveInterpolator}
curveFactory={curveFactory}
borderWidth={borderWidth}
borderColor={borderColor}
fillOpacity={fillOpacity}
Expand Down
8 changes: 4 additions & 4 deletions packages/radar/src/RadarShapes.tsx
Expand Up @@ -12,7 +12,7 @@ interface RadarShapesProps<D extends Record<string, unknown>> {
colorByKey: Record<string | number, string>
radiusScale: ScaleLinear<number, number>
angleStep: number
curveInterpolator: CurveFactory
curveFactory: CurveFactory
borderWidth: RadarCommonProps<D>['borderWidth']
borderColor: RadarCommonProps<D>['borderColor']
fillOpacity: RadarCommonProps<D>['fillOpacity']
Expand All @@ -25,7 +25,7 @@ export const RadarShapes = <D extends Record<string, unknown>>({
colorByKey,
radiusScale,
angleStep,
curveInterpolator,
curveFactory,
borderWidth,
borderColor,
fillOpacity,
Expand All @@ -38,8 +38,8 @@ export const RadarShapes = <D extends Record<string, unknown>>({
return lineRadial<number>()
.radius(d => radiusScale(d))
.angle((_, i) => i * angleStep)
.curve(curveInterpolator)
}, [radiusScale, angleStep, curveInterpolator])
.curve(curveFactory)
}, [radiusScale, angleStep, curveFactory])

const { animate, config: springConfig } = useMotionConfig()
const animatedPath = useAnimatedPath(lineGenerator(data.map(d => d[key])))
Expand Down
3 changes: 2 additions & 1 deletion packages/radar/src/RadarTooltipItem.tsx
Expand Up @@ -38,10 +38,11 @@ export const RadarTooltipItem = <D extends Record<string, unknown>>({
key,
tooltipFormatter(datum[key], key),
])
// sorting won't work if values are formatted to string
rows.sort((a, b) => a[2] - b[2])
rows.reverse()

return <TableTooltip title={<strong>{index}</strong>} rows={rows} theme={theme} />
return <TableTooltip title={<strong>{index}</strong>} rows={rows} />
}, [datum, keys, index, colorByKey, theme, tooltipFormatter])
const showItemTooltip = useCallback(
event => {
Expand Down
10 changes: 3 additions & 7 deletions packages/radar/src/hooks.ts
@@ -1,10 +1,6 @@
import { useMemo } from 'react'
import { scaleLinear } from 'd3-scale'
import {
// @ts-ignore
useCurveInterpolation,
usePropertyAccessor,
} from '@nivo/core'
import { useCurveInterpolation, usePropertyAccessor } from '@nivo/core'
import { useOrdinalColorScale } from '@nivo/colors'
import { svgDefaultProps } from './props'
import { RadarCommonProps, RadarDataProps } from './types'
Expand Down Expand Up @@ -64,7 +60,7 @@ export const useRadar = <D extends Record<string, unknown>>({
}
}, [keys, indexBy, data, maxValue, width, height])

const curveInterpolator = useCurveInterpolation(curve)
const curveFactory = useCurveInterpolation(curve)

const legendData = keys.map(key => ({
id: key,
Expand All @@ -81,7 +77,7 @@ export const useRadar = <D extends Record<string, unknown>>({
centerX,
centerY,
angleStep,
curveInterpolator,
curveFactory,
legendData,
}
}
2 changes: 1 addition & 1 deletion packages/radar/src/props.ts
Expand Up @@ -6,7 +6,7 @@ export const svgDefaultProps = {

maxValue: 'auto' as const,

curve: 'linearClosed',
curve: 'linearClosed' as const,

borderWidth: 2,
borderColor: { from: 'color' },
Expand Down
3 changes: 2 additions & 1 deletion packages/radar/src/types.ts
Expand Up @@ -8,6 +8,7 @@ import {
ModernMotionProps,
PropertyAccessor,
ValueFormat,
ClosedCurveFactoryId,
} from '@nivo/core'
import { InheritedColorConfig, OrdinalColorScaleConfig } from '@nivo/colors'
import { LegendProps } from '@nivo/legends'
Expand Down Expand Up @@ -54,7 +55,7 @@ export interface RadarCommonProps<D extends Record<string, unknown>> {

margin: Box

curve: string // closedCurvePropType.isRequired,
curve: ClosedCurveFactoryId

gridLevels: number
gridShape: 'circular' | 'linear'
Expand Down
8 changes: 4 additions & 4 deletions packages/stream/src/hooks.ts
Expand Up @@ -5,8 +5,7 @@ import {
useTheme,
usePropertyAccessor,
useValueFormatter,
// @ts-ignore
curveFromProp,
useCurveInterpolation,
// @ts-ignore
stackOrderFromProp,
// @ts-ignore
Expand Down Expand Up @@ -57,14 +56,15 @@ export const useStream = <RawDatum extends StreamDatum>({
dotBorderColor?: StreamCommonProps<RawDatum>['dotBorderColor']
borderColor?: StreamCommonProps<RawDatum>['borderColor']
}) => {
const areaCurveFactory = useCurveInterpolation(curve)
const areaGenerator = useMemo(
() =>
area<StreamLayerDatum>()
.x(({ x }) => x)
.y0(({ y1 }) => y1)
.y1(({ y2 }) => y2)
.curve(curveFromProp(curve)),
[curve]
.curve(areaCurveFactory),
[areaCurveFactory]
)

const stack = useMemo(
Expand Down
1 change: 0 additions & 1 deletion website/src/data/components/radar/props.ts
@@ -1,4 +1,3 @@
// @ts-ignore
import { closedCurvePropKeys } from '@nivo/core'
import { svgDefaultProps as defaults, RadarDots } from '@nivo/radar'
import { themeProperty, motionProperties, groupProperties } from '../../../lib/componentProperties'
Expand Down
3 changes: 2 additions & 1 deletion website/src/pages/radar/index.tsx
@@ -1,6 +1,6 @@
import React from 'react'
import { generateWinesTastes } from '@nivo/generators'
import { ResponsiveRadar } from '@nivo/radar'
import { ResponsiveRadar, svgDefaultProps } from '@nivo/radar'
import { ComponentTemplate } from '../../components/components/ComponentTemplate'
import meta from '../../data/components/radar/meta.yml'
import mapper from '../../data/components/radar/mapper'
Expand Down Expand Up @@ -79,6 +79,7 @@ const Radar = () => (
currentFlavor="svg"
properties={groups}
initialProperties={initialProperties}
defaultProperties={svgDefaultProps}
propertiesMapper={mapper}
codePropertiesMapper={(properties, data) => ({
keys: data.keys,
Expand Down

0 comments on commit bdb231c

Please sign in to comment.