forked from ddrilling/asb_cloud_front
Выделены методы генерации датасетов для графика мониторинга
This commit is contained in:
parent
685191484a
commit
17ccecb2dd
@ -14,8 +14,9 @@ import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
|||||||
import { formatDate, range, withPermissions } from '@utils'
|
import { formatDate, range, withPermissions } from '@utils'
|
||||||
import { TelemetryDataSaubService } from '@api'
|
import { TelemetryDataSaubService } from '@api'
|
||||||
|
|
||||||
import { makeChartGroups, normalizeData, yAxis } from '../TelemetryView'
|
import { normalizeData } from '../TelemetryView'
|
||||||
import cursorRender from '../TelemetryView/cursorRender'
|
import cursorRender from '../TelemetryView/cursorRender'
|
||||||
|
import { makeChartGroups, yAxis } from '../TelemetryView/dataset'
|
||||||
|
|
||||||
const DATA_COUNT = 2048 // Колличество точек на подгрузку графика
|
const DATA_COUNT = 2048 // Колличество точек на подгрузку графика
|
||||||
const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков
|
const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков
|
||||||
@ -108,10 +109,10 @@ const Archive = memo(() => {
|
|||||||
const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() })
|
const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() })
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const [loaded, setLoaded] = useState(null)
|
const [loaded, setLoaded] = useState(null)
|
||||||
|
|
||||||
const [well] = useWell()
|
const [well] = useWell()
|
||||||
const [search, setSearchParams] = useSearchParams()
|
const [search, setSearchParams] = useSearchParams()
|
||||||
|
|
||||||
const getInitialRange = useCallback(() => parseInt(search.get('range') ?? defaultPeriod) * 1000, [search])
|
const getInitialRange = useCallback(() => parseInt(search.get('range') ?? defaultPeriod) * 1000, [search])
|
||||||
|
|
||||||
const [scrollPercent, setScrollPercent] = useState(0.15)
|
const [scrollPercent, setScrollPercent] = useState(0.15)
|
||||||
@ -181,7 +182,7 @@ const Archive = memo(() => {
|
|||||||
}, [well])
|
}, [well])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setStartDate((prev) => new Date(Math.max(dateLimit.from, Math.min(+prev, +dateLimit.to - chartInterval))))
|
setStartDate((prev) => new Date(Math.max(dateLimit.from, Math.min(+prev, +dateLimit.to - chartInterval))))
|
||||||
}, [chartInterval, dateLimit])
|
}, [chartInterval, dateLimit])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -191,11 +192,11 @@ const Archive = memo(() => {
|
|||||||
invokeWebApiWrapperAsync(
|
invokeWebApiWrapperAsync(
|
||||||
async () => {
|
async () => {
|
||||||
const data = await TelemetryDataSaubService.getData(well.id, loadingStartDate.toISOString(), loadingInterval, DATA_COUNT)
|
const data = await TelemetryDataSaubService.getData(well.id, loadingStartDate.toISOString(), loadingInterval, DATA_COUNT)
|
||||||
|
|
||||||
const loadedStartDate = new Date(Math.max(+newLoaded.start, +startDate - chartInterval * ADDITIVE_PAGES))
|
const loadedStartDate = new Date(Math.max(+newLoaded.start, +startDate - chartInterval * ADDITIVE_PAGES))
|
||||||
const loadedEndDate = new Date(Math.min(+newLoaded.end, +startDate + chartInterval * (ADDITIVE_PAGES + 1)))
|
const loadedEndDate = new Date(Math.min(+newLoaded.end, +startDate + chartInterval * (ADDITIVE_PAGES + 1)))
|
||||||
setLoaded({ start: loadedStartDate, end: loadedEndDate })
|
setLoaded({ start: loadedStartDate, end: loadedEndDate })
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
data.forEach(elm => elm.date = new Date(elm.date))
|
data.forEach(elm => elm.date = new Date(elm.date))
|
||||||
setDataSaub((prevDataSaub) => {
|
setDataSaub((prevDataSaub) => {
|
||||||
@ -204,7 +205,7 @@ const Archive = memo(() => {
|
|||||||
return cutData(newData, loadedStartDate, loadedEndDate)
|
return cutData(newData, loadedStartDate, loadedEndDate)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
setShowLoader,
|
setShowLoader,
|
||||||
`Не удалось загрузить данные c ${formatDate(startDate)} по ${formatDate(+startDate + chartInterval)}`,
|
`Не удалось загрузить данные c ${formatDate(startDate)} по ${formatDate(+startDate + chartInterval)}`,
|
||||||
|
77
src/pages/Well/Telemetry/TelemetryView/dataset.js
Normal file
77
src/pages/Well/Telemetry/TelemetryView/dataset.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { formatDate } from "@utils"
|
||||||
|
|
||||||
|
export const yAxis = {
|
||||||
|
type: 'time',
|
||||||
|
accessor: (d) => new Date(d.date),
|
||||||
|
format: (d) => formatDate(d, undefined, 'DD.MM.YYYY HH:mm:ss'),
|
||||||
|
}
|
||||||
|
|
||||||
|
const dash = [7, 3]
|
||||||
|
|
||||||
|
const makeDataset = (label, shortLabel, color, key, unit, other) => ({
|
||||||
|
key,
|
||||||
|
label,
|
||||||
|
shortLabel,
|
||||||
|
color,
|
||||||
|
xAxis: {
|
||||||
|
type: 'linear',
|
||||||
|
accessor: key,
|
||||||
|
unit,
|
||||||
|
},
|
||||||
|
type: 'line',
|
||||||
|
...other,
|
||||||
|
})
|
||||||
|
|
||||||
|
export const makeChartGroups = (flowChart) => {
|
||||||
|
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',
|
||||||
|
linkedTo: accessor,
|
||||||
|
})
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
makeDataset('Высота блока', 'Высота ТБ','#303030', 'blockPosition', 'м'),
|
||||||
|
makeDataset('Глубина скважины', 'Глубина скв','#7789A1', 'wellDepth', 'м', { dash }),
|
||||||
|
makeDataset('Расход', 'Расход','#007070', 'flow', 'л/с'),
|
||||||
|
makeDataset('Положение долота', 'Долото','#B39D59', 'bitPosition', 'м'),
|
||||||
|
makeDataset('Расход', 'Расход','#007070', 'flowMM', 'л/с', makeAreaOptions('flow')),
|
||||||
|
], [
|
||||||
|
makeDataset('Скорость блока', 'Скорость ТБ','#59B359', 'blockSpeed', 'м/ч'),
|
||||||
|
makeDataset('Скорость заданная', 'Скор зад-я','#95B359', 'blockSpeedSp', 'м/ч', { dash }),
|
||||||
|
], [
|
||||||
|
makeDataset('Давление', 'Давл','#FF0000', 'pressure', 'атм'),
|
||||||
|
makeDataset('Давление заданное', 'Давл зад-е','#CC0000', 'pressureSp', 'атм'),
|
||||||
|
makeDataset('Давление ХХ', 'Давл ХХ','#CC4429', 'pressureIdle', 'атм', { dash }),
|
||||||
|
makeDataset('Перепад давления МАКС', 'ΔР макс','#B34A36', 'pressureDeltaLimitMax', 'атм', { dash }),
|
||||||
|
makeDataset('Давление', 'Давл','#FF0000', 'pressureMM', 'атм', makeAreaOptions('pressure')),
|
||||||
|
], [
|
||||||
|
makeDataset('Осевая нагрузка', 'Нагр','#0000CC', 'axialLoad', 'т'),
|
||||||
|
makeDataset('Осевая нагрузка заданная', 'Нагр зад-я','#3D6DCC', 'axialLoadSp', 'т', { dash }),
|
||||||
|
makeDataset('Осевая нагрузка МАКС', 'Нагр макс','#3D3DCC', 'axialLoadLimitMax', 'т', { dash }),
|
||||||
|
makeDataset('Осевая нагрузка', 'Нагр','#0000CC', 'axialLoadMM', 'т', makeAreaOptions('axialLoad')),
|
||||||
|
], [
|
||||||
|
makeDataset('Вес на крюке', 'Вес на крюке','#00B3B3', 'hookWeight', 'т'),
|
||||||
|
makeDataset('Вес инструмента ХХ', 'Вес инст ХХ','#29CCB1', 'hookWeightIdle', 'т', { dash }),
|
||||||
|
makeDataset('Вес инструмента МИН', 'Вес инст мин','#47A1B3', 'hookWeightLimitMin', 'т', { dash }),
|
||||||
|
makeDataset('Вес инструмента МАКС', 'Вес инст мах','#2D7280', 'hookWeightLimitMax', 'т', { dash }),
|
||||||
|
makeDataset('Обороты ротора', 'Об ротора','#11B32F', 'rotorSpeed', 'об/мин'),
|
||||||
|
makeDataset('Обороты ротора', 'Об ротора','#11B32F', 'rotorSpeedMM', 'об/мин', makeAreaOptions('rotorSpeed')),
|
||||||
|
], [
|
||||||
|
makeDataset('Момент на роторе', 'Момент','#990099', 'rotorTorque', 'кН·м'),
|
||||||
|
makeDataset('План. Момент на роторе', 'Момент зад-й','#9629CC', 'rotorTorqueSp', 'кН·м', { dash }),
|
||||||
|
makeDataset('Момент на роторе ХХ', 'Момент ХХ','#CC2996', 'rotorTorqueIdle', 'кН·м', { dash }),
|
||||||
|
makeDataset('Момент МАКС.', 'Момент макс','#FF00FF', 'rotorTorqueLimitMax', 'кН·м', { dash }),
|
||||||
|
makeDataset('Момент на роторе', 'Момент','#990099', 'rotorTorqueMM', 'кН·м', makeAreaOptions('rotorTorque')),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -12,12 +12,13 @@ import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker'
|
|||||||
import { formatDate, hasPermission, withPermissions } from '@utils'
|
import { formatDate, hasPermission, withPermissions } from '@utils'
|
||||||
import { Subscribe } from '@services/signalr'
|
import { Subscribe } from '@services/signalr'
|
||||||
import {
|
import {
|
||||||
DrillFlowChartService,
|
DrillFlowChartService,
|
||||||
OperationStatService,
|
OperationStatService,
|
||||||
TelemetryDataSaubService,
|
TelemetryDataSaubService,
|
||||||
TelemetryDataSpinService
|
TelemetryDataSpinService
|
||||||
} from '@api'
|
} from '@api'
|
||||||
|
|
||||||
|
import { makeChartGroups, yAxis } from './dataset'
|
||||||
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
import ActiveMessagesOnline from './ActiveMessagesOnline'
|
||||||
import WirelineRunOut from './WirelineRunOut'
|
import WirelineRunOut from './WirelineRunOut'
|
||||||
import { CustomColumn } from './CustomColumn'
|
import { CustomColumn } from './CustomColumn'
|
||||||
@ -36,286 +37,196 @@ import '@styles/message.less'
|
|||||||
|
|
||||||
const { Option } = Select
|
const { Option } = Select
|
||||||
|
|
||||||
export const yAxis = {
|
const getLast = (data) => Array.isArray(data) ? data.at(-1) : data
|
||||||
type: 'time',
|
|
||||||
accessor: (d) => new Date(d.date),
|
|
||||||
format: (d) => formatDate(d, undefined, 'DD.MM.YYYY HH:mm:ss'),
|
|
||||||
}
|
|
||||||
|
|
||||||
const dash = [7, 3]
|
|
||||||
|
|
||||||
const makeDataset = (label, shortLabel, color, key, unit, other) => ({
|
|
||||||
key,
|
|
||||||
label,
|
|
||||||
shortLabel,
|
|
||||||
color,
|
|
||||||
xAxis: {
|
|
||||||
type: 'linear',
|
|
||||||
accessor: key,
|
|
||||||
unit,
|
|
||||||
},
|
|
||||||
type: 'line',
|
|
||||||
...other,
|
|
||||||
})
|
|
||||||
|
|
||||||
export const makeChartGroups = (flowChart) => {
|
|
||||||
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',
|
|
||||||
linkedTo: accessor,
|
|
||||||
})
|
|
||||||
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
makeDataset('Высота блока', 'Высота ТБ','#303030', 'blockPosition', 'м'),
|
|
||||||
makeDataset('Глубина скважины', 'Глубина скв','#7789A1', 'wellDepth', 'м', { dash }),
|
|
||||||
makeDataset('Расход', 'Расход','#007070', 'flow', 'л/с'),
|
|
||||||
makeDataset('Положение долота', 'Долото','#B39D59', 'bitPosition', 'м'),
|
|
||||||
makeDataset('Расход', 'Расход','#007070', 'flowMM', 'л/с', makeAreaOptions('flow')),
|
|
||||||
], [
|
|
||||||
makeDataset('Скорость блока', 'Скорость ТБ','#59B359', 'blockSpeed', 'м/ч'),
|
|
||||||
makeDataset('Скорость заданная', 'Скор зад-я','#95B359', 'blockSpeedSp', 'м/ч', { dash }),
|
|
||||||
], [
|
|
||||||
makeDataset('Давление', 'Давл','#FF0000', 'pressure', 'атм'),
|
|
||||||
makeDataset('Давление заданное', 'Давл зад-е','#CC0000', 'pressureSp', 'атм'),
|
|
||||||
makeDataset('Давление ХХ', 'Давл ХХ','#CC4429', 'pressureIdle', 'атм', { dash }),
|
|
||||||
makeDataset('Перепад давления МАКС', 'ΔР макс','#B34A36', 'pressureDeltaLimitMax', 'атм', { dash }),
|
|
||||||
makeDataset('Давление', 'Давл','#FF0000', 'pressureMM', 'атм', makeAreaOptions('pressure')),
|
|
||||||
], [
|
|
||||||
makeDataset('Осевая нагрузка', 'Нагр','#0000CC', 'axialLoad', 'т'),
|
|
||||||
makeDataset('Осевая нагрузка заданная', 'Нагр зад-я','#3D6DCC', 'axialLoadSp', 'т', { dash }),
|
|
||||||
makeDataset('Осевая нагрузка МАКС', 'Нагр макс','#3D3DCC', 'axialLoadLimitMax', 'т', { dash }),
|
|
||||||
makeDataset('Осевая нагрузка', 'Нагр','#0000CC', 'axialLoadMM', 'т', makeAreaOptions('axialLoad')),
|
|
||||||
], [
|
|
||||||
makeDataset('Вес на крюке', 'Вес на крюке','#00B3B3', 'hookWeight', 'т'),
|
|
||||||
makeDataset('Вес инструмента ХХ', 'Вес инст ХХ','#29CCB1', 'hookWeightIdle', 'т', { dash }),
|
|
||||||
makeDataset('Вес инструмента МИН', 'Вес инст мин','#47A1B3', 'hookWeightLimitMin', 'т', { dash }),
|
|
||||||
makeDataset('Вес инструмента МАКС', 'Вес инст мах','#2D7280', 'hookWeightLimitMax', 'т', { dash }),
|
|
||||||
makeDataset('Обороты ротора', 'Об ротора','#11B32F', 'rotorSpeed', 'об/мин'),
|
|
||||||
makeDataset('Обороты ротора', 'Об ротора','#11B32F', 'rotorSpeedMM', 'об/мин', makeAreaOptions('rotorSpeed')),
|
|
||||||
], [
|
|
||||||
makeDataset('Момент на роторе', 'Момент','#990099', 'rotorTorque', 'кН·м'),
|
|
||||||
makeDataset('План. Момент на роторе', 'Момент зад-й','#9629CC', 'rotorTorqueSp', 'кН·м', { dash }),
|
|
||||||
makeDataset('Момент на роторе ХХ', 'Момент ХХ','#CC2996', 'rotorTorqueIdle', 'кН·м', { dash }),
|
|
||||||
makeDataset('Момент МАКС.', 'Момент макс','#FF00FF', 'rotorTorqueLimitMax', 'кН·м', { dash }),
|
|
||||||
makeDataset('Момент на роторе', 'Момент','#990099', 'rotorTorqueMM', 'кН·м', makeAreaOptions('rotorTorque')),
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
const getLast = (data) =>
|
|
||||||
Array.isArray(data) ? data.at(-1) : data
|
|
||||||
|
|
||||||
const isMseEnabled = (dataSaub) => {
|
|
||||||
const lastData = getLast(dataSaub)
|
|
||||||
return (lastData?.mseState && 2) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const isTorqueStabEnabled = (dataSpin) => {
|
|
||||||
const lastData = getLast(dataSpin)
|
|
||||||
return lastData?.state === 7
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const isMseEnabled = (dataSaub) => (getLast(dataSaub)?.mseState && 2) > 0
|
||||||
|
const isTorqueStabEnabled = (dataSpin) => getLast(dataSpin)?.state === 7
|
||||||
const isSpinEnabled = (dataSpin) => {
|
const isSpinEnabled = (dataSpin) => {
|
||||||
const lastData = getLast(dataSpin)
|
const lastData = getLast(dataSpin)
|
||||||
return lastData?.state > 0 && lastData?.state !== 6
|
return lastData?.state > 0 && lastData?.state !== 6
|
||||||
}
|
}
|
||||||
|
|
||||||
export const normalizeData = (data) => data?.map(item => ({
|
export const normalizeData = (data) => data?.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
rotorSpeed: item.rotorSpeed < 1 ? 0 : item.rotorSpeed,
|
rotorSpeed: item.rotorSpeed < 1 ? 0 : item.rotorSpeed,
|
||||||
rotorTorque: item.rotorTorque < 1 ? 0 : item.rotorTorque,
|
rotorTorque: item.rotorTorque < 1 ? 0 : item.rotorTorque,
|
||||||
blockSpeed: Math.abs(item.blockSpeed)
|
blockSpeed: Math.abs(item.blockSpeed)
|
||||||
})) ?? []
|
})) ?? []
|
||||||
|
|
||||||
const dateSorter = makeDateSorter('date')
|
const dateSorter = makeDateSorter('date')
|
||||||
|
|
||||||
|
const makeSubjectSubsription = (subject$, handler) => {
|
||||||
|
const subscribtion = subject$.pipe(
|
||||||
|
buffer(subject$.pipe(throttleTime(700)))
|
||||||
|
).subscribe((data) => handler(data.flat().filter(Boolean)))
|
||||||
|
|
||||||
|
return () => subscribtion.unsubscribe()
|
||||||
|
}
|
||||||
|
|
||||||
const TelemetryView = memo(() => {
|
const TelemetryView = memo(() => {
|
||||||
const [dataSaub, setDataSaub] = useState([])
|
const [dataSaub, setDataSaub] = useState([])
|
||||||
const [dataSpin, setDataSpin] = useState([])
|
const [dataSpin, setDataSpin] = useState([])
|
||||||
const [chartInterval, setChartInterval] = useState(defaultPeriod)
|
const [chartInterval, setChartInterval] = useState(defaultPeriod)
|
||||||
const [showLoader, setShowLoader] = useState(false)
|
const [showLoader, setShowLoader] = useState(false)
|
||||||
const [flowChartData, setFlowChartData] = useState([])
|
const [flowChartData, setFlowChartData] = useState([])
|
||||||
const [rop, setRop] = useState(null)
|
const [rop, setRop] = useState(null)
|
||||||
const [domain, setDomain] = useState({})
|
const [domain, setDomain] = useState({})
|
||||||
const [chartMethods, setChartMethods] = useState()
|
const [chartMethods, setChartMethods] = useState()
|
||||||
|
|
||||||
const [well, updateWell] = useWell()
|
const [well, updateWell] = useWell()
|
||||||
|
|
||||||
const saubSubject$ = useMemo(() => new BehaviorSubject(), [])
|
const saubSubject$ = useMemo(() => new BehaviorSubject(), [])
|
||||||
const spinSubject$ = useMemo(() => new BehaviorSubject(), [])
|
const spinSubject$ = useMemo(() => new BehaviorSubject(), [])
|
||||||
|
|
||||||
const handleDataSaub = useCallback((data) => {
|
const handleDataSaub = useCallback((data) => {
|
||||||
if (data) {
|
if (!data) return
|
||||||
const dataSaub = normalizeData(data)
|
|
||||||
setDataSaub((prev) => {
|
|
||||||
const out = [...prev, ...dataSaub]
|
|
||||||
out.sort(dateSorter)
|
|
||||||
return out
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const handleDataSpin = useCallback((data) => data && setDataSpin((prev) => [...prev, ...data]), [])
|
const dataSaub = normalizeData(data)
|
||||||
|
setDataSaub((prev) => {
|
||||||
|
const out = [...prev, ...dataSaub]
|
||||||
|
out.sort(dateSorter)
|
||||||
|
return out
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
const handleDataSpin = useCallback((data) => data && setDataSpin((prev) => [...prev, ...data]), [])
|
||||||
const subscribtion = saubSubject$.pipe(
|
|
||||||
buffer(saubSubject$.pipe(throttleTime(700)))
|
|
||||||
).subscribe((data) => handleDataSaub(data.flat().filter(Boolean)))
|
|
||||||
|
|
||||||
return () => subscribtion.unsubscribe()
|
const onStatusChanged = useCallback((value) => updateWell({ idState: value }), [well])
|
||||||
}, [saubSubject$])
|
|
||||||
|
|
||||||
useEffect(() => {
|
const filteredData = useMemo(() => {
|
||||||
const subscribtion = spinSubject$.pipe(
|
let i, j
|
||||||
buffer(spinSubject$.pipe(throttleTime(700)))
|
for (i = 0; i < dataSaub.length; i++) {
|
||||||
).subscribe((data) => handleDataSpin(data.flat().filter(Boolean)))
|
const date = +new Date(dataSaub[i]?.date)
|
||||||
|
if (date >= +domain.min) break
|
||||||
|
}
|
||||||
|
|
||||||
return () => subscribtion.unsubscribe()
|
for (j = dataSaub.length - 1; j >= i; j--) {
|
||||||
}, [spinSubject$])
|
const date = +new Date(dataSaub[i]?.date)
|
||||||
|
if (date <= +domain.max) break
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
if (i >= j) return []
|
||||||
invokeWebApiWrapperAsync(
|
return dataSaub.slice(i, j)
|
||||||
async () => {
|
}, [dataSaub, domain])
|
||||||
const flowChart = await DrillFlowChartService.getByIdWell(well.id)
|
|
||||||
const dataSaub = await TelemetryDataSaubService.getData(well.id, null, chartInterval)
|
const chartGroups = useMemo(() => makeChartGroups(flowChartData), [flowChartData])
|
||||||
const dataSpin = await TelemetryDataSpinService.getData(well.id, null, chartInterval)
|
|
||||||
setFlowChartData(flowChart ?? [])
|
useEffect(() => makeSubjectSubsription(saubSubject$, handleDataSaub), [saubSubject$, handleDataSaub])
|
||||||
handleDataSaub(dataSaub)
|
useEffect(() => makeSubjectSubsription(spinSubject$, handleDataSpin), [spinSubject$, handleDataSpin])
|
||||||
handleDataSpin(dataSpin)
|
|
||||||
},
|
useEffect(() => {
|
||||||
null,
|
invokeWebApiWrapperAsync(
|
||||||
`Не удалось получить данные`,
|
async () => {
|
||||||
{ actionName: 'Получение данных по скважине', well }
|
const flowChart = await DrillFlowChartService.getByIdWell(well.id)
|
||||||
|
const dataSaub = await TelemetryDataSaubService.getData(well.id, null, chartInterval)
|
||||||
|
const dataSpin = await TelemetryDataSpinService.getData(well.id, null, chartInterval)
|
||||||
|
setFlowChartData(flowChart ?? [])
|
||||||
|
handleDataSaub(dataSaub)
|
||||||
|
handleDataSpin(dataSpin)
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
`Не удалось получить данные`,
|
||||||
|
{ actionName: 'Получение данных по скважине', well }
|
||||||
|
)
|
||||||
|
}, [well, chartInterval, handleDataSpin, handleDataSaub])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unsubscribe = Subscribe(
|
||||||
|
'hubs/telemetry', `well_${well.id}`,
|
||||||
|
{ methodName: 'ReceiveDataSaub', handler: (data) => saubSubject$.next(data) },
|
||||||
|
{ methodName: 'ReceiveDataSpin', handler: (data) => spinSubject$.next(data) }
|
||||||
|
)
|
||||||
|
|
||||||
|
return () => unsubscribe()
|
||||||
|
}, [well.id, saubSubject$, spinSubject$])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
invokeWebApiWrapperAsync(
|
||||||
|
async () => {
|
||||||
|
const rop = await OperationStatService.getClusterRopStatByIdWell(well.id)
|
||||||
|
setRop(rop)
|
||||||
|
},
|
||||||
|
setShowLoader,
|
||||||
|
`Не удалось загрузить данные`,
|
||||||
|
{ actionName: 'Получение данных по скважине', well }
|
||||||
|
)
|
||||||
|
}, [well])
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LoaderPortal show={showLoader}>
|
||||||
|
<Grid style={{ gridTemplateColumns: 'auto repeat(6, 1fr)' }}>
|
||||||
|
<GridItem col={'1'} row={'1'} colSpan={'8'} style={{ marginBottom: '0.5rem' }}>
|
||||||
|
<div className={'page-top'}>
|
||||||
|
<ModeDisplay data={dataSaub} />
|
||||||
|
<div>
|
||||||
|
Интервал:
|
||||||
|
<PeriodPicker onChange={setChartInterval} />
|
||||||
|
</div>
|
||||||
|
<Button onClick={() => chartMethods?.setSettingsVisible(true)}>Настроить графики</Button>
|
||||||
|
<div>
|
||||||
|
Статус:
|
||||||
|
<Select value={well.idState ?? 0} onChange={onStatusChanged} disabled={!hasPermission('Well.edit')}>
|
||||||
|
<Option value={0} disabled hidden>Неизвестно</Option>
|
||||||
|
<Option value={1}>В работе</Option>
|
||||||
|
<Option value={2}>Завершено</Option>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<Setpoints />
|
||||||
|
<span style={{ flexGrow: 20 }}> </span>
|
||||||
|
<WirelineRunOut />
|
||||||
|
<div className={'icons'}>
|
||||||
|
<img src={isTorqueStabEnabled(dataSpin) ? MomentStabPicEnabled : MomentStabPicDisabled} alt={'TorqueMaster'} />
|
||||||
|
<img src={isSpinEnabled(dataSpin) ? SpinPicEnabled : SpinPicDisabled} alt={'SpinMaster'} />
|
||||||
|
<h2 style={{ marginBottom: 0, fontWeight: 'bold', color: isMseEnabled(dataSaub) ? 'green' : 'lightgrey' }}>MSE</h2>
|
||||||
|
</div>
|
||||||
|
<UserOfWell data={dataSaub} />
|
||||||
|
</div>
|
||||||
|
</GridItem>
|
||||||
|
<GridItem col={'1'} row={'2'} rowSpan={'3'} style={{ minWidth: '260px', width: '0.142fr' }}>
|
||||||
|
<CustomColumn data={dataSaub} />
|
||||||
|
</GridItem>
|
||||||
|
<GridItem col={2} row={2} colSpan={8} rowSpan={2}>
|
||||||
|
<D3MonitoringCharts
|
||||||
|
methods={setChartMethods}
|
||||||
|
chartName={'monitoring'}
|
||||||
|
datasetGroups={chartGroups}
|
||||||
|
data={filteredData}
|
||||||
|
yDomain={domain}
|
||||||
|
yAxis={yAxis}
|
||||||
|
yTicks={{
|
||||||
|
visible: true,
|
||||||
|
format: (d) => formatDate(d, 'YYYY-MM-DD')
|
||||||
|
}}
|
||||||
|
plugins={{
|
||||||
|
menu: { enabled: false },
|
||||||
|
cursor: {
|
||||||
|
render: cursorRender,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
height={'70vh'}
|
||||||
|
/>
|
||||||
|
</GridItem>
|
||||||
|
<GridItem col={'2'} row={'3'} colSpan={'7'}>
|
||||||
|
<ActiveMessagesOnline well={well} />
|
||||||
|
</GridItem>
|
||||||
|
</Grid>
|
||||||
|
</LoaderPortal>
|
||||||
)
|
)
|
||||||
}, [well, chartInterval, handleDataSpin, handleDataSaub])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const unsubscribe = Subscribe(
|
|
||||||
'hubs/telemetry', `well_${well.id}`,
|
|
||||||
{ methodName: 'ReceiveDataSaub', handler: (data) => saubSubject$.next(data) },
|
|
||||||
{ methodName: 'ReceiveDataSpin', handler: (data) => spinSubject$.next(data) }
|
|
||||||
)
|
|
||||||
|
|
||||||
return () => unsubscribe()
|
|
||||||
}, [well.id, saubSubject$, spinSubject$])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
invokeWebApiWrapperAsync(
|
|
||||||
async () => {
|
|
||||||
const rop = await OperationStatService.getClusterRopStatByIdWell(well.id)
|
|
||||||
setRop(rop)
|
|
||||||
},
|
|
||||||
setShowLoader,
|
|
||||||
`Не удалось загрузить данные`,
|
|
||||||
{ actionName: 'Получение данных по скважине', well }
|
|
||||||
)
|
|
||||||
}, [well])
|
|
||||||
|
|
||||||
const onStatusChanged = useCallback((value) => updateWell({ idState: value }), [well])
|
|
||||||
|
|
||||||
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])
|
|
||||||
|
|
||||||
const chartGroups = useMemo(() => makeChartGroups(flowChartData), [flowChartData])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LoaderPortal show={showLoader}>
|
|
||||||
<Grid style={{ gridTemplateColumns: 'auto repeat(6, 1fr)' }}>
|
|
||||||
<GridItem col={'1'} row={'1'} colSpan={'8'} style={{ marginBottom: '0.5rem' }}>
|
|
||||||
<div className={'page-top'}>
|
|
||||||
<ModeDisplay data={dataSaub} />
|
|
||||||
<div>
|
|
||||||
Интервал:
|
|
||||||
<PeriodPicker onChange={setChartInterval} />
|
|
||||||
</div>
|
|
||||||
<Button onClick={() => chartMethods?.setSettingsVisible(true)}>Настроить графики</Button>
|
|
||||||
<div>
|
|
||||||
Статус:
|
|
||||||
<Select value={well.idState ?? 0} onChange={onStatusChanged} disabled={!hasPermission('Well.edit')}>
|
|
||||||
<Option value={0} disabled hidden>Неизвестно</Option>
|
|
||||||
<Option value={1}>В работе</Option>
|
|
||||||
<Option value={2}>Завершено</Option>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<Setpoints />
|
|
||||||
<span style={{ flexGrow: 20 }}> </span>
|
|
||||||
<WirelineRunOut />
|
|
||||||
<div className={'icons'}>
|
|
||||||
<img src={isTorqueStabEnabled(dataSpin) ? MomentStabPicEnabled : MomentStabPicDisabled} alt={'TorqueMaster'} />
|
|
||||||
<img src={isSpinEnabled(dataSpin) ? SpinPicEnabled : SpinPicDisabled} alt={'SpinMaster'} />
|
|
||||||
<h2 style={{ marginBottom: 0, fontWeight: 'bold', color: isMseEnabled(dataSaub) ? 'green' : 'lightgrey' }}>MSE</h2>
|
|
||||||
</div>
|
|
||||||
<UserOfWell data={dataSaub} />
|
|
||||||
</div>
|
|
||||||
</GridItem>
|
|
||||||
<GridItem col={'1'} row={'2'} rowSpan={'3'} style={{ minWidth: '260px', width: '0.142fr' }}>
|
|
||||||
<CustomColumn data={dataSaub} />
|
|
||||||
</GridItem>
|
|
||||||
<GridItem col={2} row={2} colSpan={8} rowSpan={2}>
|
|
||||||
<D3MonitoringCharts
|
|
||||||
methods={setChartMethods}
|
|
||||||
chartName={'monitoring'}
|
|
||||||
datasetGroups={chartGroups}
|
|
||||||
data={filteredData}
|
|
||||||
yDomain={domain}
|
|
||||||
yAxis={yAxis}
|
|
||||||
yTicks={{
|
|
||||||
visible: true,
|
|
||||||
format: (d) => formatDate(d, 'YYYY-MM-DD')
|
|
||||||
}}
|
|
||||||
plugins={{
|
|
||||||
menu: { enabled: false },
|
|
||||||
cursor: {
|
|
||||||
render: cursorRender,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
height={'70vh'}
|
|
||||||
/>
|
|
||||||
</GridItem>
|
|
||||||
<GridItem col={'2'} row={'3'} colSpan={'7'}>
|
|
||||||
<ActiveMessagesOnline well={well} />
|
|
||||||
</GridItem>
|
|
||||||
</Grid>
|
|
||||||
</LoaderPortal>
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export default withPermissions(TelemetryView, [
|
export default withPermissions(TelemetryView, [
|
||||||
'DrillFlowChart.get',
|
'DrillFlowChart.get',
|
||||||
'OperationStat.get',
|
'OperationStat.get',
|
||||||
'TelemetryDataSaub.get',
|
'TelemetryDataSaub.get',
|
||||||
'TelemetryDataSpin.get',
|
'TelemetryDataSpin.get',
|
||||||
'Well.get',
|
'Well.get',
|
||||||
])
|
])
|
||||||
|
Loading…
Reference in New Issue
Block a user