Skip to content

Commit dcce4fd

Browse files
committed
Scatter chart: added axis prop, labels of axis, typings
1 parent c37dc0e commit dcce4fd

File tree

3 files changed

+185
-201
lines changed

3 files changed

+185
-201
lines changed

packages/charts/src/components/ScatterChart/ScatterChart.stories.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@ import { action } from '@storybook/addon-actions';
22
import { boolean } from '@storybook/addon-knobs';
33
import React from 'react';
44
import { ScatterChart } from '../../lib/ScatterChart';
5-
import {
6-
bigDataSet,
7-
complexDataSet,
8-
scatterComplexDataSet,
9-
secondaryDimensionDataSet,
10-
simpleDataSet
11-
} from '../../resources/DemoProps';
5+
import { bigDataSet, complexDataSet, scatterComplexDataSet } from '../../resources/DemoProps';
126

137
export default {
148
title: 'Charts / ScatterChart',
@@ -24,20 +18,23 @@ export const renderStory = () => (
2418
onLegendClick={action('onLegendClick')}
2519
dataset={scatterComplexDataSet}
2620
style={{ width: '100%' }}
27-
dimension={{
28-
accessor: 'volume',
29-
formatter: (e) => e + 'test'
30-
}}
3121
measures={[
3222
{
3323
accessor: 'users',
3424
label: 'Users',
35-
formatter: (val) => val.toLocaleString()
25+
formatter: (e) => e + ' Users',
26+
axis: 'x'
3627
},
3728
{
3829
accessor: 'sessions',
3930
label: 'Active Sessions',
40-
hideDataLabel: true
31+
formatter: (e) => e + ' Sessions',
32+
hideDataLabel: true,
33+
axis: 'y'
34+
},
35+
{
36+
accessor: 'volume',
37+
axis: 'z'
4138
}
4239
]}
4340
/>

packages/charts/src/components/ScatterChart/ScatterChart.tsx

Lines changed: 45 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingPara
22
import { useConsolidatedRef } from '@ui5/webcomponents-react-base/lib/useConsolidatedRef';
33
import { enrichEventWithDetails } from '@ui5/webcomponents-react-base/lib/Utils';
44
import { ChartContainer } from '@ui5/webcomponents-react-charts/lib/components/ChartContainer';
5-
import { ChartDataLabel } from '@ui5/webcomponents-react-charts/lib/components/ChartDataLabel';
65
import { XAxisTicks } from '@ui5/webcomponents-react-charts/lib/components/XAxisTicks';
76
import { YAxisTicks } from '@ui5/webcomponents-react-charts/lib/components/YAxisTicks';
87
import { LineChartPlaceholder } from '@ui5/webcomponents-react-charts/lib/LineChartPlaceholder';
98
import { useLegendItemClick } from '@ui5/webcomponents-react-charts/lib/useLegendItemClick';
109
import React, { FC, forwardRef, Ref, useCallback, useMemo } from 'react';
1110
import {
12-
Brush,
1311
CartesianGrid,
1412
Legend,
1513
Scatter,
@@ -18,19 +16,17 @@ import {
1816
Tooltip,
1917
XAxis,
2018
YAxis,
21-
ZAxis,
22-
Line
19+
ZAxis
2320
} from 'recharts';
2421
import { useChartMargin } from '../../hooks/useChartMargin';
2522
import { useLongestYAxisLabel } from '../../hooks/useLongestYAxisLabel';
26-
import { useObserveXAxisHeights } from '../../hooks/useObserveXAxisHeights';
2723
import { usePrepareDimensionsAndMeasures } from '../../hooks/usePrepareDimensionsAndMeasures';
2824
import { useTooltipFormatter } from '../../hooks/useTooltipFormatter';
2925
import { IChartBaseProps } from '../../interfaces/IChartBaseProps';
30-
import { IChartDimension } from '../../interfaces/IChartDimension';
3126
import { IChartMeasure } from '../../interfaces/IChartMeasure';
3227
import { defaultFormatter } from '../../internal/defaults';
3328
import { tickLineConfig, tooltipContentStyle, tooltipFillOpacity, xAxisPadding } from '../../internal/staticProps';
29+
import { useObserveXAxisHeights } from '../../hooks/useObserveXAxisHeights';
3430

3531
interface MeasureConfig extends IChartMeasure {
3632
/**
@@ -43,15 +39,20 @@ interface MeasureConfig extends IChartMeasure {
4339
* @default 1
4440
*/
4541
opacity?: number;
42+
/**
43+
* Defines axis of measures
44+
* @default 1
45+
*/
46+
axis: 'x' | 'y' | 'z';
4647
}
4748

48-
interface DimensionConfig extends IChartDimension {
49-
interval?: number;
49+
interface ScatterDataObject {
50+
label?: string;
51+
data: any[];
5052
}
5153

5254
export interface ScatterChartProps extends IChartBaseProps {
53-
dimension: DimensionConfig;
54-
dataset?: Record<string, any>[][];
55+
dataset?: ScatterDataObject[];
5556
/**
5657
* An array of config objects. Each object is defining one line in the chart.
5758
*
@@ -73,14 +74,8 @@ export interface ScatterChartProps extends IChartBaseProps {
7374
measures: MeasureConfig[];
7475
}
7576

76-
const dimensionDefaults = {
77-
formatter: defaultFormatter
78-
};
79-
8077
const measureDefaults = {
81-
formatter: defaultFormatter,
82-
width: 1,
83-
opacity: 1
78+
formatter: defaultFormatter
8479
};
8580

8681
/**
@@ -115,30 +110,10 @@ const ScatterChart: FC<ScatterChartProps> = forwardRef((props: ScatterChartProps
115110
};
116111
}, [props.chartConfig]);
117112

118-
const { dimensions, measures } = usePrepareDimensionsAndMeasures(
119-
[],
120-
props.measures,
121-
dimensionDefaults,
122-
measureDefaults
123-
);
113+
const { measures } = usePrepareDimensionsAndMeasures([], props.measures, {}, measureDefaults);
124114

125115
const tooltipValueFormatter = useTooltipFormatter(measures);
126-
127-
const primaryDimension = dimensions[0];
128-
const primaryMeasure = measures[0];
129-
130116
const chartRef = useConsolidatedRef<any>(ref);
131-
132-
const dataKeys = measures.map(({ accessor }) => accessor);
133-
134-
const dimension: DimensionConfig = useMemo(
135-
() => ({
136-
formatter: defaultFormatter,
137-
...props.dimension
138-
}),
139-
[props.dimension]
140-
);
141-
142117
const onItemLegendClick = useLegendItemClick(onLegendClick);
143118

144119
const onDataPointClickInternal = useCallback(
@@ -161,11 +136,18 @@ const ScatterChart: FC<ScatterChartProps> = forwardRef((props: ScatterChartProps
161136
);
162137

163138
const isBigDataSet = dataset?.length > 30 ?? false;
164-
const primaryDimensionAccessor = primaryDimension?.accessor;
165139

166-
const [yAxisWidth, legendPosition] = useLongestYAxisLabel(dataset[0], measures);
140+
const xMeasure = measures.filter(({ axis }) => axis === 'x');
141+
const yMeasure = measures.filter(({ axis }) => axis === 'y');
142+
const zMeasure = measures.filter(({ axis }) => axis === 'z');
143+
144+
const [yAxisWidth, legendPosition] = useLongestYAxisLabel(
145+
dataset[0].data,
146+
measures.filter(({ axis }) => axis === 'y')
147+
);
148+
const xAxisHeights = useObserveXAxisHeights(chartRef, 1);
149+
167150
const marginChart = useChartMargin(chartConfig.margin, chartConfig.zoomingTool);
168-
// const xAxisHeights = useObserveXAxisHeights(chartRef, props.dimensions.length);
169151

170152
return (
171153
<ChartContainer
@@ -192,32 +174,40 @@ const ScatterChart: FC<ScatterChartProps> = forwardRef((props: ScatterChartProps
192174
{chartConfig.xAxisVisible && (
193175
<XAxis
194176
type={'number'}
195-
key={measures[0].accessor}
196-
name={measures[0].accessor}
197-
dataKey={measures[0].accessor}
198-
interval={measures[0]?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
199-
tick={<XAxisTicks config={measures[0]} />}
177+
key={xMeasure[0].accessor}
178+
label={{ position: 'bottom', value: xMeasure[0].label }}
179+
dataKey={xMeasure[0].accessor}
180+
interval={xMeasure[0]?.interval ?? (isBigDataSet ? 'preserveStart' : 0)}
181+
tick={<XAxisTicks config={xMeasure[0]} />}
200182
padding={xAxisPadding}
183+
// height={xAxisHeights[0]}
201184
/>
202185
)}
203186
<YAxis
187+
label={yMeasure[0].label ? { position: 'top', value: yMeasure[0].label } : false}
204188
type={'number'}
205-
name={measures[1].accessor}
189+
name={yMeasure[0].accessor}
206190
axisLine={chartConfig.yAxisVisible}
207191
tickLine={tickLineConfig}
208-
key={measures[1].accessor}
209-
dataKey={measures[1].accessor}
210-
tickFormatter={measures[1]?.formatter}
192+
key={yMeasure[0].accessor}
193+
dataKey={yMeasure[0].accessor}
194+
tickFormatter={yMeasure[0]?.formatter}
211195
interval={0}
212-
tick={<YAxisTicks config={measures[1]} />}
196+
tick={<YAxisTicks config={yMeasure[0]} />}
213197
width={yAxisWidth}
198+
padding={yMeasure[0].label ? { top: 10 } : 0}
199+
/>
200+
<ZAxis
201+
name={zMeasure[0].accessor}
202+
dataKey={zMeasure[0].accessor}
203+
range={[0, 5000]}
204+
key={zMeasure[0].accessor}
214205
/>
215-
<ZAxis name={dimension.accessor} dataKey={dimension.accessor} range={[0, 5000]} key={dimension.accessor} />
216-
{dataset.map((data, index) => {
206+
{dataset.map((dataSet, index) => {
217207
return (
218208
<Scatter
219-
data={data}
220-
name={dimension.accessor}
209+
data={dataSet.data}
210+
name={dataSet.label}
221211
fill={`var(--sapChart_OrderedColor_${(index % 11) + 1})`}
222212
isAnimationActive={noAnimation === false}
223213
/>
@@ -240,15 +230,6 @@ const ScatterChart: FC<ScatterChartProps> = forwardRef((props: ScatterChartProps
240230
/>
241231
)}
242232
<Tooltip cursor={tooltipFillOpacity} formatter={tooltipValueFormatter} contentStyle={tooltipContentStyle} />
243-
{chartConfig.zoomingTool && (
244-
<Brush
245-
y={10}
246-
dataKey={primaryDimensionAccessor}
247-
stroke={ThemingParameters.sapObjectHeader_BorderColor}
248-
travellerWidth={10}
249-
height={20}
250-
/>
251-
)}
252233
</ScatterChartLib>
253234
</ChartContainer>
254235
);

0 commit comments

Comments
 (0)