Переработано отображение точек-линии на графиках

This commit is contained in:
Александр Сироткин 2022-07-30 19:00:42 +05:00
parent cdd09edf4f
commit 367b63ae50
5 changed files with 44 additions and 26 deletions

View File

@ -102,12 +102,13 @@ export const getTouchedElements = <DataType,>(
case 'line': case 'line':
case 'point': { case 'point': {
const tag = chart.point?.shape ?? 'circle' const tag = chart.point?.shape ?? 'circle'
nodes = chart().selectAll(tag) nodes = chart().selectAll(['hline', 'vline'].includes(tag) ? 'line' : tag)
switch (tag) { switch (tag) {
case 'circle': case 'circle':
nodes = nodes.filter(makeIsCircleTouched(x, y, chart.tooltip?.limit ?? limit, type)) nodes = nodes.filter(makeIsCircleTouched(x, y, chart.tooltip?.limit ?? limit, type))
break break
case 'line': case 'hline':
case 'vline':
nodes = nodes.filter(makeIsLineTouched(x, y, chart.tooltip?.limit ?? limit, type)) nodes = nodes.filter(makeIsLineTouched(x, y, chart.tooltip?.limit ?? limit, type))
break break
} }

View File

@ -1,5 +1,15 @@
import { ChartRegistry, PointChartDataset } from '@components/d3/types' import { ChartRegistry, PointChartDataset } from '@components/d3/types'
const defaultConfig: Required<Omit<PointChartDataset, 'type'>> = {
radius: 3,
shape: 'circle',
strokeWidth: 0,
strokeColor: 'currentColor',
strokeOpacity: 1,
fillColor: 'currentColor',
fillOpacity: 1,
}
export const renderPoint = <DataType extends Record<string, unknown>>( export const renderPoint = <DataType extends Record<string, unknown>>(
xAxis: (value: any) => number, xAxis: (value: any) => number,
yAxis: (value: any) => number, yAxis: (value: any) => number,
@ -7,20 +17,11 @@ export const renderPoint = <DataType extends Record<string, unknown>>(
data: DataType[], data: DataType[],
embeded: boolean = false, embeded: boolean = false,
): DataType[] => { ): DataType[] => {
let config: Required<Omit<PointChartDataset, 'type'>> = { let config: Required<Omit<PointChartDataset, 'type'>>
radius: 3,
shape: 'circle',
strokeWidth: 0,
strokeColor: 'currentColor',
strokeOpacity: 1,
fillColor: 'currentColor',
fillOpacity: 1,
}
if (embeded) if (embeded)
config = { ...config, ...chart.point } config = { ...defaultConfig, ...chart.point }
else if (chart.type === 'point') else if (chart.type === 'point')
config = { ...config, ...chart } config = { ...defaultConfig, ...chart }
else return data else return data
const getPointsRoot = (): d3.Selection<any, any, any, any> => { const getPointsRoot = (): d3.Selection<any, any, any, any> => {
@ -42,15 +43,17 @@ export const renderPoint = <DataType extends Record<string, unknown>>(
.attr('stroke', config.strokeColor) .attr('stroke', config.strokeColor)
.attr('stroke-opacity', config.strokeOpacity) .attr('stroke-opacity', config.strokeOpacity)
const shape = ['hline', 'vline'].includes(config.shape) ? 'line' : config.shape
const currentPoints = getPointsRoot() const currentPoints = getPointsRoot()
.selectAll(config.shape) .selectAll(shape)
.data(data.filter(chart.y)) .data(data.filter(chart.y))
currentPoints.exit().remove() currentPoints.exit().remove()
currentPoints.enter().append(config.shape) currentPoints.enter().append(shape)
const newPoints = getPointsRoot() const newPoints = getPointsRoot()
.selectAll<d3.BaseType, DataType>(config.shape) .selectAll<d3.BaseType, DataType>(shape)
.transition() .transition()
.duration(chart.animDurationMs ?? 0) .duration(chart.animDurationMs ?? 0)
@ -61,7 +64,13 @@ export const renderPoint = <DataType extends Record<string, unknown>>(
.attr('cx', (d) => xAxis(chart.x(d))) .attr('cx', (d) => xAxis(chart.x(d)))
.attr('cy', (d) => yAxis(chart.y(d))) .attr('cy', (d) => yAxis(chart.y(d)))
break break
case 'line': case 'hline':
newPoints.attr('x1', (d) => xAxis(chart.x(d)) - config.radius)
.attr('x2', (d) => xAxis(chart.x(d)) + config.radius)
.attr('y1', (d) => yAxis(chart.y(d)))
.attr('y2', (d) => yAxis(chart.y(d)))
break
case 'vline':
newPoints.attr('x1', (d) => xAxis(chart.x(d))) newPoints.attr('x1', (d) => xAxis(chart.x(d)))
.attr('x2', (d) => xAxis(chart.x(d))) .attr('x2', (d) => xAxis(chart.x(d)))
.attr('y1', (d) => yAxis(chart.y(d)) - config.radius) .attr('y1', (d) => yAxis(chart.y(d)) - config.radius)

View File

@ -21,7 +21,7 @@ export type PointChartDataset = {
/** Радиус точек */ /** Радиус точек */
radius?: number radius?: number
/** Форма точек */ /** Форма точек */
shape?: 'circle' | 'line' shape?: 'circle' | 'hline' | 'vline'
/** Цвет обводки точек */ /** Цвет обводки точек */
strokeColor?: Property.Color strokeColor?: Property.Color
/** Толщина обводки */ /** Толщина обводки */

View File

@ -55,11 +55,22 @@ const chartDatasets = [{
}, },
optimization: false, optimization: false,
point: { point: {
radius: 2, radius: 5,
strokeColor: 'none', strokeWidth: 1.5,
shape: 'vline',
fillColor: 'currentColor', fillColor: 'currentColor',
}, },
nullValues: 'gap', nullValues: 'gap',
}, {
key: 'target_dash',
type: 'needle',
width: 2,
color: 'black',
opacity: 0.075,
yAxis: {
type: 'linear',
accessor: (row) => row.operationValue?.targetValue ?? null,
}
}] }]
const xAxis = { const xAxis = {
@ -75,10 +86,7 @@ const ticks = {
} }
export const OperationsChart = memo(({ data, yDomain, height, category, onDomainChanged }) => { export const OperationsChart = memo(({ data, yDomain, height, category, onDomainChanged }) => {
const domain = useMemo(() => ({ const domain = useMemo(() => ({ y: { min: 0, max: yDomain } }), [yDomain])
y: { min: 0, max: yDomain },
// x: { min: new Date('2021-11-04 03:57'), max: new Date('2022-06-17 13:16') }
}), [yDomain])
const plugins = useMemo(() => ({ const plugins = useMemo(() => ({
menu: { enabled: false }, menu: { enabled: false },

View File

@ -125,7 +125,7 @@ const makeDataset = (key, label, color, width, radius, dash) => ({
strokeColor: 'currentColor', strokeColor: 'currentColor',
strokeOpacity: 0.7, strokeOpacity: 0.7,
fillOpacity: 0.1, fillOpacity: 0.1,
shape: 'line', shape: 'vline',
strokeWidth: 1.5, strokeWidth: 1.5,
radius radius
}, },