Добавлена реализация отрисовки графика параметра ограничивающего подачу

This commit is contained in:
Александр Сироткин 2022-08-14 15:05:48 +05:00
parent 539030e9fd
commit 0a18b79416
2 changed files with 103 additions and 0 deletions

View File

@ -573,6 +573,14 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
return <line key={`${i}`} x1={x} x2={x} y1={sizes.chartsTop} y2={offset.top + sizes.inlineHeight} /> return <line key={`${i}`} x1={x} x2={x} y1={sizes.chartsTop} y2={offset.top + sizes.inlineHeight} />
})} })}
</g> </g>
<D3MonitoringLimitChart
data={data}
yAxis={yAxis}
width={20}
height={sizes.chartsHeight}
left={sizes.inlineWidth + sizes.left}
top={sizes.chartsTop}
/>
<D3MouseZone width={width} height={height} offset={{ ...offset, top: sizes.chartsTop }}> <D3MouseZone width={width} height={height} offset={{ ...offset, top: sizes.chartsTop }}>
<D3HorizontalCursor <D3HorizontalCursor
{...plugins?.cursor} {...plugins?.cursor}

View File

@ -0,0 +1,95 @@
import { memo, useEffect, useMemo, useState } from 'react'
import * as d3 from 'd3'
import { TelemetryDataSaubDto } from '@api'
export type D3MonitoringLimitChartProps<DataType> = {
yAxis?: d3.ScaleTime<number, number, never>
data: DataType[]
width: number
height: number
left: number
top: number
}
type LimitChartData = {
id: number
dateStart: Date
dateEnd: Date
}
type LimitChartDataRaw = {
id?: number
dateStart?: string
dateEnd?: string
}
const regulators: Record<number, any> = {
1: { color: '#007070', label: 'Расход' },
2: { color: '#59B359', label: 'Скорость блока' },
3: { color: '#FF0000', label: 'Давление' },
4: { color: '#0000CC', label: 'Осевая нагрузка' },
5: { color: '#00B3B3', label: 'Вес на крюке' },
6: { color: '#990099', label: 'Момент на роторе' },
}
const getLast = (out: LimitChartDataRaw[]) => out.at(-1) as LimitChartDataRaw
function isDataCorrect(value: LimitChartDataRaw): value is Required<LimitChartDataRaw> {
return typeof value.id !== 'undefined'
}
const calcualteData = <DataType extends TelemetryDataSaubDto>(data: DataType[]) => {
const out = data.filter((row) => row.dateTime).reduce((out, row) => {
const last = getLast(out)
if (last.id === row.idFeedRegulator) {
if (!row.idFeedRegulator) return out
last.dateEnd = row.dateTime
} else {
const n: LimitChartDataRaw = {}
if (row.idFeedRegulator) {
n.id = row.idFeedRegulator
n.dateStart = row.dateTime
n.dateEnd = row.dateTime
}
out.push(n)
}
return out
}, [{}] as LimitChartDataRaw[])
return out.filter(isDataCorrect).map<LimitChartData>((row) => ({
id: row.id,
dateStart: new Date(row.dateStart),
dateEnd: new Date(row.dateEnd),
}))
}
const _D3MonitoringLimitChart = <DataType extends TelemetryDataSaubDto>({ yAxis, data: chartData, width, height, left, top }: D3MonitoringLimitChartProps<DataType>) => {
const [ref, setRef] = useState<SVGGElement | null>(null)
const data = useMemo(() => calcualteData(chartData), [chartData])
useEffect(() => {
if (!ref || !yAxis) return
const elms = d3.select(ref).selectAll<SVGRectElement, unknown>('rect').data(data)
elms.exit().remove()
const newElms = elms.enter().append('rect')
elms.merge(newElms)
.attr('width', width)
.attr('height', (d) => Math.max(yAxis(d.dateEnd) - yAxis(d.dateStart), 1))
.attr('y', (d) => yAxis(d.dateStart))
.attr('fill', (d) => regulators[d.id].color)
}, [yAxis, data, ref, width])
return (
<g transform={`translate(${left}, ${top})`} stroke={'#333'} strokeWidth={1} fill={'none'}>
<g ref={setRef} strokeWidth={0} />
<rect x={0} y={0} width={width} height={height} />
</g>
)
}
export const D3MonitoringLimitChart = memo(_D3MonitoringLimitChart) as typeof _D3MonitoringLimitChart
export default D3MonitoringLimitChart