From 0f5ac2fec4da359ec2baf8a8daf8a40c0ff0230d Mon Sep 17 00:00:00 2001 From: Carlos Catalan Date: Tue, 23 Jul 2024 17:59:35 +0800 Subject: [PATCH] (feat)Line: add support for hiding line charts by default (#2540) * (feat)Line: add support for hiding line charts by default * add unit test * add unit test for testing hiding multiple series by default * add to documentation * add to types and update props * use make fmt --------- Co-authored-by: Carlos Catalan --- packages/line/index.d.ts | 1 + packages/line/src/Line.js | 2 + packages/line/src/hooks.js | 3 +- packages/line/src/props.js | 1 + packages/line/tests/Line.test.js | 97 +++++++++++++++++++++++ storybook/stories/line/Line.stories.tsx | 11 +++ website/src/data/components/line/props.ts | 8 ++ 7 files changed, 122 insertions(+), 1 deletion(-) diff --git a/packages/line/index.d.ts b/packages/line/index.d.ts index fd9b157d56..aed145da8f 100644 --- a/packages/line/index.d.ts +++ b/packages/line/index.d.ts @@ -193,6 +193,7 @@ export interface LineProps { debugMesh?: boolean enableSlices?: 'x' | 'y' | false + initialHiddenIds?: string[] debugSlices?: boolean sliceTooltip?: SliceTooltip diff --git a/packages/line/src/Line.js b/packages/line/src/Line.js index 934e9d2461..7a3bdee72a 100644 --- a/packages/line/src/Line.js +++ b/packages/line/src/Line.js @@ -107,6 +107,7 @@ const Line = props => { enableTouchCrosshair = false, role = 'img', + initialHiddenIds = [], } = props const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions( @@ -139,6 +140,7 @@ const Line = props => { pointColor, pointBorderColor, enableSlices, + initialHiddenIds, }) const theme = useTheme() diff --git a/packages/line/src/hooks.js b/packages/line/src/hooks.js index e13027d235..38cd2d31c4 100644 --- a/packages/line/src/hooks.js +++ b/packages/line/src/hooks.js @@ -148,6 +148,7 @@ export const useLine = ({ pointColor = LineDefaultProps.pointColor, pointBorderColor = LineDefaultProps.pointBorderColor, enableSlices = LineDefaultProps.enableSlicesTooltip, + initialHiddenIds = LineDefaultProps.initialHiddenIds, }) => { const [componentId] = useState(uniqueId(LINE_UNIQUE_ID_PREFIX)) const formatX = useValueFormatter(xFormat) @@ -156,7 +157,7 @@ export const useLine = ({ const theme = useTheme() const getPointColor = useInheritedColor(pointColor, theme) const getPointBorderColor = useInheritedColor(pointBorderColor, theme) - const [hiddenIds, setHiddenIds] = useState([]) + const [hiddenIds, setHiddenIds] = useState(initialHiddenIds ?? []) const { xScale, diff --git a/packages/line/src/props.js b/packages/line/src/props.js index 58e229653a..34f747b4e9 100644 --- a/packages/line/src/props.js +++ b/packages/line/src/props.js @@ -67,6 +67,7 @@ export const LineDefaultProps = { defs: [], fill: [], role: 'img', + initialHiddenIds: [], } export const LineCanvasDefaultProps = { diff --git a/packages/line/tests/Line.test.js b/packages/line/tests/Line.test.js index f46777cbb4..b6c133d7ad 100644 --- a/packages/line/tests/Line.test.js +++ b/packages/line/tests/Line.test.js @@ -1,6 +1,7 @@ import { mount } from 'enzyme' import { Axis } from '@nivo/axes' import Line from '../src/Line' +import Lines from '../src/Lines' import { LINE_UNIQUE_ID_PREFIX } from '../src/hooks' import SlicesItem from '../src/SlicesItem' import renderer from 'react-test-renderer' @@ -89,6 +90,102 @@ it('should create slice for each x value', () => { expect(slices.at(4).prop('slice').x).toBe(500) }) +it('should hide single line charts by default given their id', () => { + const data = [ + { + id: 'A', + data: [ + { x: 0, y: 3 }, + { x: 1, y: 7 }, + { x: 2, y: 11 }, + { x: 3, y: 9 }, + { x: 4, y: 8 }, + ], + }, + { + id: 'B', + data: [ + { x: 0, y: 4 }, + { x: 2, y: 8 }, + { x: 3, y: 12 }, + { x: 4, y: 10 }, + { x: 5, y: 9 }, + ], + }, + { + id: 'C', + data: [ + { x: 0, y: 5 }, + { x: 2, y: 9 }, + { x: 3, y: 13 }, + { x: 4, y: 11 }, + { x: 5, y: 10 }, + ], + }, + ] + const wrapper = mount( + + ) + + const lines = wrapper.find(Lines) + expect(lines).toHaveLength(1) +}) + +it('should hide multiple line charts by default given their ids', () => { + const data = [ + { + id: 'A', + data: [ + { x: 0, y: 3 }, + { x: 1, y: 7 }, + { x: 2, y: 11 }, + { x: 3, y: 9 }, + { x: 4, y: 8 }, + ], + }, + { + id: 'B', + data: [ + { x: 0, y: 4 }, + { x: 2, y: 8 }, + { x: 3, y: 12 }, + { x: 4, y: 10 }, + { x: 5, y: 9 }, + ], + }, + { + id: 'C', + data: [ + { x: 0, y: 5 }, + { x: 2, y: 9 }, + { x: 3, y: 13 }, + { x: 4, y: 11 }, + { x: 5, y: 10 }, + ], + }, + ] + const wrapper = mount( + + ) + + const lines = wrapper.find(Lines) + expect(lines).toHaveLength(1) +}) + it('should have left and bottom axis by default', () => { const data = [ { diff --git a/storybook/stories/line/Line.stories.tsx b/storybook/stories/line/Line.stories.tsx index 41fbedefed..27d8cb3550 100644 --- a/storybook/stories/line/Line.stories.tsx +++ b/storybook/stories/line/Line.stories.tsx @@ -36,6 +36,7 @@ const commonProperties = { animate: true, enableTouchCrosshair: true, enableSlices: 'x', + initialHiddenIds: ['cognac'], } const CustomSymbol = ({ size, color, borderWidth, borderColor }) => ( @@ -64,6 +65,16 @@ export const StackedLines: Story = { stacked: true, }} curve={args.curve} + legends={[ + { + anchor: 'bottom', + direction: 'row', + itemHeight: 20, + itemWidth: 80, + toggleSerie: true, + translateY: 50, + }, + ]} /> ), } diff --git a/website/src/data/components/line/props.ts b/website/src/data/components/line/props.ts index 1b4d8dc58d..2462e1b65f 100644 --- a/website/src/data/components/line/props.ts +++ b/website/src/data/components/line/props.ts @@ -541,6 +541,14 @@ const props: ChartProperty[] = [ defaultValue: defaults.enableTouchCrosshair, control: { type: 'switch' }, }, + { + key: 'initialHiddenIds', + flavors: allFlavors, + group: 'Interactivity', + help: `Hides certain series by default given their ids`, + type: 'string[]', + defaultValue: defaults.initialHiddenIds, + }, { key: 'crosshairType', flavors: ['svg'],