Skip to content

Commit

Permalink
feat(line): add ability to toggle serie via legend item (#1555)
Browse files Browse the repository at this point in the history
  • Loading branch information
wyze authored Jun 2, 2021
1 parent 4e8280d commit 463d380
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 29 deletions.
11 changes: 11 additions & 0 deletions packages/core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ declare module '@nivo/core' {
line: Partial<React.CSSProperties>
}
legends: {
hidden: {
symbol: Partial<{
fill: string
opacity: number
}>
text: Partial<React.CSSProperties>
}
text: Partial<React.CSSProperties>
}
labels: {
Expand Down Expand Up @@ -129,6 +136,10 @@ declare module '@nivo/core' {
line: Partial<CompleteTheme['grid']['line']>
}>
legends: Partial<{
hidden: Partial<{
symbol: CompleteTheme['legends']['hidden']['symbol']
text: CompleteTheme['legends']['hidden']['text']
}>
text: Partial<CompleteTheme['legends']['text']>
}>
labels: Partial<{
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/theming/defaultTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ export const defaultTheme = {
},
},
legends: {
hidden: {
symbol: {
fill: '#333333',
opacity: 0.6,
},
text: {
fill: '#333333',
opacity: 0.6,
},
},
text: {},
},
labels: {
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/theming/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export const gridThemePropType = PropTypes.shape({
})

export const legendsThemePropType = PropTypes.shape({
hidden: PropTypes.shape({
symbol: PropTypes.shape({
fill: PropTypes.string.isRequired,
opacity: PropTypes.number,
}).isRequired,
text: PropTypes.shape({ ...textProps, opacity: PropTypes.number }).isRequired,
}).isRequired,
text: PropTypes.shape({ ...textProps }).isRequired,
})

Expand Down
2 changes: 2 additions & 0 deletions packages/legends/src/svg/BoxLegendSvg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const BoxLegendSvg = ({
onClick,
onMouseEnter,
onMouseLeave,
toggleSerie,

effects,
}: BoxLegendSvgProps) => {
Expand Down Expand Up @@ -78,6 +79,7 @@ export const BoxLegendSvg = ({
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
toggleSerie={typeof toggleSerie === 'boolean' ? undefined : toggleSerie}
/>
)
}
2 changes: 2 additions & 0 deletions packages/legends/src/svg/LegendSvg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const LegendSvg = ({
onClick,
onMouseEnter,
onMouseLeave,
toggleSerie,
}: LegendSvgProps) => {
const { padding } = computeDimensions({
itemCount: data.length,
Expand Down Expand Up @@ -67,6 +68,7 @@ export const LegendSvg = ({
onClick={onClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
toggleSerie={toggleSerie}
/>
))}
</g>
Expand Down
6 changes: 5 additions & 1 deletion packages/legends/src/svg/LegendSvgItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const LegendSvgItem = ({
onClick,
onMouseEnter,
onMouseLeave,
toggleSerie,

effects,
}: LegendSvgItemProps) => {
Expand Down Expand Up @@ -93,7 +94,7 @@ export const LegendSvgItem = ({
height,
})

const isInteractive = [onClick, onMouseEnter, onMouseLeave].some(
const isInteractive = [onClick, onMouseEnter, onMouseLeave, toggleSerie].some(
handler => handler !== undefined
)

Expand All @@ -115,6 +116,7 @@ export const LegendSvgItem = ({
}}
onClick={event => {
onClick?.(data, event)
toggleSerie?.(data.id)
}}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
Expand All @@ -127,6 +129,7 @@ export const LegendSvgItem = ({
fill: data.fill ?? data.color ?? 'black',
borderWidth: style.symbolBorderWidth ?? symbolBorderWidth,
borderColor: style.symbolBorderColor ?? symbolBorderColor,
...(data.hidden ? theme.legends.hidden.symbol : undefined),
})}
<text
textAnchor={labelAnchor}
Expand All @@ -136,6 +139,7 @@ export const LegendSvgItem = ({
dominantBaseline: labelAlignment,
pointerEvents: 'none',
userSelect: 'none',
...(data.hidden ? theme.legends.hidden.text : undefined),
}}
x={labelX}
y={labelY}
Expand Down
2 changes: 2 additions & 0 deletions packages/legends/src/svg/symbols/SymbolCircle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const SymbolCircle = ({
y,
size,
fill,
opacity = 1,
borderWidth = 0,
borderColor = 'transparent',
}: SymbolProps) => {
Expand All @@ -15,6 +16,7 @@ export const SymbolCircle = ({
cx={x + size / 2}
cy={y + size / 2}
fill={fill}
opacity={opacity}
strokeWidth={borderWidth}
stroke={borderColor}
style={{
Expand Down
2 changes: 2 additions & 0 deletions packages/legends/src/svg/symbols/SymbolDiamond.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const SymbolDiamond = ({
y,
size,
fill,
opacity = 1,
borderWidth = 0,
borderColor = 'transparent',
}: SymbolProps) => {
Expand All @@ -20,6 +21,7 @@ export const SymbolDiamond = ({
L${size / 2} 0
`}
fill={fill}
opacity={opacity}
strokeWidth={borderWidth}
stroke={borderColor}
style={{
Expand Down
2 changes: 2 additions & 0 deletions packages/legends/src/svg/symbols/SymbolSquare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const SymbolSquare = ({
y,
size,
fill,
opacity = 1,
borderWidth = 0,
borderColor = 'transparent',
}: SymbolProps) => {
Expand All @@ -14,6 +15,7 @@ export const SymbolSquare = ({
x={x}
y={y}
fill={fill}
opacity={opacity}
strokeWidth={borderWidth}
stroke={borderColor}
width={size}
Expand Down
2 changes: 2 additions & 0 deletions packages/legends/src/svg/symbols/SymbolTriangle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const SymbolTriangle = ({
y,
size,
fill,
opacity = 1,
borderWidth = 0,
borderColor = 'transparent',
}: SymbolProps) => {
Expand All @@ -19,6 +20,7 @@ export const SymbolTriangle = ({
L${size / 2} 0
`}
fill={fill}
opacity={opacity}
strokeWidth={borderWidth}
stroke={borderColor}
style={{
Expand Down
1 change: 1 addition & 0 deletions packages/legends/src/svg/symbols/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type SymbolProps = {
y: number
size: number
fill: string
opacity?: number
borderWidth?: number
borderColor?: string
}
16 changes: 12 additions & 4 deletions packages/legends/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ type InteractivityProps = Partial<
Record<
'onClick' | 'onMouseEnter' | 'onMouseLeave',
(datum: Datum, event: React.MouseEvent<SVGRectElement>) => void
>
> & {
toggleSerie: (id: Datum['id']) => void
}
>

export type LegendAnchor =
Expand All @@ -56,6 +58,7 @@ export type LegendItemDirection =
export type Datum = {
id: string | number
label: string | number
hidden?: boolean
color?: string
fill?: string
}
Expand All @@ -81,15 +84,20 @@ export type LegendProps = {
translateX?: number
translateY?: number
anchor: LegendAnchor
toggleSerie?: boolean
} & CommonLegendProps &
BoxLegendSymbolProps &
InteractivityProps
Omit<InteractivityProps, 'toggleSerie'>

export type BoxLegendSvgProps = {
containerWidth: number
containerHeight: number
} & LegendProps &
Required<Pick<LegendProps, 'data'>>
} & Omit<LegendProps, 'toggleSerie'> &
Required<Pick<LegendProps, 'data'>> &
Omit<InteractivityProps, 'toggleSerie'> &
Partial<{
toggleSerie: boolean | InteractivityProps['toggleSerie']
}>

export type LegendSvgProps = {
x: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ exports[`should support bottom-to-top direction 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -81,6 +82,7 @@ exports[`should support bottom-to-top direction justified 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -137,6 +139,7 @@ exports[`should support left-to-right direction 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -193,6 +196,7 @@ exports[`should support left-to-right direction justified 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -249,6 +253,7 @@ exports[`should support right-to-left direction 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -305,6 +310,7 @@ exports[`should support right-to-left direction justified 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -361,6 +367,7 @@ exports[`should support top-to-bottom direction 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down Expand Up @@ -417,6 +424,7 @@ exports[`should support top-to-bottom direction justified 1`] = `
<rect
fill="red"
height={16}
opacity={1}
stroke="transparent"
strokeWidth={0}
style={
Expand Down
25 changes: 12 additions & 13 deletions packages/line/src/Line.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,17 @@ const Line = props => {
partialMargin
)

const { lineGenerator, areaGenerator, series, xScale, yScale, slices, points } = useLine({
const {
legendData,
toggleSerie,
lineGenerator,
areaGenerator,
series,
xScale,
yScale,
slices,
points,
} = useLine({
data,
xScale: xScaleSpec,
xFormat,
Expand All @@ -126,18 +136,6 @@ const Line = props => {
const [currentPoint, setCurrentPoint] = useState(null)
const [currentSlice, setCurrentSlice] = useState(null)

const legendData = useMemo(
() =>
series
.map(line => ({
id: line.id,
label: line.id,
color: line.color,
}))
.reverse(),
[series]
)

const layerById = {
grid: (
<Grid
Expand Down Expand Up @@ -192,6 +190,7 @@ const Line = props => {
containerHeight={innerHeight}
data={legend.data || legendData}
theme={theme}
toggleSerie={legend.toggleSerie ? toggleSerie : undefined}
/>
)),
}
Expand Down
Loading

0 comments on commit 463d380

Please sign in to comment.