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

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 'point': {
const tag = chart.point?.shape ?? 'circle'
nodes = chart().selectAll(tag)
nodes = chart().selectAll(['hline', 'vline'].includes(tag) ? 'line' : tag)
switch (tag) {
case 'circle':
nodes = nodes.filter(makeIsCircleTouched(x, y, chart.tooltip?.limit ?? limit, type))
break
case 'line':
case 'hline':
case 'vline':
nodes = nodes.filter(makeIsLineTouched(x, y, chart.tooltip?.limit ?? limit, type))
break
}

View File

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

View File

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

View File

@ -55,11 +55,22 @@ const chartDatasets = [{
},
optimization: false,
point: {
radius: 2,
strokeColor: 'none',
radius: 5,
strokeWidth: 1.5,
shape: 'vline',
fillColor: 'currentColor',
},
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 = {
@ -75,10 +86,7 @@ const ticks = {
}
export const OperationsChart = memo(({ data, yDomain, height, category, onDomainChanged }) => {
const domain = useMemo(() => ({
y: { min: 0, max: yDomain },
// x: { min: new Date('2021-11-04 03:57'), max: new Date('2022-06-17 13:16') }
}), [yDomain])
const domain = useMemo(() => ({ y: { min: 0, max: yDomain } }), [yDomain])
const plugins = useMemo(() => ({
menu: { enabled: false },

View File

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