diff --git a/src/components/d3/monitoring/D3MonitoringCharts.tsx b/src/components/d3/monitoring/D3MonitoringCharts.tsx index 3edb11e..df06431 100644 --- a/src/components/d3/monitoring/D3MonitoringCharts.tsx +++ b/src/components/d3/monitoring/D3MonitoringCharts.tsx @@ -116,6 +116,8 @@ export type D3MonitoringChartsProps = Omit /** Цвет фона в формате CSS-значения */ @@ -181,6 +183,7 @@ const _D3MonitoringCharts = >({ loading = false, datasetGroups, data, + flowData, plugins, offset: _offset, yAxis: _yAxisConfig, @@ -493,7 +496,7 @@ const _D3MonitoringCharts = >({ chartData = renderArea(xAxis, yAxis, chart, chartData) break case 'rect_area': - renderRectArea(xAxis, yAxis, chart) + renderRectArea(xAxis, yAxis, chart, flowData) break default: break @@ -507,7 +510,7 @@ const _D3MonitoringCharts = >({ chart.afterDraw?.(chart) }) }) - }, [data, groups, height, offset, sizes, chartDomains, yAxis]) + }, [data, flowData, groups, height, offset, sizes, chartDomains, yAxis]) return ( ( xAxis: (value: d3.NumberValue) => number, yAxis: (value: d3.NumberValue) => number, - chart: ChartRegistry + chart: ChartRegistry, + data: DataType[] | undefined, ) => { if ( chart.type !== 'rect_area' || @@ -14,25 +15,27 @@ export const renderRectArea = ( !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('rect').data(data) rects.exit().remove() rects.enter().append('rect') - + appendTransition(chart().selectAll>('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))) } diff --git a/src/pages/Well/Telemetry/TelemetryView/dataset.js b/src/pages/Well/Telemetry/TelemetryView/dataset.js index 3f96262..4e90c09 100644 --- a/src/pages/Well/Telemetry/TelemetryView/dataset.js +++ b/src/pages/Well/Telemetry/TelemetryView/dataset.js @@ -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, }) diff --git a/src/pages/Well/Telemetry/TelemetryView/index.jsx b/src/pages/Well/Telemetry/TelemetryView/index.jsx index 256b2f0..ee21a85 100644 --- a/src/pages/Well/Telemetry/TelemetryView/index.jsx +++ b/src/pages/Well/Telemetry/TelemetryView/index.jsx @@ -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 (
@@ -312,6 +312,7 @@ const TelemetryView = memo(() => { {...chartProps} yDomain={domain} data={filteredData} + flowData={flowData} methods={setChartMethods} datasetGroups={chartGroups} onWheel={onWheel}