From 3d9557f9e6f781485ff7d4a92c61a721b8bbb6a2 Mon Sep 17 00:00:00 2001 From: mbauchet Date: Sun, 30 Jul 2023 16:15:27 +0200 Subject: [PATCH 01/10] add number of months --- src/stories/input-elements/DateRangePicker.stories.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/stories/input-elements/DateRangePicker.stories.tsx b/src/stories/input-elements/DateRangePicker.stories.tsx index 2cfadc7b0..424e98482 100644 --- a/src/stories/input-elements/DateRangePicker.stories.tsx +++ b/src/stories/input-elements/DateRangePicker.stories.tsx @@ -199,3 +199,8 @@ UncontrolledWithoutAllowClear.args = { defaultValue: { from: new Date(2022, 10, 1), to: new Date() }, enableClear: false, }; + +export const WithNumberOfMonths = UncontrolledTemplate.bind({}); +WithNumberOfMonths.args = { + numberOfMonths: 2 +}; \ No newline at end of file From 75a94273f81ee65450e0b103ffcc913c697ecdc0 Mon Sep 17 00:00:00 2001 From: mbauchet Date: Sun, 30 Jul 2023 16:15:54 +0200 Subject: [PATCH 02/10] add number of mnths --- .../input-elements/DateRangePicker/DateRangePicker.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/input-elements/DateRangePicker/DateRangePicker.tsx b/src/components/input-elements/DateRangePicker/DateRangePicker.tsx index b32bdda26..f792d5a14 100644 --- a/src/components/input-elements/DateRangePicker/DateRangePicker.tsx +++ b/src/components/input-elements/DateRangePicker/DateRangePicker.tsx @@ -48,6 +48,7 @@ export interface DateRangePickerProps locale?: Locale; enableClear?: boolean; enableYearNavigation?: boolean; + numberOfMonths?: number; children?: React.ReactElement[] | React.ReactElement; } @@ -67,6 +68,7 @@ const DateRangePicker = React.forwardRef(( children, className, enableYearNavigation = false, + numberOfMonths = 1, ...other } = props; @@ -242,6 +244,7 @@ const DateRangePicker = React.forwardRef(( from: selectedStartDate, to: selectedEndDate, }} + numberOfMonths={numberOfMonths ?? 1} onSelect={ ((v: DateRange) => { onValueChange?.({ from: v?.from, to: v?.to }); From bde4b3fd6778f3429803658971840db264e1f1ea Mon Sep 17 00:00:00 2001 From: mbauchet Date: Wed, 13 Sep 2023 13:21:41 +0200 Subject: [PATCH 03/10] add click event on scatter chart --- .../ScatterChart/ScatterChart.tsx | 57 ++++++++++++++++++- .../chart-elements/ScatterChart.stories.tsx | 7 +++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index 3388d3f7f..4338a5ae9 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -10,6 +10,7 @@ import { XAxis, YAxis, ZAxis, + Sector, } from "recharts"; import { AxisDomain } from "recharts/types/util/types"; @@ -35,6 +36,43 @@ export type ScatterChartValueFormatter = { size?: ValueFormatter; }; +const deepEqual = (obj1: any, obj2: any ) => { + if (obj1 === obj2) return true; + + if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) + return false; + + const keys1 = Object.keys(obj1); + const keys2 = Object.keys(obj2); + + if (keys1.length !== keys2.length) return false; + + for (const key of keys1) { + if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) return false; + } + + return true; + } + +const renderShape = (props: any, activeNode: any | undefined) => { + const { + cx, + cy, + width, + node, + fillOpacity + } = props; + + return ( + + ); + }; + export interface ScatterChartProps extends BaseAnimationTimingProps, React.HTMLAttributes { @@ -61,6 +99,7 @@ export interface ScatterChartProps minYValue?: number; maxYValue?: number; allowDecimals?: boolean; + showOnClickVisualFeedback?: boolean; noDataText?: string; } @@ -95,12 +134,24 @@ const ScatterChart = React.forwardRef((props, minYValue, maxYValue, allowDecimals = true, + showOnClickVisualFeedback = true, noDataText, className, ...other } = props; const [legendHeight, setLegendHeight] = useState(60); - + const [activeNode, setActiveNode] = React.useState(undefined); + + function onNodeClick(data: any, index: number, event: React.MouseEvent) { + event.stopPropagation() + + if (!showOnClickVisualFeedback) return; + if (deepEqual(activeNode, data.node)) { + setActiveNode(undefined); + } else { + setActiveNode(data.node); + } + } const categories = constructCategories(data, category); const categoryColors = constructCategoryColors(categories, colors); @@ -112,7 +163,7 @@ const ScatterChart = React.forwardRef((props,
{data?.length ? ( - + setActiveNode(undefined)}> {showGridLines ? ( ((props, data={category ? data.filter((d) => d[category] === cat) : data} isAnimationActive={showAnimation} animationDuration={animationDuration} + shape={(props) => renderShape(props, activeNode)} + onClick={onNodeClick} /> ); })} diff --git a/src/stories/chart-elements/ScatterChart.stories.tsx b/src/stories/chart-elements/ScatterChart.stories.tsx index 59b0d0d46..432dc2fb0 100644 --- a/src/stories/chart-elements/ScatterChart.stories.tsx +++ b/src/stories/chart-elements/ScatterChart.stories.tsx @@ -101,6 +101,13 @@ WithNoDataText.args = { noDataText: "No data, try again later.", }; +export const WithNoClickVisualFeedback = DefaultTemplate.bind({}); +WithNoClickVisualFeedback.args = { + ...args, + data, + showOnClickVisualFeedback: false +}; + export const WithExampleDatas = ResponsiveTemplate.bind({}); // More on args: https://storybook.js.org/docs/react/writing-stories/args WithExampleDatas.args = { From 723ac00a7bdf64b42a50be64842226aa7f631493 Mon Sep 17 00:00:00 2001 From: mbauchet Date: Wed, 13 Sep 2023 13:24:08 +0200 Subject: [PATCH 04/10] fix lint --- .../ScatterChart/ScatterChart.tsx | 62 +++++++------------ src/components/chart-elements/common/utils.ts | 18 ++++++ .../chart-elements/ScatterChart.stories.tsx | 2 +- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index 4338a5ae9..c7d752985 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -10,11 +10,15 @@ import { XAxis, YAxis, ZAxis, - Sector, } from "recharts"; import { AxisDomain } from "recharts/types/util/types"; -import { constructCategories, constructCategoryColors, getYAxisDomain } from "../common/utils"; +import { + constructCategories, + constructCategoryColors, + deepEqual, + getYAxisDomain, +} from "../common/utils"; import NoData from "../common/NoData"; import BaseAnimationTimingProps from "../common/BaseAnimationTimingProps"; import ChartLegend from "components/chart-elements/common/ChartLegend"; @@ -36,42 +40,18 @@ export type ScatterChartValueFormatter = { size?: ValueFormatter; }; -const deepEqual = (obj1: any, obj2: any ) => { - if (obj1 === obj2) return true; - - if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) - return false; - - const keys1 = Object.keys(obj1); - const keys2 = Object.keys(obj2); - - if (keys1.length !== keys2.length) return false; - - for (const key of keys1) { - if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) return false; - } - - return true; - } - const renderShape = (props: any, activeNode: any | undefined) => { - const { - cx, - cy, - width, - node, - fillOpacity - } = props; - - return ( - - ); - }; + const { cx, cy, width, node, fillOpacity } = props; + + return ( + + ); +}; export interface ScatterChartProps extends BaseAnimationTimingProps, @@ -141,10 +121,10 @@ const ScatterChart = React.forwardRef((props, } = props; const [legendHeight, setLegendHeight] = useState(60); const [activeNode, setActiveNode] = React.useState(undefined); - - function onNodeClick(data: any, index: number, event: React.MouseEvent) { - event.stopPropagation() - + + function onNodeClick(data: any, index: number, event: React.MouseEvent) { + event.stopPropagation(); + if (!showOnClickVisualFeedback) return; if (deepEqual(activeNode, data.node)) { setActiveNode(undefined); diff --git a/src/components/chart-elements/common/utils.ts b/src/components/chart-elements/common/utils.ts index a7720e04b..97293bc3b 100644 --- a/src/components/chart-elements/common/utils.ts +++ b/src/components/chart-elements/common/utils.ts @@ -32,3 +32,21 @@ export const constructCategories = (data: any[], color?: string): string[] => { }); return Array.from(categories); }; + +export const deepEqual = (obj1: any, obj2: any) => { + if (obj1 === obj2) return true; + + if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) + return false; + + const keys1 = Object.keys(obj1); + const keys2 = Object.keys(obj2); + + if (keys1.length !== keys2.length) return false; + + for (const key of keys1) { + if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) return false; + } + + return true; +}; diff --git a/src/stories/chart-elements/ScatterChart.stories.tsx b/src/stories/chart-elements/ScatterChart.stories.tsx index 432dc2fb0..fdf488912 100644 --- a/src/stories/chart-elements/ScatterChart.stories.tsx +++ b/src/stories/chart-elements/ScatterChart.stories.tsx @@ -105,7 +105,7 @@ export const WithNoClickVisualFeedback = DefaultTemplate.bind({}); WithNoClickVisualFeedback.args = { ...args, data, - showOnClickVisualFeedback: false + showOnClickVisualFeedback: false, }; export const WithExampleDatas = ResponsiveTemplate.bind({}); From 9405ae97fcca0de5b090633d44d2c6622d867aa9 Mon Sep 17 00:00:00 2001 From: mbauchet Date: Wed, 13 Sep 2023 13:31:26 +0200 Subject: [PATCH 05/10] add onValueChange prop --- src/components/chart-elements/ScatterChart/ScatterChart.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index c7d752985..1ec4e2dc1 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -80,6 +80,7 @@ export interface ScatterChartProps maxYValue?: number; allowDecimals?: boolean; showOnClickVisualFeedback?: boolean; + onValueChange?: (value: any) => void; noDataText?: string; } @@ -115,6 +116,7 @@ const ScatterChart = React.forwardRef((props, maxYValue, allowDecimals = true, showOnClickVisualFeedback = true, + onValueChange, noDataText, className, ...other @@ -124,12 +126,13 @@ const ScatterChart = React.forwardRef((props, function onNodeClick(data: any, index: number, event: React.MouseEvent) { event.stopPropagation(); - + if (!showOnClickVisualFeedback) return; if (deepEqual(activeNode, data.node)) { setActiveNode(undefined); } else { setActiveNode(data.node); + onValueChange?.(data.payload.payload); } } const categories = constructCategories(data, category); From 13311cb0ef5bab745d76c758915c371dfc5e827b Mon Sep 17 00:00:00 2001 From: mbauchet Date: Wed, 13 Sep 2023 13:34:19 +0200 Subject: [PATCH 06/10] remove numberOfMonth datepicker (error) --- .../input-elements/DateRangePicker/DateRangePicker.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/input-elements/DateRangePicker/DateRangePicker.tsx b/src/components/input-elements/DateRangePicker/DateRangePicker.tsx index 5aad14d55..6fdba43b3 100644 --- a/src/components/input-elements/DateRangePicker/DateRangePicker.tsx +++ b/src/components/input-elements/DateRangePicker/DateRangePicker.tsx @@ -259,7 +259,6 @@ const DateRangePicker = React.forwardRef(( from: selectedStartDate, to: selectedEndDate, }} - numberOfMonths={1} onSelect={ ((v: DateRange) => { onValueChange?.({ from: v?.from, to: v?.to }); From 6d4a3cb2312be39b964dabf1d395babfcd96e2fa Mon Sep 17 00:00:00 2001 From: mbauchet Date: Wed, 13 Sep 2023 14:16:01 +0200 Subject: [PATCH 07/10] fix payload return and add story for onValueChange --- .../chart-elements/ScatterChart/ScatterChart.tsx | 2 +- src/stories/chart-elements/ScatterChart.stories.tsx | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index 1ec4e2dc1..0431554f6 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -132,7 +132,7 @@ const ScatterChart = React.forwardRef((props, setActiveNode(undefined); } else { setActiveNode(data.node); - onValueChange?.(data.payload.payload); + onValueChange?.(data.payload); } } const categories = constructCategories(data, category); diff --git a/src/stories/chart-elements/ScatterChart.stories.tsx b/src/stories/chart-elements/ScatterChart.stories.tsx index fdf488912..990624f52 100644 --- a/src/stories/chart-elements/ScatterChart.stories.tsx +++ b/src/stories/chart-elements/ScatterChart.stories.tsx @@ -108,6 +108,14 @@ WithNoClickVisualFeedback.args = { showOnClickVisualFeedback: false, }; +export const WithOnValueChange = ResponsiveTemplate.bind({}); +// More on args: https://storybook.js.org/docs/react/writing-stories/args +WithOnValueChange.args = { + ...args, + data, + onValueChange: (value) => alert(JSON.stringify(value)), +}; + export const WithExampleDatas = ResponsiveTemplate.bind({}); // More on args: https://storybook.js.org/docs/react/writing-stories/args WithExampleDatas.args = { From f93055cf81fedd666d6e552ac29af788f35b9761 Mon Sep 17 00:00:00 2001 From: Severin Landolt Date: Thu, 14 Sep 2023 17:37:04 +0200 Subject: [PATCH 08/10] fix lint --- src/components/chart-elements/ScatterChart/ScatterChart.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index 0431554f6..f433696d8 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -126,7 +126,6 @@ const ScatterChart = React.forwardRef((props, function onNodeClick(data: any, index: number, event: React.MouseEvent) { event.stopPropagation(); - if (!showOnClickVisualFeedback) return; if (deepEqual(activeNode, data.node)) { setActiveNode(undefined); From e01c4b79279f80a0ede0a8384a5811e4fe49ba23 Mon Sep 17 00:00:00 2001 From: Severin Landolt Date: Sun, 17 Sep 2023 12:26:06 +0200 Subject: [PATCH 09/10] gacp removed showOnClickVisualFeedback --- .../chart-elements/ScatterChart/ScatterChart.tsx | 4 +--- src/stories/chart-elements/ScatterChart.stories.tsx | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/components/chart-elements/ScatterChart/ScatterChart.tsx b/src/components/chart-elements/ScatterChart/ScatterChart.tsx index f433696d8..e666c588a 100644 --- a/src/components/chart-elements/ScatterChart/ScatterChart.tsx +++ b/src/components/chart-elements/ScatterChart/ScatterChart.tsx @@ -79,7 +79,6 @@ export interface ScatterChartProps minYValue?: number; maxYValue?: number; allowDecimals?: boolean; - showOnClickVisualFeedback?: boolean; onValueChange?: (value: any) => void; noDataText?: string; } @@ -115,7 +114,6 @@ const ScatterChart = React.forwardRef((props, minYValue, maxYValue, allowDecimals = true, - showOnClickVisualFeedback = true, onValueChange, noDataText, className, @@ -126,7 +124,7 @@ const ScatterChart = React.forwardRef((props, function onNodeClick(data: any, index: number, event: React.MouseEvent) { event.stopPropagation(); - if (!showOnClickVisualFeedback) return; + if (onValueChange == null) return; if (deepEqual(activeNode, data.node)) { setActiveNode(undefined); } else { diff --git a/src/stories/chart-elements/ScatterChart.stories.tsx b/src/stories/chart-elements/ScatterChart.stories.tsx index 990624f52..7d827677a 100644 --- a/src/stories/chart-elements/ScatterChart.stories.tsx +++ b/src/stories/chart-elements/ScatterChart.stories.tsx @@ -101,13 +101,6 @@ WithNoDataText.args = { noDataText: "No data, try again later.", }; -export const WithNoClickVisualFeedback = DefaultTemplate.bind({}); -WithNoClickVisualFeedback.args = { - ...args, - data, - showOnClickVisualFeedback: false, -}; - export const WithOnValueChange = ResponsiveTemplate.bind({}); // More on args: https://storybook.js.org/docs/react/writing-stories/args WithOnValueChange.args = { From a9d9ebacec59aceee981ecabe5b6173a49c333e8 Mon Sep 17 00:00:00 2001 From: Severin Landolt Date: Mon, 18 Sep 2023 16:45:11 +0200 Subject: [PATCH 10/10] update onvaluechange story --- .../chart-elements/ScatterChart.stories.tsx | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/stories/chart-elements/ScatterChart.stories.tsx b/src/stories/chart-elements/ScatterChart.stories.tsx index 7d827677a..ee07e2952 100644 --- a/src/stories/chart-elements/ScatterChart.stories.tsx +++ b/src/stories/chart-elements/ScatterChart.stories.tsx @@ -15,20 +15,25 @@ export default { } as ComponentMeta; // More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args -const ResponsiveTemplate: ComponentStory = (args) => ( - <> - Mobile -
+const ResponsiveTemplate: ComponentStory = (args) => { + if (args.onValueChange?.length === 0) { + args.onValueChange = undefined; + } + return ( + <> + Mobile +
+ + + +
+ Desktop -
- Desktop - - - - -); + + ); +}; const DefaultTemplate: ComponentStory = ({ ...args }) => (