diff --git a/semcore/d3-chart/src/Area.jsx b/semcore/d3-chart/src/Area.jsx index c6c7d62756..f9285e2ebc 100644 --- a/semcore/d3-chart/src/Area.jsx +++ b/semcore/d3-chart/src/Area.jsx @@ -6,7 +6,7 @@ import { area, curveLinear, line } from 'd3-shape'; import React from 'react'; import AnimatedClipPath from './AnimatedClipPath'; -import { DATA_TYPE, FORECAST, POTENTIAL } from './component/Chart/AbstractChart.type'; +import { DATA_TYPE, FORECAST, POTENTIAL } from './component/Chart'; import { SvgElement } from './component/SvgElement'; import createElement from './createElement'; import Dots from './Dots'; diff --git a/semcore/d3-chart/src/Line.jsx b/semcore/d3-chart/src/Line.jsx index fccf60e5d6..60a7b8ff6c 100644 --- a/semcore/d3-chart/src/Line.jsx +++ b/semcore/d3-chart/src/Line.jsx @@ -5,9 +5,11 @@ import { curveLinear, line as d3Line, area as d3Area, curveCardinal } from 'd3-s import React from 'react'; import AnimatedClipPath from './AnimatedClipPath'; +import { DATA_TYPE, FORECAST, POTENTIAL } from './component/Chart'; +import { SvgElement } from './component/SvgElement'; import createElement from './createElement'; import Dots from './Dots'; -import { resolvePatternDasharray } from './Pattern'; +import { ForecastGradient, PotentialGradient, resolvePatternDasharray, StrokeMask } from './Pattern'; import style from './style/line.shadow.css'; import { definedData, @@ -94,6 +96,78 @@ class LineRoot extends Component { onClick(index, e); } + renderForecast() { + const SLine = this.Element; + const { + styles, + hide, + color, + resolveColor, + uid, + size, + d3, + duration, + y, + transparent, + } = this.asProps; + const data = this.asProps.data.filter((item) => item[y] !== interpolateValue && item[DATA_TYPE] === FORECAST); + + return sstyled(styles)( + <> + + + + , + ); + } + + renderPotential() { + const SLine = this.Element; + const { + styles, + hide, + uid, + size, + d3, + duration, + y, + transparent, + patterns, + } = this.asProps; + const data = this.asProps.data.filter((item) => item[y] !== interpolateValue && item[DATA_TYPE] === POTENTIAL); + + return sstyled(styles)( + <> + + + , + ); + } + render() { const SLine = this.Element; const { @@ -110,7 +184,7 @@ class LineRoot extends Component { transparent, patterns, } = this.asProps; - const data = this.asProps.data.filter((item) => item[y] !== interpolateValue); + const data = this.asProps.data.filter((item) => item[y] !== interpolateValue && item[DATA_TYPE] !== FORECAST && item[DATA_TYPE] !== POTENTIAL); this.asProps.dataHintsHandler.specifyDataRowFields(x, y); this.asProps.dataHintsHandler.establishDataType('time-series'); @@ -143,6 +217,8 @@ class LineRoot extends Component { height={size[1]} /> )} + {this.renderForecast()} + {this.renderPotential()} , ); } diff --git a/semcore/d3-chart/src/component/Chart/LineChart.tsx b/semcore/d3-chart/src/component/Chart/LineChart.tsx index fc43b3dada..a1f950c4d2 100644 --- a/semcore/d3-chart/src/component/Chart/LineChart.tsx +++ b/semcore/d3-chart/src/component/Chart/LineChart.tsx @@ -3,6 +3,8 @@ import i18nEnhance from '@semcore/core/lib/utils/enhances/i18nEnhance'; import { type ScaleLinear, scaleLinear, scaleTime } from 'd3-scale'; import React from 'react'; +import type { ObjectData } from './AbstractChart.type'; +import { HIGHLIGHT_DOT } from './AbstractChart.type'; import type { LineChartData, LineChartDefaultProps, LineChartProps, LineChartType } from './LineChart.type'; // @ts-ignore import { Line, minMax, HoverLine } from '../..'; @@ -83,7 +85,7 @@ class LineChartComponent extends AbstractChart< curve={curve} onClick={onClickLine} > - + {area?.[item.id] && ( )} @@ -116,6 +118,10 @@ class LineChartComponent extends AbstractChart< protected getLegendAriaLabel(): string { return this.asProps.getI18nText('legendForChart', { chartType: 'Line' }); } + + protected displayDots = (i: number, isActive: boolean, noAround: boolean, data: ObjectData): boolean => { + return isActive || noAround || Boolean(data[HIGHLIGHT_DOT]); + }; } /** diff --git a/stories/components/d3-chart/__mocks__/line.ts b/stories/components/d3-chart/__mocks__/line.ts index 7731a9e4e6..515fa37e74 100644 --- a/stories/components/d3-chart/__mocks__/line.ts +++ b/stories/components/d3-chart/__mocks__/line.ts @@ -1,4 +1,4 @@ -import { interpolateValue } from '@semcore/ui/d3-chart'; +import { DATA_TYPE, FORECAST, GOOD, HIGHLIGHT_DOT, interpolateValue, POTENTIAL, INSIGHTFUL } from '@semcore/ui/d3-chart'; export default { Default: [ @@ -23,6 +23,52 @@ export default { { x: 18, y: 1 }, { x: 19, y: 10 }, ], + Forecast: [ + { x: 0, y: 2 }, + { x: 1, y: 4 }, + { x: 2, y: 6 }, + { x: 3, y: 8 }, + { x: 4, y: 5 }, + { x: 5, y: 7 }, + { x: 6, y: 3 }, + { x: 7, y: 9 }, + { x: 8, y: 7 }, + { x: 9, y: 10, [HIGHLIGHT_DOT]: GOOD } as const, + { x: 10, y: 2 }, + { x: 11, y: 4 }, + { x: 12, y: 6 }, + { x: 13, y: 8 }, + { x: 14, y: 5 }, + { x: 15, y: 7 }, + { x: 15, y: 7, [DATA_TYPE]: FORECAST } as const, + { x: 16, y: 3, [DATA_TYPE]: FORECAST } as const, + { x: 17, y: 9, [DATA_TYPE]: FORECAST } as const, + { x: 18, y: 1, [DATA_TYPE]: FORECAST } as const, + { x: 19, y: 10, [DATA_TYPE]: FORECAST } as const, + ], + Potential: [ + { x: 0, y: 2 }, + { x: 1, y: 4 }, + { x: 2, y: 6 }, + { x: 3, y: 8 }, + { x: 4, y: 5 }, + { x: 5, y: 7 }, + { x: 6, y: 3 }, + { x: 7, y: 9 }, + { x: 8, y: 7 }, + { x: 9, y: 10 }, + { x: 10, y: 2 }, + { x: 11, y: 4 }, + { x: 12, y: 6 }, + { x: 13, y: 8 }, + { x: 14, y: 5 }, + { x: 15, y: 7 }, + { x: 16, y: 3 }, + { x: 16, y: 3, [DATA_TYPE]: POTENTIAL } as const, + { x: 17, y: 4, [DATA_TYPE]: POTENTIAL } as const, + { x: 18, y: 6, [DATA_TYPE]: POTENTIAL } as const, + { x: 19, y: 8, [DATA_TYPE]: POTENTIAL, [HIGHLIGHT_DOT]: INSIGHTFUL } as const, + ], TwoLines: [ { x: 0, line1: 2, line2: 5 }, { x: 1, line1: 4, line2: 7 }, diff --git a/stories/components/d3-chart/docs/examples/line-chart/basic-usage.tsx b/stories/components/d3-chart/docs/examples/line-chart/basic-usage.tsx index 05650ce66a..37bde4c6d0 100644 --- a/stories/components/d3-chart/docs/examples/line-chart/basic-usage.tsx +++ b/stories/components/d3-chart/docs/examples/line-chart/basic-usage.tsx @@ -1,3 +1,4 @@ +import { Flex } from '@semcore/ui/base-components'; import { Chart } from '@semcore/ui/d3-chart'; import React from 'react'; @@ -5,14 +6,32 @@ import LineMockData from '../../../__mocks__/line'; const Demo = () => { return ( - + + + + + ); };