forked from ddrilling/asb_cloud_front
* Данные РТК вынесены в отдельный проп графика
* Добавлена прозрачность РТК * Добавлен метод расчёта данных для РТК
This commit is contained in:
parent
a2d641abdd
commit
44afd5f1f0
@ -116,6 +116,8 @@ export type D3MonitoringChartsProps<DataType extends BaseDataType> = Omit<React.
|
|||||||
loading?: boolean
|
loading?: boolean
|
||||||
/** Массив отображаемых данных */
|
/** Массив отображаемых данных */
|
||||||
data?: DataType[]
|
data?: DataType[]
|
||||||
|
/** Массив данных для прямоугольников */
|
||||||
|
flowData?: DataType[]
|
||||||
/** Отступы графика от края SVG */
|
/** Отступы графика от края SVG */
|
||||||
offset?: Partial<ChartOffset>
|
offset?: Partial<ChartOffset>
|
||||||
/** Цвет фона в формате CSS-значения */
|
/** Цвет фона в формате CSS-значения */
|
||||||
@ -181,6 +183,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
|
|||||||
loading = false,
|
loading = false,
|
||||||
datasetGroups,
|
datasetGroups,
|
||||||
data,
|
data,
|
||||||
|
flowData,
|
||||||
plugins,
|
plugins,
|
||||||
offset: _offset,
|
offset: _offset,
|
||||||
yAxis: _yAxisConfig,
|
yAxis: _yAxisConfig,
|
||||||
@ -493,7 +496,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
|
|||||||
chartData = renderArea<DataType>(xAxis, yAxis, chart, chartData)
|
chartData = renderArea<DataType>(xAxis, yAxis, chart, chartData)
|
||||||
break
|
break
|
||||||
case 'rect_area':
|
case 'rect_area':
|
||||||
renderRectArea<DataType>(xAxis, yAxis, chart)
|
renderRectArea<DataType>(xAxis, yAxis, chart, flowData)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
@ -507,7 +510,7 @@ const _D3MonitoringCharts = <DataType extends Record<string, unknown>>({
|
|||||||
chart.afterDraw?.(chart)
|
chart.afterDraw?.(chart)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, [data, groups, height, offset, sizes, chartDomains, yAxis])
|
}, [data, flowData, groups, height, offset, sizes, chartDomains, yAxis])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal
|
<LoaderPortal
|
||||||
|
@ -6,7 +6,8 @@ import { appendTransition } from './base'
|
|||||||
export const renderRectArea = <DataType extends BaseDataType>(
|
export const renderRectArea = <DataType extends BaseDataType>(
|
||||||
xAxis: (value: d3.NumberValue) => number,
|
xAxis: (value: d3.NumberValue) => number,
|
||||||
yAxis: (value: d3.NumberValue) => number,
|
yAxis: (value: d3.NumberValue) => number,
|
||||||
chart: ChartRegistry<DataType>
|
chart: ChartRegistry<DataType>,
|
||||||
|
data: DataType[] | undefined,
|
||||||
) => {
|
) => {
|
||||||
if (
|
if (
|
||||||
chart.type !== 'rect_area' ||
|
chart.type !== 'rect_area' ||
|
||||||
@ -14,25 +15,27 @@ export const renderRectArea = <DataType extends BaseDataType>(
|
|||||||
!chart.maxXAccessor ||
|
!chart.maxXAccessor ||
|
||||||
!chart.minYAccessor ||
|
!chart.minYAccessor ||
|
||||||
!chart.maxYAccessor ||
|
!chart.maxYAccessor ||
|
||||||
!chart.data
|
!data
|
||||||
) return
|
) return
|
||||||
|
|
||||||
const data = chart.data
|
|
||||||
const xMin = getByAccessor(chart.minXAccessor)
|
const xMin = getByAccessor(chart.minXAccessor)
|
||||||
const xMax = getByAccessor(chart.maxXAccessor)
|
const xMax = getByAccessor(chart.maxXAccessor)
|
||||||
const yMin = getByAccessor(chart.minYAccessor)
|
const yMin = getByAccessor(chart.minYAccessor)
|
||||||
const yMax = getByAccessor(chart.maxYAccessor)
|
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)
|
const rects = chart().selectAll<SVGRectElement, null>('rect').data(data)
|
||||||
|
|
||||||
rects.exit().remove()
|
rects.exit().remove()
|
||||||
rects.enter().append('rect')
|
rects.enter().append('rect')
|
||||||
|
|
||||||
appendTransition(chart().selectAll<SVGRectElement, Record<string, any>>('rect'), chart)
|
appendTransition(chart().selectAll<SVGRectElement, Record<string, any>>('rect'), chart)
|
||||||
.attr('x1', (d) => xAxis(xMin(d)))
|
.attr('x', (d) => xAxis(xMin(d)))
|
||||||
.attr('x2', (d) => xAxis(xMax(d)))
|
.attr('y', (d) => yAxis(yMin(d)))
|
||||||
.attr('y1', (d) => yAxis(yMin(d)))
|
.attr('width', (d) => xAxis(xMax(d)) - xAxis(xMin(d)))
|
||||||
.attr('y2', (d) => yAxis(yMax(d)))
|
.attr('height', (d) => yAxis(yMax(d)) - yAxis(yMin(d)))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { formatDate } from "@utils"
|
import { formatDate } from '@utils'
|
||||||
|
|
||||||
export const yAxis = {
|
export const yAxis = {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
@ -22,19 +22,46 @@ const makeDataset = (label, shortLabel, color, key, unit, other) => ({
|
|||||||
...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) => ({
|
const makeAreaOptions = (accessor) => ({
|
||||||
type: 'rect_area',
|
type: 'rect_area',
|
||||||
data: flowChart,
|
|
||||||
hideLabel: true,
|
hideLabel: true,
|
||||||
yAxis: {
|
minYAccessor: 'dateStart',
|
||||||
type: 'linear',
|
maxYAccessor: 'dateEnd',
|
||||||
accessor: 'depth',
|
minXAccessor: accessor + 'Min',
|
||||||
},
|
maxXAccessor: accessor + 'Max',
|
||||||
minXAccessor: 'depthStart',
|
|
||||||
maxXAccessor: 'depthEnd',
|
|
||||||
minYAccessor: accessor + 'Min',
|
|
||||||
maxYAccessor: accessor + 'Max',
|
|
||||||
linkedTo: accessor,
|
linkedTo: accessor,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
TelemetryDataSpinService
|
TelemetryDataSpinService
|
||||||
} from '@api'
|
} 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 { ADDITIVE_PAGES, cutData, DATA_COUNT, getLoadingInterval, makeDateTimeDisabled } from './archive_methods'
|
||||||
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
||||||
import TelemetrySummary from './TelemetrySummary'
|
import TelemetrySummary from './TelemetrySummary'
|
||||||
@ -94,8 +94,6 @@ const TelemetryView = memo(() => {
|
|||||||
|
|
||||||
const onStatusChanged = useCallback((value) => updateWell({ idState: value }), [well])
|
const onStatusChanged = useCallback((value) => updateWell({ idState: value }), [well])
|
||||||
|
|
||||||
const dateTimeDisabled = useMemo(() => makeDateTimeDisabled(dateLimit, chartInterval), [dateLimit, chartInterval])
|
|
||||||
|
|
||||||
const handleDataSaub = useCallback((data, replace = false) => {
|
const handleDataSaub = useCallback((data, replace = false) => {
|
||||||
setDataSaub((prev) => {
|
setDataSaub((prev) => {
|
||||||
if (!data || !Array.isArray(data))
|
if (!data || !Array.isArray(data))
|
||||||
@ -137,6 +135,8 @@ const TelemetryView = memo(() => {
|
|||||||
}
|
}
|
||||||
}, [archiveMode, loadedDataRange, chartInterval, dateLimit])
|
}, [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 domain = useMemo(() => ({ min: new Date(+endDate - chartInterval), max: endDate }), [endDate, chartInterval])
|
||||||
|
|
||||||
const spinLast = useMemo(() => getLast(dataSpin), [dataSpin])
|
const spinLast = useMemo(() => getLast(dataSpin), [dataSpin])
|
||||||
@ -146,7 +146,9 @@ const TelemetryView = memo(() => {
|
|||||||
const saubSubject$ = useMemo(() => new BehaviorSubject(), [])
|
const saubSubject$ = useMemo(() => new BehaviorSubject(), [])
|
||||||
const spinSubject$ = 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(() => {
|
useEffect(() => {
|
||||||
if (!searchParams.has('range') || !searchParams.has('end')) return
|
if (!searchParams.has('range') || !searchParams.has('end')) return
|
||||||
@ -253,8 +255,6 @@ const TelemetryView = memo(() => {
|
|||||||
setEndDate(new Date(saubLast.date))
|
setEndDate(new Date(saubLast.date))
|
||||||
}, [archiveMode, saubLast])
|
}, [archiveMode, saubLast])
|
||||||
|
|
||||||
const filteredData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LoaderPortal show={showLoader} style={{ flexGrow: 1 }}>
|
<LoaderPortal show={showLoader} style={{ flexGrow: 1 }}>
|
||||||
<div className={'telemetry-view-page'}>
|
<div className={'telemetry-view-page'}>
|
||||||
@ -312,6 +312,7 @@ const TelemetryView = memo(() => {
|
|||||||
{...chartProps}
|
{...chartProps}
|
||||||
yDomain={domain}
|
yDomain={domain}
|
||||||
data={filteredData}
|
data={filteredData}
|
||||||
|
flowData={flowData}
|
||||||
methods={setChartMethods}
|
methods={setChartMethods}
|
||||||
datasetGroups={chartGroups}
|
datasetGroups={chartGroups}
|
||||||
onWheel={onWheel}
|
onWheel={onWheel}
|
||||||
|
Loading…
Reference in New Issue
Block a user