* Данные РТК вынесены в отдельный проп графика

* Добавлена прозрачность РТК
* Добавлен метод расчёта данных для РТК
This commit is contained in:
Александр Сироткин 2022-11-22 09:26:44 +05:00
parent a2d641abdd
commit 44afd5f1f0
4 changed files with 62 additions and 28 deletions

View File

@ -116,6 +116,8 @@ export type D3MonitoringChartsProps<DataType extends BaseDataType> = Omit<React.
loading?: boolean
/** Массив отображаемых данных */
data?: DataType[]
/** Массив данных для прямоугольников */
flowData?: DataType[]
/** Отступы графика от края SVG */
offset?: Partial<ChartOffset>
/** Цвет фона в формате CSS-значения */
@ -181,6 +183,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
loading = false,
datasetGroups,
data,
flowData,
plugins,
offset: _offset,
yAxis: _yAxisConfig,
@ -493,7 +496,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
chartData = renderArea<DataType>(xAxis, yAxis, chart, chartData)
break
case 'rect_area':
renderRectArea<DataType>(xAxis, yAxis, chart)
renderRectArea<DataType>(xAxis, yAxis, chart, flowData)
break
default:
break
@ -507,7 +510,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
chart.afterDraw?.(chart)
})
})
}, [data, groups, height, offset, sizes, chartDomains, yAxis])
}, [data, flowData, groups, height, offset, sizes, chartDomains, yAxis])
return (
<LoaderPortal

View File

@ -6,7 +6,8 @@ import { appendTransition } from './base'
export const renderRectArea = <DataType extends BaseDataType>(
xAxis: (value: d3.NumberValue) => number,
yAxis: (value: d3.NumberValue) => number,
chart: ChartRegistry<DataType>
chart: ChartRegistry<DataType>,
data: DataType[] | undefined,
) => {
if (
chart.type !== 'rect_area' ||
@ -14,16 +15,18 @@ export const renderRectArea = <DataType extends BaseDataType>(
!chart.maxXAccessor ||
!chart.minYAccessor ||
!chart.maxYAccessor ||
!chart.data
!data
) return
const data = chart.data
const xMin = getByAccessor(chart.minXAccessor)
const xMax = getByAccessor(chart.maxXAccessor)
const yMin = getByAccessor(chart.minYAccessor)
const yMax = getByAccessor(chart.maxYAccessor)
chart().attr('fill', 'currentColor')
chart()
.attr('fill', 'currentColor')
.attr('fill-opacity', '0.15')
.attr('stroke-opacity', '0.3')
const rects = chart().selectAll<SVGRectElement, null>('rect').data(data)
@ -31,8 +34,8 @@ export const renderRectArea = <DataType extends BaseDataType>(
rects.enter().append('rect')
appendTransition(chart().selectAll<SVGRectElement, Record<string, any>>('rect'), chart)
.attr('x1', (d) => xAxis(xMin(d)))
.attr('x2', (d) => xAxis(xMax(d)))
.attr('y1', (d) => yAxis(yMin(d)))
.attr('y2', (d) => yAxis(yMax(d)))
.attr('x', (d) => xAxis(xMin(d)))
.attr('y', (d) => yAxis(yMin(d)))
.attr('width', (d) => xAxis(xMax(d)) - xAxis(xMin(d)))
.attr('height', (d) => yAxis(yMax(d)) - yAxis(yMin(d)))
}

View File

@ -1,4 +1,4 @@
import { formatDate } from "@utils"
import { formatDate } from '@utils'
export const yAxis = {
type: 'time',
@ -22,19 +22,46 @@ const makeDataset = (label, shortLabel, color, key, unit, other) => ({
...other,
})
export const makeChartGroups = (flowChart) => {
const depthInBetween = (val, flow) => flow.depthStart <= val && val <= flow.depthEnd
export const calcFlowData = (dataSaub, flowChart) => {
if (dataSaub.length < 2) return []
let minDepth = Infinity, maxDepth = -Infinity
const dates = dataSaub.map((row) => {
const depth = row.wellDepth
if (depth < minDepth) minDepth = depth
if (depth > maxDepth) maxDepth = depth
return { date: new Date(row.date), depth: row.wellDepth }
})
const out = flowChart.map((flow) => {
if (flow.depthStart > maxDepth || flow.depthEnd < minDepth) return []
const out = []
let i = 0, j = 0
while (i < dates.length) {
while (i < dates.length && !depthInBetween(dates[i].depth, flow)) i++
j = i++
while (i < dates.length && depthInBetween(dates[i].depth, flow)) i++
if (j >= dates.length || j >= i)
break
out.push({
...flow,
dateStart: dates[j].date,
dateEnd: dates[i - 1].date,
})
}
return out
}).flat()
return out
}
export const makeChartGroups = () => {
const makeAreaOptions = (accessor) => ({
type: 'rect_area',
data: flowChart,
hideLabel: true,
yAxis: {
type: 'linear',
accessor: 'depth',
},
minXAccessor: 'depthStart',
maxXAccessor: 'depthEnd',
minYAccessor: accessor + 'Min',
maxYAccessor: accessor + 'Max',
minYAccessor: 'dateStart',
maxYAccessor: 'dateEnd',
minXAccessor: accessor + 'Min',
maxXAccessor: accessor + 'Max',
linkedTo: accessor,
})

View File

@ -19,7 +19,7 @@ import {
TelemetryDataSpinService
} from '@api'
import { makeChartGroups, yAxis } from './dataset'
import { calcFlowData, makeChartGroups, yAxis } from './dataset'
import { ADDITIVE_PAGES, cutData, DATA_COUNT, getLoadingInterval, makeDateTimeDisabled } from './archive_methods'
import ActiveMessagesOnline from './ActiveMessagesOnline'
import TelemetrySummary from './TelemetrySummary'
@ -94,8 +94,6 @@ const TelemetryView = memo(() => {
const onStatusChanged = useCallback((value) => updateWell({ idState: value }), [well])
const dateTimeDisabled = useMemo(() => makeDateTimeDisabled(dateLimit, chartInterval), [dateLimit, chartInterval])
const handleDataSaub = useCallback((data, replace = false) => {
setDataSaub((prev) => {
if (!data || !Array.isArray(data))
@ -137,6 +135,8 @@ const TelemetryView = memo(() => {
}
}, [archiveMode, loadedDataRange, chartInterval, dateLimit])
const dateTimeDisabled = useMemo(() => makeDateTimeDisabled(dateLimit, chartInterval), [dateLimit, chartInterval])
const domain = useMemo(() => ({ min: new Date(+endDate - chartInterval), max: endDate }), [endDate, chartInterval])
const spinLast = useMemo(() => getLast(dataSpin), [dataSpin])
@ -146,7 +146,9 @@ const TelemetryView = memo(() => {
const saubSubject$ = useMemo(() => new BehaviorSubject(), [])
const spinSubject$ = useMemo(() => new BehaviorSubject(), [])
const chartGroups = useMemo(() => makeChartGroups(flowChartData), [flowChartData])
const filteredData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
const flowData = useMemo(() => calcFlowData(dataSaub, flowChartData), [dataSaub, flowChartData])
const chartGroups = useMemo(() => makeChartGroups(), [])
useEffect(() => {
if (!searchParams.has('range') || !searchParams.has('end')) return
@ -253,8 +255,6 @@ const TelemetryView = memo(() => {
setEndDate(new Date(saubLast.date))
}, [archiveMode, saubLast])
const filteredData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
return (
<LoaderPortal show={showLoader} style={{ flexGrow: 1 }}>
<div className={'telemetry-view-page'}>
@ -312,6 +312,7 @@ const TelemetryView = memo(() => {
{...chartProps}
yDomain={domain}
data={filteredData}
flowData={flowData}
methods={setChartMethods}
datasetGroups={chartGroups}
onWheel={onWheel}