From c882d220397ce37b0ef032fe042f8fa52b25aab3 Mon Sep 17 00:00:00 2001 From: "ilia.brauer" Date: Wed, 9 Sep 2026 15:54:27 +0200 Subject: [PATCH] [d3-chart] added BenchmarkLine component --- .../component/BenchmarkLine/BenchmarkLine.tsx | 75 +++++++++++++++++++ .../BenchmarkLine/BenchmarkLine.type.ts | 17 +++++ .../BenchmarkLine/benckmarkLine.shadow.css | 12 +++ .../src/component/Chart/AbstractChart.tsx | 10 +++ .../src/component/Chart/AbstractChart.type.ts | 2 + .../docs/examples/area-chart/basic-usage.tsx | 1 + 6 files changed, 117 insertions(+) create mode 100644 semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.tsx create mode 100644 semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.type.ts create mode 100644 semcore/d3-chart/src/component/BenchmarkLine/benckmarkLine.shadow.css diff --git a/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.tsx b/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.tsx new file mode 100644 index 0000000000..5239f2f09d --- /dev/null +++ b/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.tsx @@ -0,0 +1,75 @@ +import { Component, sstyled } from '@semcore/core'; +import React from 'react'; + +import type { BenchmarkLineProps } from './BenchmarkLine.type'; +import style from './benckmarkLine.shadow.css'; +import createElement from '../../createElement'; + +class BenchmarkLineRoot extends Component { + static style = style; + + render() { + // @ts-ignore + const SLabel = this.Element; + const SLine = 'line'; + const SRect = 'rect'; + const SText = 'text'; + const SGroup = 'g'; + + const { + styles, + theme, + benchmarkValue, + xScale, + yScale, + data, + } = this.asProps; + + const y = yScale(benchmarkValue); + + return sstyled(styles)( + + + + + + + {benchmarkValue} + + + , + ); + } +} + +export const BenchmarkLine = createElement(BenchmarkLineRoot); diff --git a/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.type.ts b/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.type.ts new file mode 100644 index 0000000000..84566fd941 --- /dev/null +++ b/semcore/d3-chart/src/component/BenchmarkLine/BenchmarkLine.type.ts @@ -0,0 +1,17 @@ +export type BenchmarkLineProps = { + /** + * Level of line + */ + level: number; + + /** + * Theme + * @default 'default' + */ + theme: 'default' | 'accent'; + + /** + * Value to display + */ + value: string | number | Date; +}; diff --git a/semcore/d3-chart/src/component/BenchmarkLine/benckmarkLine.shadow.css b/semcore/d3-chart/src/component/BenchmarkLine/benckmarkLine.shadow.css new file mode 100644 index 0000000000..962a7089a9 --- /dev/null +++ b/semcore/d3-chart/src/component/BenchmarkLine/benckmarkLine.shadow.css @@ -0,0 +1,12 @@ + +SGroup { + transform: translate(0, 50%); +} +SGroup[y] { + transform: translate(0, var(--y)); + transition: transform 0.2s ease-in-out; +} + +SLabel { + transform: translate(calc(100% - 90px), -10px); +} diff --git a/semcore/d3-chart/src/component/Chart/AbstractChart.tsx b/semcore/d3-chart/src/component/Chart/AbstractChart.tsx index 6944f8e483..3e432aff88 100644 --- a/semcore/d3-chart/src/component/Chart/AbstractChart.tsx +++ b/semcore/d3-chart/src/component/Chart/AbstractChart.tsx @@ -20,6 +20,7 @@ import { Plot, XAxis, YAxis } from '../..'; import { makeDataHintsContainer } from '../../a11y/hints'; import style from '../../style/abstract-chart.shadow.css'; import { interpolateValue } from '../../utils'; +import { BenchmarkLine } from '../BenchmarkLine/BenchmarkLine'; import ChartLegend, { ChartLegendTable } from '../ChartLegend'; import type { LegendFlexProps } from '../ChartLegend/LegendFlex/LegendFlex.type'; import type { LegendItem } from '../ChartLegend/LegendItem/LegendItem.type'; @@ -628,6 +629,14 @@ export abstract class AbstractChart< ); } + protected renderBenchmarkLine() { + const { benchmarkValue } = this.asProps; + + return ( + + ); + } + public render() { const SChart = Root; const { styles, data, patterns, a11yAltTextConfig, duration, eventEmitter, showTooltip } = @@ -654,6 +663,7 @@ export abstract class AbstractChart< {this.renderAxis()} {!showTooltip ? null : this.renderTooltip()} {this.renderChart()} + {this.renderBenchmarkLine()} , ); diff --git a/semcore/d3-chart/src/component/Chart/AbstractChart.type.ts b/semcore/d3-chart/src/component/Chart/AbstractChart.type.ts index e43ed1aea6..4bf313ba20 100644 --- a/semcore/d3-chart/src/component/Chart/AbstractChart.type.ts +++ b/semcore/d3-chart/src/component/Chart/AbstractChart.type.ts @@ -72,6 +72,8 @@ export type BaseChartProps = NSFlex.Props & { * Chart data. For all charts except Donut(Pie), Radar and Venn should be an Array */ data: T; + + benchmarkValue?: number | Date | string; /** * Width of plot * @default width is 100% of the parent element. diff --git a/stories/components/d3-chart/docs/examples/area-chart/basic-usage.tsx b/stories/components/d3-chart/docs/examples/area-chart/basic-usage.tsx index 8ca932ff25..885489abe2 100644 --- a/stories/components/d3-chart/docs/examples/area-chart/basic-usage.tsx +++ b/stories/components/d3-chart/docs/examples/area-chart/basic-usage.tsx @@ -21,6 +21,7 @@ const Demo = () => { plotHeight={200} tooltipValueFormatter={formatDate} aria-label='Area chart' + benchmarkValue={2} /> ); };