Skip to content

Commit

Permalink
feat(arcs): provide generic arc labels/arc link labels layer
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed Dec 18, 2020
1 parent 08b75bf commit 547b635
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 176 deletions.
Expand Up @@ -7,35 +7,38 @@ import {
useTheme,
} from '@nivo/core'
import { useInheritedColor } from '@nivo/colors'
import { useArcCentersTransition } from '@nivo/arcs'
import { CompletePieSvgProps, ComputedDatum } from './types'
import { useArcCentersTransition } from '../centers'
import { ArcTransitionMode } from '../arcTransitionMode'
import { DatumWithArcAndColor } from '../types'
import { ArcLabelsProps } from './props'

const sliceStyle: CSSProperties = {
pointerEvents: 'none',
}

interface SliceLabelsProps<RawDatum> {
interface ArcLabelsLayerProps<Datum extends DatumWithArcAndColor> {
center: [number, number]
data: ComputedDatum<RawDatum>[]
label: CompletePieSvgProps<RawDatum>['arcLabel']
radiusOffset: CompletePieSvgProps<RawDatum>['arcLabelsRadiusOffset']
skipAngle: CompletePieSvgProps<RawDatum>['arcLabelsSkipAngle']
textColor: CompletePieSvgProps<RawDatum>['arcLabelsTextColor']
transitionMode: CompletePieSvgProps<RawDatum>['transitionMode']
data: Datum[]
// CompletePieSvgProps<RawDatum>['arcLabel']
label: any
radiusOffset: ArcLabelsProps<Datum, Datum>['arcLabelsRadiusOffset']
skipAngle: ArcLabelsProps<Datum, Datum>['arcLabelsSkipAngle']
textColor: ArcLabelsProps<Datum, Datum>['arcLabelsTextColor']
transitionMode: ArcTransitionMode
}

export const SliceLabels = <RawDatum,>({
export const ArcLabelsLayer = <Datum extends DatumWithArcAndColor>({
center,
data,
transitionMode,
label: labelAccessor,
radiusOffset,
skipAngle,
textColor,
}: SliceLabelsProps<RawDatum>) => {
}: ArcLabelsLayerProps<Datum>) => {
const getLabel = useMemo(() => getLabelGenerator(labelAccessor), [labelAccessor])
const theme = useTheme()
const getTextColor = useInheritedColor<ComputedDatum<RawDatum>>(textColor, theme)
const getTextColor = useInheritedColor<Datum>(textColor, theme)

const filteredData = useMemo(
() =>
Expand All @@ -48,7 +51,7 @@ export const SliceLabels = <RawDatum,>({
[data, skipAngle]
)

const { transition, interpolate } = useArcCentersTransition<ComputedDatum<RawDatum>>(
const { transition, interpolate } = useArcCentersTransition<Datum>(
filteredData,
radiusOffset,
transitionMode
Expand Down
1 change: 1 addition & 0 deletions packages/arcs/src/arc_labels/index.ts
@@ -1,2 +1,3 @@
export * from './ArcLabelsLayer'
export * from './props'
export * from './useArcLabels'
@@ -1,23 +1,24 @@
import React from 'react'
import { animated } from 'react-spring'
import { useArcLinkLabelsTransition } from '@nivo/arcs'
import { ComputedDatum, CompletePieSvgProps } from './types'
import { useArcLinkLabelsTransition } from './useArcLinkLabelsTransition'
import { DatumWithArcAndColor } from '../types'
import { ArcLinkLabelsProps } from './props'

interface RadialLabelsProps<RawDatum> {
interface ArcLinkLabelsLayerProps<Datum extends DatumWithArcAndColor> {
center: [number, number]
data: ComputedDatum<RawDatum>[]
label: CompletePieSvgProps<RawDatum>['radialLabel']
skipAngle: CompletePieSvgProps<RawDatum>['radialLabelsSkipAngle']
offset: CompletePieSvgProps<RawDatum>['radialLabelsLinkOffset']
diagonalLength: CompletePieSvgProps<RawDatum>['radialLabelsLinkDiagonalLength']
straightLength: CompletePieSvgProps<RawDatum>['radialLabelsLinkHorizontalLength']
strokeWidth: CompletePieSvgProps<RawDatum>['radialLabelsLinkStrokeWidth']
textOffset: CompletePieSvgProps<RawDatum>['radialLabelsTextXOffset']
textColor: CompletePieSvgProps<RawDatum>['radialLabelsTextColor']
linkColor: CompletePieSvgProps<RawDatum>['radialLabelsLinkColor']
data: Datum[]
label: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabel']
skipAngle: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsSkipAngle']
offset: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsOffset']
diagonalLength: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsDiagonalLength']
straightLength: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsStraightLength']
strokeWidth: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsThickness']
textOffset: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsTextOffset']
textColor: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsTextColor']
linkColor: ArcLinkLabelsProps<Datum, Datum>['arcLinkLabelsColor']
}

export const RadialLabels = <RawDatum,>({
export const ArcLinkLabelsLayer = <Datum extends DatumWithArcAndColor>({
center,
data,
label,
Expand All @@ -29,8 +30,8 @@ export const RadialLabels = <RawDatum,>({
textOffset,
textColor,
linkColor,
}: RadialLabelsProps<RawDatum>) => {
const { transition, interpolateLink } = useArcLinkLabelsTransition<ComputedDatum<RawDatum>>({
}: ArcLinkLabelsLayerProps<Datum>) => {
const { transition, interpolateLink } = useArcLinkLabelsTransition<Datum>({
data,
label,
skipAngle,
Expand Down
2 changes: 2 additions & 0 deletions packages/arcs/src/arc_link_labels/index.ts
@@ -1 +1,3 @@
export * from './ArcLinkLabelsLayer'
export * from './props'
export * from './useArcLinkLabelsTransition'
15 changes: 15 additions & 0 deletions packages/arcs/src/arc_link_labels/props.ts
@@ -0,0 +1,15 @@
import { InheritedColorConfig } from '@nivo/colors'

// @ts-ignore
export interface ArcLinkLabelsProps<RawDatum, Datum> {
// string | LabelAccessorFunction<RawDatum>
arcLinkLabel: any
arcLinkLabelsSkipAngle: number
arcLinkLabelsTextOffset: number
arcLinkLabelsTextColor: InheritedColorConfig<Datum>
arcLinkLabelsOffset: number
arcLinkLabelsDiagonalLength: number
arcLinkLabelsStraightLength: number
arcLinkLabelsThickness: number
arcLinkLabelsColor: InheritedColorConfig<Datum>
}
69 changes: 34 additions & 35 deletions packages/pie/src/Pie.tsx
Expand Up @@ -6,9 +6,8 @@ import {
Container,
SvgWrapper,
} from '@nivo/core'
import { ArcLabelsLayer, ArcLinkLabelsLayer } from '@nivo/arcs'
import { InheritedColorConfig } from '@nivo/colors'
import { RadialLabels } from './RadialLabels'
import { SliceLabels } from './SliceLabels'
import PieLegends from './PieLegends'
import { useNormalizedData, usePieFromBox, usePieLayerContext } from './hooks'
import { ComputedDatum, PieLayer, PieSvgProps, PieLayerId } from './types'
Expand Down Expand Up @@ -43,25 +42,25 @@ const InnerPie = <RawDatum,>({
borderWidth = defaultProps.borderWidth,
borderColor = defaultProps.borderColor as InheritedColorConfig<ComputedDatum<RawDatum>>,

// radial labels
radialLabel = defaultProps.radialLabel,
enableRadialLabels = defaultProps.enableRadialLabels,
radialLabelsSkipAngle = defaultProps.radialLabelsSkipAngle,
radialLabelsLinkOffset = defaultProps.radialLabelsLinkOffset,
radialLabelsLinkDiagonalLength = defaultProps.radialLabelsLinkDiagonalLength,
radialLabelsLinkHorizontalLength = defaultProps.radialLabelsLinkHorizontalLength,
radialLabelsLinkStrokeWidth = defaultProps.radialLabelsLinkStrokeWidth,
radialLabelsTextXOffset = defaultProps.radialLabelsTextXOffset,
radialLabelsTextColor = defaultProps.radialLabelsTextColor,
radialLabelsLinkColor = defaultProps.radialLabelsLinkColor,

// arc labels
enableArcLabels = defaultProps.enableArcLabels,
arcLabel = defaultProps.arcLabel,
arcLabelsSkipAngle = defaultProps.arcLabelsSkipAngle,
arcLabelsTextColor = defaultProps.arcLabelsTextColor,
arcLabelsRadiusOffset = defaultProps.arcLabelsRadiusOffset,

// arc link labels
enableArcLinkLabels = defaultProps.enableArcLinkLabels,
arcLinkLabel = defaultProps.arcLinkLabel,
arcLinkLabelsSkipAngle = defaultProps.arcLinkLabelsSkipAngle,
arcLinkLabelsOffset = defaultProps.arcLinkLabelsOffset,
arcLinkLabelsDiagonalLength = defaultProps.arcLinkLabelsDiagonalLength,
arcLinkLabelsStraightLength = defaultProps.arcLinkLabelsStraightLength,
arcLinkLabelsThickness = defaultProps.arcLinkLabelsThickness,
arcLinkLabelsTextOffset = defaultProps.arcLinkLabelsTextOffset,
arcLinkLabelsTextColor = defaultProps.arcLinkLabelsTextColor,
arcLinkLabelsColor = defaultProps.arcLinkLabelsColor,

// styling
defs = defaultProps.defs,
fill = defaultProps.fill,
Expand Down Expand Up @@ -119,12 +118,31 @@ const InnerPie = <RawDatum,>({
const boundDefs = bindDefs(defs, dataWithArc, fill)

const layerById: Record<PieLayerId, ReactNode> = {
arcLinkLabels: null,
arcs: null,
radialLabels: null,
arcLabels: null,
legends: null,
}

if (enableArcLinkLabels && layers.includes('arcLinkLabels')) {
layerById.arcLinkLabels = (
<ArcLinkLabelsLayer<ComputedDatum<RawDatum>>
key="arcLinkLabels"
center={[centerX, centerY]}
data={dataWithArc}
label={arcLinkLabel}
skipAngle={arcLinkLabelsSkipAngle}
offset={arcLinkLabelsOffset}
diagonalLength={arcLinkLabelsDiagonalLength}
straightLength={arcLinkLabelsStraightLength}
strokeWidth={arcLinkLabelsThickness}
textOffset={arcLinkLabelsTextOffset}
textColor={arcLinkLabelsTextColor}
linkColor={arcLinkLabelsColor}
/>
)
}

if (layers.includes('arcs')) {
layerById.arcs = (
<Arcs<RawDatum>
Expand All @@ -146,28 +164,9 @@ const InnerPie = <RawDatum,>({
)
}

if (enableRadialLabels && layers.includes('radialLabels')) {
layerById.radialLabels = (
<RadialLabels<RawDatum>
key="radialLabels"
center={[centerX, centerY]}
data={dataWithArc}
label={radialLabel}
skipAngle={radialLabelsSkipAngle}
offset={radialLabelsLinkOffset}
diagonalLength={radialLabelsLinkDiagonalLength}
straightLength={radialLabelsLinkHorizontalLength}
strokeWidth={radialLabelsLinkStrokeWidth}
textOffset={radialLabelsTextXOffset}
textColor={radialLabelsTextColor}
linkColor={radialLabelsLinkColor}
/>
)
}

if (enableArcLabels && layers.includes('arcLabels')) {
layerById.arcLabels = (
<SliceLabels<RawDatum>
<ArcLabelsLayer<ComputedDatum<RawDatum>>
key="arcLabels"
center={[centerX, centerY]}
data={dataWithArc}
Expand Down
59 changes: 30 additions & 29 deletions packages/pie/src/PieCanvas.tsx
Expand Up @@ -49,25 +49,25 @@ const InnerPieCanvas = <RawDatum,>({
borderWidth = defaultProps.borderWidth,
borderColor = defaultProps.borderColor as InheritedColorConfig<ComputedDatum<RawDatum>>,

// radial labels
radialLabel = defaultProps.radialLabel,
enableRadialLabels = defaultProps.enableRadialLabels,
radialLabelsSkipAngle = defaultProps.radialLabelsSkipAngle,
radialLabelsLinkOffset = defaultProps.radialLabelsLinkOffset,
radialLabelsLinkDiagonalLength = defaultProps.radialLabelsLinkDiagonalLength,
radialLabelsLinkHorizontalLength = defaultProps.radialLabelsLinkHorizontalLength,
radialLabelsLinkStrokeWidth = defaultProps.radialLabelsLinkStrokeWidth,
radialLabelsTextXOffset = defaultProps.radialLabelsTextXOffset,
radialLabelsTextColor = defaultProps.radialLabelsTextColor,
radialLabelsLinkColor = defaultProps.radialLabelsLinkColor,

// arc labels
enableArcLabels = defaultProps.enableArcLabels,
arcLabel = defaultProps.arcLabel,
arcLabelsSkipAngle = defaultProps.arcLabelsSkipAngle,
arcLabelsTextColor = defaultProps.arcLabelsTextColor,
arcLabelsRadiusOffset = defaultProps.arcLabelsRadiusOffset,

// arc link labels
enableArcLinkLabels = defaultProps.enableArcLinkLabels,
arcLinkLabel = defaultProps.arcLinkLabel,
arcLinkLabelsSkipAngle = defaultProps.arcLinkLabelsSkipAngle,
arcLinkLabelsOffset = defaultProps.arcLinkLabelsOffset,
arcLinkLabelsDiagonalLength = defaultProps.arcLinkLabelsDiagonalLength,
arcLinkLabelsStraightLength = defaultProps.arcLinkLabelsStraightLength,
arcLinkLabelsThickness = defaultProps.arcLinkLabelsThickness,
arcLinkLabelsTextOffset = defaultProps.arcLinkLabelsTextOffset,
arcLinkLabelsTextColor = defaultProps.arcLinkLabelsTextColor,
arcLinkLabelsColor = defaultProps.arcLinkLabelsColor,

// interactivity
isInteractive = defaultProps.isInteractive,
onClick,
Expand Down Expand Up @@ -118,18 +118,6 @@ const InnerPieCanvas = <RawDatum,>({

const getBorderColor = useInheritedColor<ComputedDatum<RawDatum>>(borderColor, theme)

const radialLabels = useArcLinkLabels<ComputedDatum<RawDatum>>({
data: dataWithArc,
skipAngle: radialLabelsSkipAngle,
offset: radialLabelsLinkOffset,
diagonalLength: radialLabelsLinkDiagonalLength,
straightLength: radialLabelsLinkHorizontalLength,
label: radialLabel,
linkColor: radialLabelsLinkColor,
textOffset: radialLabelsTextXOffset,
textColor: radialLabelsTextColor,
})

const arcLabels = useArcLabels<ComputedDatum<RawDatum>>({
data: dataWithArc,
label: arcLabel,
Expand All @@ -138,6 +126,18 @@ const InnerPieCanvas = <RawDatum,>({
textColor: arcLabelsTextColor,
})

const arcLinkLabels = useArcLinkLabels<ComputedDatum<RawDatum>>({
data: dataWithArc,
skipAngle: arcLinkLabelsSkipAngle,
offset: arcLinkLabelsOffset,
diagonalLength: arcLinkLabelsDiagonalLength,
straightLength: arcLinkLabelsStraightLength,
label: arcLinkLabel,
linkColor: arcLinkLabelsColor,
textOffset: arcLinkLabelsTextOffset,
textColor: arcLinkLabelsTextColor,
})

useEffect(() => {
if (!canvasEl.current) return

Expand Down Expand Up @@ -174,12 +174,12 @@ const InnerPieCanvas = <RawDatum,>({
}
})

if (enableRadialLabels === true) {
if (enableArcLinkLabels === true) {
drawCanvasArcLinkLabels<ComputedDatum<RawDatum>>(
ctx,
radialLabels,
arcLinkLabels,
theme,
radialLabelsLinkStrokeWidth
arcLinkLabelsThickness
)
}

Expand Down Expand Up @@ -213,10 +213,11 @@ const InnerPieCanvas = <RawDatum,>({
arcGenerator,
dataWithArc,
getBorderColor,
enableRadialLabels,
radialLabels,
enableArcLabels,
arcLabels,
enableArcLinkLabels,
arcLinkLabels,
arcLinkLabelsThickness,
legends,
theme,
])
Expand Down
26 changes: 13 additions & 13 deletions packages/pie/src/props.ts
Expand Up @@ -10,7 +10,7 @@ export const defaultProps = {
padAngle: 0,
cornerRadius: 0,

layers: ['radialLabels', 'arcs', 'arcLabels', 'legends'],
layers: ['arcLinkLabels', 'arcs', 'arcLabels', 'legends'],

// layout
startAngle: 0,
Expand All @@ -26,25 +26,25 @@ export const defaultProps = {
modifiers: [['darker', 1]],
},

// radial labels
radialLabel: 'id',
enableRadialLabels: true,
radialLabelsSkipAngle: 0,
radialLabelsLinkOffset: 0,
radialLabelsLinkDiagonalLength: 16,
radialLabelsLinkHorizontalLength: 24,
radialLabelsLinkStrokeWidth: 1,
radialLabelsTextXOffset: 6,
radialLabelsTextColor: { theme: 'labels.text.fill' },
radialLabelsLinkColor: { theme: 'axis.ticks.line.stroke' },

// arc labels
enableArcLabels: true,
arcLabel: 'formattedValue',
arcLabelsSkipAngle: 0,
arcLabelsRadiusOffset: 0.5,
arcLabelsTextColor: { theme: 'labels.text.fill' },

// arc link labels
enableArcLinkLabels: true,
arcLinkLabel: 'id',
arcLinkLabelsSkipAngle: 0,
arcLinkLabelsOffset: 0,
arcLinkLabelsDiagonalLength: 16,
arcLinkLabelsStraightLength: 24,
arcLinkLabelsThickness: 1,
arcLinkLabelsTextOffset: 6,
arcLinkLabelsTextColor: { theme: 'labels.text.fill' },
arcLinkLabelsColor: { theme: 'axis.ticks.line.stroke' },

colors: ({ scheme: 'nivo' } as unknown) as OrdinalColorScaleConfig,
defs: [],
fill: [],
Expand Down

0 comments on commit 547b635

Please sign in to comment.