diff --git a/src/pages/Telemetry/Archive/ArchiveColumn.jsx b/src/pages/Telemetry/Archive/ArchiveColumn.jsx
deleted file mode 100755
index 6f7ebfb..0000000
--- a/src/pages/Telemetry/Archive/ArchiveColumn.jsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { memo, useMemo } from 'react'
-
-import { Grid, GridItem } from '@components/Grid'
-import { Column } from '@components/charts/Column'
-
-export const ArchiveColumn = memo(({ lineGroup, data, interval, style, headerHeight, yStart }) => {
- const lgws = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup])
- const pv = useMemo(() => lgws.filter(line => line.showLabels).map(line => ({
- color: line.color,
- label: line.label
- })), [lgws])
-
- return (
-
-
- {pv?.map((v, idx) => (
- {v.label}
- ))}
-
-
-
- )
-})
-
-export default ArchiveColumn
diff --git a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx b/src/pages/Telemetry/Archive/ArchiveDisplay.jsx
deleted file mode 100755
index c3310ba..0000000
--- a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { memo, useMemo } from 'react'
-
-import { Grid, GridItem } from '@components/Grid'
-
-import { paramsGroups } from '../TelemetryView'
-import { ArchiveColumn } from './ArchiveColumn'
-
-const interpolationSearch = (data, begin, end, accessor) => {
- const fy = (i) => new Date(data[i]?.[accessor] ?? 0)
- const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b)))
- const findIdx = (val, startIdx, c) => {
- let x = startIdx
- let endIdx = data.length - 1
- if(val < fy(startIdx))
- return startIdx
- if(val > fy(endIdx))
- return endIdx
- for(let i = 0; i < c; i++){
- x = fx(val, startIdx, endIdx)
- if(fy(x) < val)
- startIdx = x
- else
- endIdx = x
- if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx)))
- return x
- }
- return x
- }
- let x0 = findIdx(begin, 0, 5)
- let x1 = findIdx(end, x0, 3)
- return { start: x0, end: x1, count: x1 - x0 }
-}
-
-export const cutData = (data, beginDate, endDate) => {
- if (data?.length > 0) {
- let { start, end } = interpolationSearch(data, beginDate, endDate, 'date')
- if (start > 0) start--
- if (end + 1 < end.length) end++
- return data.slice(start, end)
- }
- return data
-}
-
-export const ArchiveDisplay = memo(({data, startDate, interval, onWheel}) => {
- const endDate = useMemo(() => new Date(+startDate + interval), [startDate, interval])
- const chartData = useMemo(() => cutData(data, startDate, endDate), [data, startDate, endDate])
-
- return (
-
- {paramsGroups.map((group, index) => (
-
-
-
- ))}
-
- )
-})
-
-export default ArchiveDisplay
diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx
index 909a480..4608520 100755
--- a/src/pages/Telemetry/Archive/index.jsx
+++ b/src/pages/Telemetry/Archive/index.jsx
@@ -1,24 +1,30 @@
/* eslint-disable react-hooks/exhaustive-deps */
-import { useState, useEffect, memo, useCallback } from 'react'
+import { useState, useEffect, memo, useCallback, useMemo } from 'react'
import { useSearchParams } from 'react-router-dom'
import { useIdWell } from '@asb/context'
import { Flex } from '@components/Grid'
+import { D3MonitoringCharts } from '@components/d3'
import { CopyUrlButton } from '@components/CopyUrl'
import LoaderPortal from '@components/LoaderPortal'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { DatePickerWrapper, makeDateSorter } from '@components/Table'
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
-import { range, wrapPrivateComponent } from '@utils'
+import { formatDate, range, wrapPrivateComponent } from '@utils'
import { TelemetryDataSaubService } from '@api'
-import { normalizeData } from '../TelemetryView'
-import { ArchiveDisplay, cutData } from './ArchiveDisplay'
+import { chartGroups, normalizeData } from '../TelemetryView'
+import { Select } from 'antd'
const DATA_COUNT = 2048 // Колличество точек на подгрузку графика
const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков
const LOADING_TRIGGER = 0.5
-const WHEEL_SENSITIVITY = 1 / 530
+
+const scrollOptions = [
+ { label: '10%', value: 0.1 },
+ { label: '15%', value: 0.15 },
+ { label: '25%', value: 0.25 },
+]
const getLoadingInterval = (loaded, startDate, interval) => {
// Если данные загружены и дата не заходит за тригер дозагрузка не требуется
@@ -58,6 +64,42 @@ const getLoadingInterval = (loaded, startDate, interval) => {
}
}
+const interpolationSearch = (data, begin, end, accessor) => {
+ const fy = (i) => new Date(data[i]?.[accessor] ?? 0)
+ const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b)))
+ const findIdx = (val, startIdx, c) => {
+ let x = startIdx
+ let endIdx = data.length - 1
+ if(val < fy(startIdx))
+ return startIdx
+ if(val > fy(endIdx))
+ return endIdx
+ for(let i = 0; i < c; i++){
+ x = fx(val, startIdx, endIdx)
+ if(fy(x) < val)
+ startIdx = x
+ else
+ endIdx = x
+ if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx)))
+ return x
+ }
+ return x
+ }
+ let x0 = findIdx(begin, 0, 5)
+ let x1 = findIdx(end, x0, 3)
+ return { start: x0, end: x1, count: x1 - x0 }
+}
+
+export const cutData = (data, beginDate, endDate) => {
+ if (data?.length > 0) {
+ let { start, end } = interpolationSearch(data, beginDate, endDate, 'date')
+ if (start > 0) start--
+ if (end + 1 < end.length) end++
+ return data.slice(start, end)
+ }
+ return data
+}
+
const Archive = memo(() => {
const [dataSaub, setDataSaub] = useState([])
const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() })
@@ -70,20 +112,21 @@ const Archive = memo(() => {
const getInitialRange = useCallback(() => parseInt(search.get('range') ?? defaultPeriod) * 1000, [search])
const getInitialDate = useCallback(() => new Date(search.get('start') ?? (Date.now() - chartInterval)), [search])
+ const [scrollPercent, setScrollPercent] = useState(0.15)
const [chartInterval, setChartInterval] = useState(getInitialRange)
const [startDate, setStartDate] = useState(getInitialDate)
const onGraphWheel = useCallback((e) => {
if (loaded && dateLimit.from && dateLimit.to) {
setStartDate((prevStartDate) => {
- const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY
+ const offset = e.deltaY / 100 * chartInterval * scrollPercent
const nextStartDate = +prevStartDate + offset
const firstPossibleDate = Math.max(loaded.start, dateLimit.from)
const lastPossibleDate = Math.min(dateLimit.to, (loaded.end ?? Date.now())) - chartInterval
return new Date(Math.max(firstPossibleDate, Math.min(nextStartDate, lastPossibleDate)))
})
}
- }, [loaded, dateLimit, chartInterval])
+ }, [loaded, dateLimit, chartInterval, scrollPercent])
const isDateDisabled = useCallback((date) => {
if (!date) return false
@@ -171,6 +214,9 @@ const Archive = memo(() => {
setDataSaub([])
}, [])
+ const domain = useMemo(() => ({ min: startDate, max: new Date(+startDate + chartInterval)}), [startDate, chartInterval])
+ const chartData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain])
+
return (
<>
@@ -187,13 +233,23 @@ const Archive = memo(() => {
Период:
+
+ Прокрутка:
+
+
- formatDate(d)
+ }}
+ plugins={{ menu: { enabled: false }}}
+ height={'76vh'}
onWheel={onGraphWheel}
/>
diff --git a/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx b/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx
deleted file mode 100755
index af7d928..0000000
--- a/src/pages/Telemetry/TelemetryView/ChartTimeOnlineFooter.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import { memo } from 'react'
-import { Popover } from 'antd'
-import { ControlOutlined } from '@ant-design/icons'
-
-import { ValueDisplay } from '@components/Display'
-
-export const ChartTimeOnlineFooter = memo(({ data, lineGroup }) => {
- const getFooterData = (name) => {
- const dataIdx = data && lineGroup?.find(line => line?.footer === name)?.xAccessorName
- return ()
- }
-
- const spValues = getFooterData('SP')
- const idleValues = getFooterData('IDLE')
-
- const popContent = lineGroup?.filter(line => line.footer === true).map(line => (
-
- {line.label}
-
-
- ))
-
- return(
-
- {popContent?.length > 0 ? (
-
-
-
- ) : (
-
- )}
-
-
- )
-})
-
-export default ChartTimeOnlineFooter
diff --git a/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx b/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx
deleted file mode 100755
index b01e274..0000000
--- a/src/pages/Telemetry/TelemetryView/MonitoringColumn.jsx
+++ /dev/null
@@ -1,123 +0,0 @@
-import { memo, useCallback, useEffect, useMemo, useState } from 'react'
-
-import { Grid, GridItem } from '@components/Grid'
-import { makeDateSorter } from '@components/Table'
-import { Column, GetOrCreateDatasetByLineConfig } from '@components/charts/Column'
-
-import { ChartTimeOnlineFooter } from './ChartTimeOnlineFooter'
-
-const GetLimitShape = (flowChartData, points, accessor) => {
- const min = [], max = []
-
- for (const point of points) {
- const program = flowChartData?.find(v => v.depthStart < point.depth && point.depth < v.depthEnd)
- if (!program) continue
-
- min.push({ x: program[`${accessor}Min`], y: new Date(point.y), label: point.label })
- max.push({ x: program[`${accessor}Max`], y: new Date(point.y), label: point.label })
- }
-
- return min.concat(max.reverse()) ?? []
-}
-
-const RemoveSimilar = (input, accessor) => {
- if (!input || input.length <= 0) return input
- const data = [input[0]]
- for (let i = 1; i < input.length; i++)
- if (input[i][accessor] !== input[i - 1][accessor])
- data.push(input[i])
- return data
-}
-
-const addPointData = (point) => ({ depth: point.wellDepth })
-
-const ChartValues = memo(({ pv }) => pv?.map((v, idx) => {
- const text = `${v.value?.toFixed(2) ?? '--'} ${v.unit}`
- return (
-
- )
-}))
-
-export const MonitoringColumn = memo(({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, pointCount = 2048, additionalLabels }) => {
- const [dataStore, setDataStore] = useState([])
- const dataLast = useMemo(() => data?.[data.length - 1], [data])
- const yStart = useMemo(() => new Date((dataLast?.date ? +new Date(dataLast.date) : Date.now()) - interval * 0.97), [dataLast, interval])
- const pv = useMemo(() => lineGroup.filter(line => line.showLabels).map(line => ({
- color: line.color,
- label: line.label,
- unit: line.units,
- value: dataLast?.[line.xAccessorName]
- })), [lineGroup, dataLast])
-
- const lineGroupWithoutShapes = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup])
-
- const postParsing = useCallback((data) => {
- lineGroupWithoutShapes.forEach(lineCfg => {
- const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg)
-
- if (flowChartData) {
- lineGroup.filter(cfg => cfg.isShape && cfg.xAccessorName === lineCfg.xAccessorName).forEach(areaCfg => {
- const dataset = GetOrCreateDatasetByLineConfig(data.data, areaCfg)
- dataset.data = GetLimitShape(flowChartData, lineDataSet.data, areaCfg.xAccessorName)
- })
- }
- })
- }, [lineGroupWithoutShapes, flowChartData, lineGroup])
-
- useEffect(() => {
- setDataStore(prevData => {
- let newData = [...prevData, ...data]
- newData.sort(makeDateSorter('date'))
- newData = RemoveSimilar(newData, 'date')
- if (newData.length > pointCount)
- newData.splice(0, pointCount - newData.length)
- return newData
- })
- }, [data, pointCount])
-
- return (
-
-
- {pv?.map((v, idx) => (
- {v.label}
- ))}
-
-
-
-
- {additionalLabels?.map((label, idx) => (
-
- ))}
-
-
-
-
-
- )
-})
-
-export default MonitoringColumn
diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx
index 7071e2b..0464f8d 100755
--- a/src/pages/Telemetry/TelemetryView/index.jsx
+++ b/src/pages/Telemetry/TelemetryView/index.jsx
@@ -1,13 +1,14 @@
import { Select } from 'antd'
-import { useState, useEffect, useCallback, memo } from 'react'
+import { useState, useEffect, useCallback, memo, useMemo } from 'react'
import { useIdWell } from '@asb/context'
import { makeDateSorter } from '@components/Table'
+import { D3MonitoringCharts } from '@components/d3'
import LoaderPortal from '@components/LoaderPortal'
import { Grid, GridItem, Flex } from '@components/Grid'
import { invokeWebApiWrapperAsync } from '@components/factory'
import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
-import { hasPermission, wrapPrivateComponent } from '@utils'
+import { formatDate, hasPermission, wrapPrivateComponent } from '@utils'
import { Subscribe } from '@services/signalr'
import {
DrillFlowChartService,
@@ -17,7 +18,6 @@ import {
WellService
} from '@api'
-import { MonitoringColumn } from './MonitoringColumn'
import { CustomColumn } from './CustomColumn'
import ActiveMessagesOnline from './ActiveMessagesOnline'
import { ModeDisplay } from './ModeDisplay'
@@ -34,241 +34,61 @@ import '@styles/message.css'
const { Option } = Select
+const yAxis = {
+ type: 'time',
+ accessor: (d) => new Date(d.date),
+ format: (d) => formatDate(d),
+}
+
const dash = [7, 3]
-const blockHeightGroup = [
- {
- label: 'Высота блока',
- units: 'м',
- xAccessorName: 'blockPosition',
- yAccessorName: 'date',
- color: '#333',
- showLabels: true
- }, {
- label: 'Глубина скважины',
- units: 'м',
- xAccessorName: 'wellDepth',
- yAccessorName: 'date',
- color: '#333',
- showLine: false,
- showDatalabels: true,
- xConstValue: 50,
- dash
- }, {
- label: 'Расход',
- units: 'л/c',
- xAccessorName: 'flow',
- yAccessorName: 'date',
- color: '#077',
- showLabels: true,
- showLine: true
- }, {
- label: 'Предел расхода',
- units: 'л/с',
- xAccessorName: 'flow',
- yAccessorName: 'date',
- color: 'rgba(0,119,119,.1)',
- isShape: true
- }
-]
+const makeDataset = (label, color, key, unit, other) => ({
+ key,
+ label,
+ color,
+ yAxis,
+ xAxis: {
+ type: 'linear',
+ accessor: key,
+ unit,
+ },
+ type: 'line',
+ ...other,
+})
-const blockSpeedGroup = [
- {
- label: 'Скорость блока',
- units: 'м/ч',
- xAccessorName: 'blockSpeed',
- yAccessorName: 'date',
- color: '#0a0',
- showLabels: true,
- }, {
- label: 'Скорость заданная',
- units: 'м/ч',
- xAccessorName: 'blockSpeedSp',
- yAccessorName: 'date',
- color: '#0a0',
- footer: 'SP',
- dash
- }
-]
-
-const pressureGroup = [
- {
- label: 'Давление',
- units: 'атм',
- xAccessorName: 'pressure',
- yAccessorName: 'date',
- color: '#c00',
- showLabels: true
- }, {
- label: 'Давление заданное',
- units: 'атм',
- xAccessorName: 'pressureSp',
- yAccessorName: 'date',
- color: '#c00',
- footer: 'SP',
- dash
- }, {
- label: 'Давление ХХ',
- units: 'атм',
- xAccessorName: 'pressureIdle',
- yAccessorName: 'date',
- color: '#c00',
- footer: 'IDLE',
- dash
- }, {
- label: 'Перепад давления максимальный',
- units: 'атм',
- xAccessorName: 'pressureDeltaLimitMax',
- yAccessorName: 'date',
- color: '#c00',
- footer: true,
- dash
- }, {
- label: 'Предел давления заданный',
- units: 'атм',
- xAccessorName: 'pressure',
- yAccessorName: 'date',
- color: 'rgba(204,0,0,.1)',
- isShape: true
- }
-]
-
-const axialLoadGroup = [
- {
- label: 'Осевая нагрузка',
- units: 'т',
- xAccessorName: 'axialLoad',
- yAccessorName: 'date',
- color: '#00a',
- showLabels: true
- }, {
- label: 'Осевая нагрузка заданная',
- units: 'т',
- xAccessorName: 'axialLoadSp',
- yAccessorName: 'date',
- color: '#00a',
- footer: 'SP',
- dash
- }, {
- label: 'Осевая нагрузка максимальная',
- units: 'т',
- xAccessorName: 'axialLoadLimitMax',
- yAccessorName: 'date',
- color: '#00a',
- footer: true,
- dash
- }, {
- label: 'Пределы осевой нагрузки',
- units: 'т',
- xAccessorName: 'axialLoad',
- yAccessorName: 'date',
- color: 'rgba(0,0,170,.1)',
- isShape: true
- }
-]
-
-const hookWeightGroup = [
- {
- label: 'Вес на крюке',
- units: 'т',
- xAccessorName: 'hookWeight',
- yAccessorName: 'date',
- color: '#0aa',
- showLabels: true
- }, {
- label: 'Вес инструмента ХХ',
- units: 'т',
- xAccessorName: 'hookWeightIdle',
- yAccessorName: 'date',
- color: '#0aa',
- footer: 'IDLE',
- dash
- }, {
- label: 'Вес инструмента минимальный',
- units: 'т',
- xAccessorName: 'hookWeightLimitMin',
- yAccessorName: 'date',
- color: '#0aa',
- footer: true,
- dash
- }, {
- label: 'Вес инструмента максимальный',
- units: 'т',
- xAccessorName: 'hookWeightLimitMax',
- yAccessorName: 'date',
- color: '#0aa',
- footer: true,
- dash
- }, {
- label: 'Обороты ротора',
- units: 'об/мин',
- xAccessorName: 'rotorSpeed',
- yAccessorName: 'date',
- color: '#aa0',
- showLabels: true
- }, {
- label: 'Скорость вращения ВСП максимальная',
- units: 'об/мин',
- xAccessorName: 'rotorSpeed',
- yAccessorName: 'date',
- color: 'rgba(170,170,0,.1)',
- isShape: true
- }
-]
-
-const rotorTorqueGroup = [
- {
- label: 'Момент на роторе',
- units: 'кН·м',
- xAccessorName: 'rotorTorque',
- yAccessorName: 'date',
- color: '#a0a',
- showLabels: true
- }, {
- label: 'План. Момент на роторе',
- units: 'кН·м',
- xAccessorName: 'rotorTorqueSp',
- yAccessorName: 'date',
- color: '#a0a',
- footer: 'SP',
- dash
- }, {
- label: 'Момент на роторе х.х.',
- units: 'кН·м',
- xAccessorName: 'rotorTorqueIdle',
- yAccessorName: 'date',
- color: '#a0a',
- footer: 'IDLE',
- dash
- }, {
- label: 'Момент максимальный',
- units: 'кН·м',
- xAccessorName: 'rotorTorqueLimitMax',
- yAccessorName: 'date',
- color: '#a0a',
- footer: true,
- dash
- }, {
- label: 'Ограничения момента',
- units: 'кН·м',
- xAccessorName: 'rotorTorque',
- yAccessorName: 'date',
- color: 'rgba(170,0,170,.1)',
- isShape: true
- }
-]
-
-export const paramsGroups = [
- blockHeightGroup,
- blockSpeedGroup,
- pressureGroup,
- axialLoadGroup,
- hookWeightGroup,
- rotorTorqueGroup
+export const chartGroups = [
+ [
+ makeDataset('Высота блока', '#333', 'blockPosition', 'м'),
+ makeDataset('Глубина скважины', '#333', 'wellDepth', 'м', { dash, yDomain: { min: 0, max: 5000, hideXAxis: true } }),
+ makeDataset('Расход', '#077', 'flow', 'л/с'),
+ ], [
+ makeDataset('Скорость блока', '#0a0', 'blockSpeed', 'м/ч'),
+ makeDataset('Скорость заданная', '#0a0', 'blockSpeedSp', 'м/ч', { dash, yDomain: { min: 0, max: 50 } }),
+ ], [
+ makeDataset('Давление', '#c00', 'pressure', 'атм', { yDomain: { min: 50, max: 150 } }),
+ makeDataset('Давление заданное', '#c00', 'pressureSp', 'атм', { yDomain: { min: 50, max: 150 } }),
+ makeDataset('Давление ХХ', '#c00', 'pressureIdle', 'атм', { dash, yDomain: { min: 50, max: 150 } }),
+ makeDataset('Перепад давления максимальный', '#c00', 'pressureDeltaLimitMax', 'атм', { dash, yDomain: { min: 50, max: 150 } }),
+ ], [
+ makeDataset('Осевая нагрузка', '#00a', 'axialLoad', 'т', { yDomain: { min: 0, max: 15 } }),
+ makeDataset('Осевая нагрузка заданная', '#00a', 'axialLoadSp', 'т', { dash, yDomain: { min: 0, max: 15 } }),
+ makeDataset('Осевая нагрузка максимальная', '#00a', 'axialLoadLimitMax', 'т', { dash, yDomain: { min: 0, max: 15 } }),
+ ], [
+ makeDataset('Вес на крюке', '#0aa', 'hookWeight', 'т', { yDomain: { min: 0, max: 80 } }),
+ makeDataset('Вес инструмента ХХ', '#0aa', 'hookWeightIdle', 'т', { dash, yDomain: { min: 0, max: 80 } }),
+ makeDataset('Вес инструмента минимальный', '#0aa', 'hookWeightLimitMin', 'т', { dash, yDomain: { min: 0, max: 80 } }),
+ makeDataset('Вес инструмента максимальный', '#0aa', 'hookWeightLimitMax', 'т', { dash, yDomain: { min: 0, max: 80 } }),
+ makeDataset('Обороты ротора', '#0aa', 'rotorSpeed', 'об/мин', { yDomain: { min: 0, max: 80 } }),
+ ], [
+ makeDataset('Момент на роторе', '#a0a', 'rotorTorque', 'кН·м', { yDomain: { min: 0, max: 30 } }),
+ makeDataset('План. Момент на роторе', '#a0a', 'rotorTorqueSp', 'кН·м', { dash, yDomain: { min: 0, max: 30 } }),
+ makeDataset('Момент на роторе х.х.', '#a0a', 'rotorTorqueIdle', 'кН·м', { dash, yDomain: { min: 0, max: 30 } }),
+ makeDataset('Момент максимальный', '#a0a', 'rotorTorqueLimitMax', 'кН·м', { dash, yDomain: { min: 0, max: 30 } }),
+ ]
]
const getLast = (data) =>
- Array.isArray(data) ? data.slice(-1)[0] : data
+ Array.isArray(data) ? data.at(-1) : data
const isMseEnabled = (dataSaub) => {
const lastData = getLast(dataSaub)
@@ -285,18 +105,6 @@ const isSpinEnabled = (dataSpin) => {
return lastData?.state > 0 && lastData?.state !== 6
}
-const getIndexOfDrillingBy = (dataSaub) => {
- const order = {
- 0: -1,
- 1: 1, // скорость
- 2: 2, // давление
- 3: 3, // нагрузка
- 4: 5, // момент
- }
- const idFeedRegulator = getLast(dataSaub)?.idFeedRegulator ?? 0
- return order[idFeedRegulator] ?? -1
-}
-
export const normalizeData = (data) => data?.map(item => ({
...item,
rotorSpeed: item.rotorSpeed < 1 ? 0 : item.rotorSpeed,
@@ -312,6 +120,7 @@ const TelemetryView = memo(() => {
const [showLoader, setShowLoader] = useState(false)
const [flowChartData, setFlowChartData] = useState([])
const [rop, setRop] = useState(null)
+ const [domain, setDomain] = useState({})
const idWell = useIdWell()
@@ -372,12 +181,30 @@ const TelemetryView = memo(() => {
'Задание состояния скважины'
), [idWell, wellData])
- const columnAdditionalLabels = {
- 1: rop && [
- `ROP сред: ${rop.ropAverage.toFixed(2)} м/ч`,
- `ROP макс: ${rop.ropMax.toFixed(2)} м/ч`
- ]
- }
+ useEffect(() => {
+ if (dataSaub.length <= 0) return
+ const last = new Date(dataSaub.at(-1).date)
+ setDomain({
+ min: new Date(+last - chartInterval * 1000),
+ max: last
+ })
+ }, [dataSaub, chartInterval])
+
+ const filteredData = useMemo(() => {
+ let i, j
+ for (i = 0; i < dataSaub.length; i++) {
+ const date = +new Date(dataSaub[i]?.date)
+ if (date >= +domain.min) break
+ }
+
+ for (j = dataSaub.length - 1; j >= i; j--) {
+ const date = +new Date(dataSaub[i]?.date)
+ if (date <= +domain.max) break
+ }
+
+ if (i >= j) return []
+ return dataSaub.slice(i, j)
+ }, [dataSaub, domain])
return (
@@ -409,21 +236,19 @@ const TelemetryView = memo(() => {
- {paramsGroups.map((group, index) =>
-
-
-
- )}
+
+ formatDate(d)
+ }}
+ plugins={{ menu: { enabled: false }}}
+ height={'70vh'}
+ />
+