From 7c8135263871aa31fdc7fa8dfd94950f0bd84497 Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 1 Nov 2021 14:47:12 +0500 Subject: [PATCH 01/17] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=D1=8B,=20=D0=B3?= =?UTF-8?q?=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8=20=D1=87=D0=B0=D1=81=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=BD=D0=BE=20=D0=BF=D0=B5=D1=80=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ArchiveColumn.jsx | 123 ---------------- src/components/charts/ChartDepth.jsx | 16 --- src/components/charts/ChartTimeBase.tsx | 44 +++--- src/pages/Archive.jsx | 178 +++++++----------------- src/pages/TelemetryView/Column.jsx | 51 ++++--- src/pages/TelemetryView/index.jsx | 10 +- 6 files changed, 111 insertions(+), 311 deletions(-) delete mode 100644 src/components/ArchiveColumn.jsx delete mode 100644 src/components/charts/ChartDepth.jsx diff --git a/src/components/ArchiveColumn.jsx b/src/components/ArchiveColumn.jsx deleted file mode 100644 index 60c5858..0000000 --- a/src/components/ArchiveColumn.jsx +++ /dev/null @@ -1,123 +0,0 @@ -import { useState, useEffect } from 'react'; -import { Button, Select, Tag, Popover, Row, Tooltip } from 'antd'; -import { ChartTimeArchive } from './charts/ChartTimeArchive'; -import { DeleteOutlined } from '@ant-design/icons'; - -const { Option } = Select; - -const linesCollection = [ - { label: "Глубина забоя", xAccessorName: "wellDepth", color: '#f00' }, - { label: "Положение инструмента", xAccessorName: "bitDepth", color: '#ff0' }, - { label: "Положение талевого блока", xAccessorName: "blockPosition", color: '#f0f' }, - { label: "Талевый блок. Мин положение", xAccessorName: "blockPositionMin", color: '#0ff' }, - { label: "Талевый блок. Макс положение", xAccessorName: "blockPositionMax", color: '#0f0' }, - { label: "Скорость талевого блока", xAccessorName: "blockSpeed", color: '#00f' }, - - { label: "Скорости талевого блока. Задание", xAccessorName: "blockSpeedSp", color: '#c00' }, - { label: "Талевый блок. Задание скорости для роторного бурения", xAccessorName: "blockSpeedSpRotor", color: '#cc0' }, - { label: "Талевый блок. Задание скорости для режима слайда", xAccessorName: "blockSpeedSpSlide", color: '#c0c' }, - { label: "Талевый блок. Задание скорости для проработки", xAccessorName: "blockSpeedSpDevelop", color: '#0cc' }, - { label: "Давление", xAccessorName: "pressure", color: '#0c0' }, - { label: "Давление. Холостой ход", xAccessorName: "pressureIdle", color: '#00c' }, - - { label: "Давление. Задание", xAccessorName: "pressureSp", color: '#900' }, - { label: "Давление. Задание для роторного бурения", xAccessorName: "pressureSpRotor", color: '#990' }, - { label: "Давление. Задание для режима слайда", xAccessorName: "pressureSpSlide", color: '#909' }, - { label: "Давление. Задание для проработки", xAccessorName: "pressureSpDevelop", color: '#099' }, - { label: "Давление дифф. Аварийное макс.", xAccessorName: "pressureDeltaLimitMax", color: '#090' }, - { label: "Осевая нагрузка", xAccessorName: "axialLoad", color: '#009' }, - - { label: "Осевая нагрузка. Задание", xAccessorName: "axialLoadSp", color: '#600' }, - { label: "Осевая нагрузка. Аварийная макс.", xAccessorName: "axialLoadLimitMax", color: '#660' }, - { label: "Вес на крюке", xAccessorName: "hookWeight", color: '#606' }, - { label: "Вес на крюке. Холостой ход", xAccessorName: "hookWeightIdle", color: '#066' }, - { label: "Вес на крюке. Посадка", xAccessorName: "hookWeightLimitMin", color: '#060' }, - { label: "Вес на крюке. Затяжка", xAccessorName: "hookWeightLimitMax", color: '#006' }, - - { label: "Момент на роторе", xAccessorName: "rotorTorque", color: '#300' }, - { label: "Момент на роторе. Холостой ход", xAccessorName: "rotorTorqueIdle", color: '#330' }, - { label: "Момент на роторе. Задание", xAccessorName: "rotorTorqueSp", color: '#303' }, - { label: "Момент на роторе. Аварийный макс.", xAccessorName: "rotorTorqueLimitMax", color: '#033' }, - { label: "Обороты ротора", xAccessorName: "rotorSpeed", color: '#030' }, - { label: "Расход", xAccessorName: "flow", color: '#003' }, - - { label: "Расход. Холостой ход", xAccessorName: "flowIdle", color: '#666' }, - { label: "Расход. Аварийный макс.", xAccessorName: "flowDeltaLimitMax", color: '#ccc' }, -] - -const tagRender = ({ label, value, closable, onClose }) =>{ - const onPreventMouseDown = event => { - event.preventDefault(); - event.stopPropagation(); - }; - - let color = linesCollection.find(l=>l.xAccessorName === value)?.color - return ( - -       -  {label} - - ); -} - -export function ArchiveColumn({ data, config, rangeDate, chartRatio, onRemoveChart, onSaveConfig }) { - const [lines, setLines] = useState([]); - - useEffect(() => { - setLines(config.lines); - },[config]); - - const handleLinesSetChange = (linesKeys) => { - let newLines = linesCollection.filter(line => linesKeys.includes(line.xAccessorName)); - config.lines = newLines; - if(onSaveConfig) - onSaveConfig() - setLines(newLines); - }; - - let selectedValues = lines?.map(line=>line.xAccessorName)??[] - - const select = ; - - const popBar = - {select} - - - - - - return ( - <> - -
- -
-
- - ); -} diff --git a/src/components/charts/ChartDepth.jsx b/src/components/charts/ChartDepth.jsx deleted file mode 100644 index 0af149e..0000000 --- a/src/components/charts/ChartDepth.jsx +++ /dev/null @@ -1,16 +0,0 @@ -import ChartDataLabels from 'chartjs-plugin-datalabels' - -const defaultOptionsDepthLabels = { - borderWidth: 1, - borderColor: black, - borderRadius: 4, - clamp: true, - display: true, - data: { - datasets: [{ - datalabels: { - color: '#0f4000' - } - }] - } -} \ No newline at end of file diff --git a/src/components/charts/ChartTimeBase.tsx b/src/components/charts/ChartTimeBase.tsx index b3a8621..5c7ff02 100644 --- a/src/components/charts/ChartTimeBase.tsx +++ b/src/components/charts/ChartTimeBase.tsx @@ -1,14 +1,14 @@ import { useEffect, useRef, useState} from 'react' -import { - Chart, - TimeScale, - LinearScale, - Legend, - LineController, - PointElement, - LineElement, - ChartData, - ChartTypeRegistry, +import { + Chart, + TimeScale, + LinearScale, + Legend, + LineController, + PointElement, + LineElement, + ChartData, + ChartTypeRegistry, ChartOptions} from 'chart.js' import 'chartjs-adapter-moment' import ChartDataLabels from 'chartjs-plugin-datalabels' @@ -65,7 +65,7 @@ const defaultOptions = { color:'#000', } }, - + x:{ type:'linear', position:'top' @@ -108,6 +108,7 @@ export type ChartTimeData = ChartData { if(intervalSec <= 32*60*60) return 'minute' - + if(intervalSec <= 32*12*60*60) return 'hour' - + if(intervalSec <= 32*24*60*60) return 'day' if(intervalSec <= 32*7*24*60*60) return 'week' - + if(intervalSec <= 32*30.4375*24*60*60) return 'month' @@ -186,13 +187,13 @@ export const timeParamsByInterval = (intervalSec: number): TimeParams => { stepSize /= 365.25*24*60*60 break; } - + stepSize = Math.round(stepSize/linesPerInterval) stepSize = stepSize > 0 ? stepSize : 1 return {unit, stepSize} } -export const ChartTimeBase: React.FC = ({options, dataParams}) => { +export const ChartTimeBase: React.FC = ({options, dataParams}) => { const chartRef = useRef(null) const [chart, setChart] = useState() @@ -202,7 +203,7 @@ export const ChartTimeBase: React.FC = ({options, dataParams Object.assign(thisOptions, defaultOptions, options) let newChart = new Chart(chartRef.current, { - type: 'line', + type: 'line', plugins: [ChartDataLabels], options: thisOptions, data: dataParams.data @@ -217,10 +218,11 @@ export const ChartTimeBase: React.FC = ({options, dataParams chart.data = dataParams.data chart.options.aspectRatio = options?.aspectRatio if(dataParams.yStart){ - const interval = Number(dataParams.yInterval ?? 600) const start = new Date(dataParams.yStart) - const end = new Date(dataParams.yStart) - end.setSeconds(end.getSeconds() + interval) + const end = new Date(dataParams.yEnd ?? dataParams.yStart) + const interval = Number(dataParams.yInterval ?? (dataParams.yEnd ? end.getSeconds() - start.getSeconds() : 600)) + if (!dataParams.yEnd) + end.setSeconds(end.getSeconds() + interval) const { unit, stepSize } = timeParamsByInterval(interval) if(chart.options.scales?.y){ @@ -236,4 +238,4 @@ export const ChartTimeBase: React.FC = ({options, dataParams }, [chart, dataParams, options]) return() -} \ No newline at end of file +} diff --git a/src/pages/Archive.jsx b/src/pages/Archive.jsx index cb75ad5..8abd9de 100644 --- a/src/pages/Archive.jsx +++ b/src/pages/Archive.jsx @@ -1,144 +1,62 @@ -import { useRef, useLayoutEffect, useState, useEffect } from 'react' -import { - Button, - DatePicker, - Row, - Col, - Tooltip} from 'antd' +import { useState, useEffect } from 'react' +import { DatePicker } from 'antd' import { TelemetryDataSaubService } from '../services/api' -import {generateUUID} from '../services/UidGenerator' -import { ArchiveColumn } from '../components/ArchiveColumn' import moment from 'moment' -import { notify } from "../components/factory" +import { invokeWebApiWrapperAsync } from "../components/factory" import LoaderPortal from '../components/LoaderPortal' +import { Grid, GridItem } from '../components/Grid' +import { Column } from './TelemetryView/Column' +import { paramsGroups } from './TelemetryView' const { RangePicker } = DatePicker -const SaveObject = (key, obj) => { - let json = JSON.stringify(obj) - localStorage.setItem(key, json) -} - -const LoadObject = (key) => { - let json = localStorage.getItem(key) - return json ? JSON.parse(json) : null -} - -export default function Archive({idWell}) { - const [saubData, setSaubData] = useState([]) - const [chartsCfgs, setChartsCfgs] = useState([]) +export default function Archive({idWell}) { + const [dataSaub, setDataSaub] = useState([]) const [rangeDate, setRangeDate] = useState([moment().subtract(3,'hours'), moment()]) - const [geometry, setGeometry] = useState({ratioRest:1, ratio1st:1, wRest:.5, w1st:.5}) - const [loader, setLoader] = useState(false) - const chartsCfgsKey = 'chartsCfgs' - const chartsContainerRef = useRef(); - - const handleReceiveDataSaub = (data) => { - if (data) - setSaubData(data) - } - - const onAddChart = () => { - let newChartCfgs = [...chartsCfgs, {id: generateUUID(), yDisplay: false, aspectRatio:1}] - setChartsCfgs(newChartCfgs) - } - - const onRemoveChart = (id) => { - let newChartCfgs = chartsCfgs.filter(cfg => cfg.id !== id ) - setChartsCfgs(newChartCfgs) - } - - const onSaveConfig = ()=>{ - SaveObject(chartsCfgsKey, chartsCfgs) - } + const [showLoader, setShowLoader] = useState(false) + const [chartInterval, setChartInterval] = useState(600) const onChangeRange = (range) => { setRangeDate(range) } - - useLayoutEffect(()=>{ - if(chartsContainerRef.current && chartsCfgs?.length){ - let w = chartsContainerRef.current.offsetWidth //1792 - w = w > 0 ? w : 1792 - let ot = chartsContainerRef.current.offsetTop - let ph = chartsContainerRef.current.offsetParent.offsetHeight - let h = ph - ot - 32 //761 - h = h > 0 ? h : 761 - let chartsCount = chartsCfgs.length + useEffect(() => invokeWebApiWrapperAsync( + async () => { + const interval = (rangeDate[1] - rangeDate[0]) / 1000 + let startDate = rangeDate[0].toISOString() - let labelLenght = 8 - let borderWidth = 8 - let wRest = Math.floor((w - labelLenght)/chartsCount) - borderWidth - let w1st = wRest + labelLenght + const data = await TelemetryDataSaubService.getData(idWell, startDate, interval, 2048) + data?.sort((a, b) => a.date > b.date ? 1 : -1) + setDataSaub(data ?? []) + setChartInterval(interval) + }, + setShowLoader, + `Не удалось загрузить данные по скважине "${idWell}" c ${rangeDate[0]} по ${rangeDate[1]}` + ), [idWell, rangeDate]) - let ratio1st = w1st/h - let ratioRest = wRest/h - - setGeometry({ratio1st, ratioRest, w1st, wRest}) - } - },[chartsContainerRef, chartsCfgs]) - - useEffect(() => { - let cfgs = LoadObject(chartsCfgsKey) - if(cfgs) - setChartsCfgs(cfgs) - },[]) - - useEffect(()=>{ - SaveObject(chartsCfgsKey, chartsCfgs) - },[chartsCfgs]) - - useEffect(() => { - let interval = (rangeDate[1] - rangeDate[0]) / 1000 - let startDate = rangeDate[0].toISOString() - - setLoader(true) - TelemetryDataSaubService.getData(idWell, startDate, interval, 2048) - .then(handleReceiveDataSaub) - .catch(error => { - notify(`Не удалось загрузить данные по скважине (${idWell}) c ${rangeDate[0]} по ${rangeDate[1]}`, 'error') - console.error(error) - }) - .finally(()=>setLoader(false)) - }, [idWell, rangeDate]); - - let charts = null - if(chartsCfgs.length > 0){ - chartsCfgs[0].yDisplay = true - - charts = chartsCfgs.map((cfg, i) => - - - ) - } - - return (<> - - - - - - - {charts} - - - ) -} \ No newline at end of file + return ( + <> + + + console.log(e)}> + {paramsGroups.map((group, index) => ( + + + + ))} + + + + ) +} diff --git a/src/pages/TelemetryView/Column.jsx b/src/pages/TelemetryView/Column.jsx index 621d541..d67194e 100644 --- a/src/pages/TelemetryView/Column.jsx +++ b/src/pages/TelemetryView/Column.jsx @@ -18,7 +18,7 @@ const chartPluginsOptions = { anchor: 'center', clip: true }, - legend:{ display: false }, + legend: { display: false }, tooltip: { enable: true } } } @@ -41,9 +41,9 @@ const GetRandomColor = () => '#' + Math.floor(Math.random()*16777215).toString(1 const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { let dataset = data?.datasets.find(d => d.label === lineConfig.label) if(!dataset) { - let color = lineConfig.borderColor - ?? lineConfig.backgroundColor - ?? lineConfig.color + let color = lineConfig.borderColor + ?? lineConfig.backgroundColor + ?? lineConfig.color ?? GetRandomColor() dataset = { @@ -61,7 +61,7 @@ const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { return dataset } -export const Column = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, yDisplay }) => { +export const Column = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, yDisplay, yStart, showLastValues, pointCount }) => { const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart: new Date(), }) let dataLast = data?.[data.length - 1] @@ -89,26 +89,29 @@ export const Column = ({ lineGroup, data, flowChartData, interval, showBorder, s const lineData = [ ...dataset.data, ...points,] if(points?.length > 2) lineData.sort((a,b) => a.y > b.y ? 1 : -1) - if(lineData.length > 1024) - lineData.splice(0, (1024 - lineData.length)) + if(lineData.length > pointCount) + lineData.splice(0, (pointCount - lineData.length)) dataset.data = lineData //Area - lineGroup.filter(cfg => cfg.isShape && cfg.xAccessorName === lineCfg.xAccessorName).forEach(areaCfg => { - const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, areaCfg) - dataset.data = GetLimitShape(flowChartData, lineData, areaCfg.xAccessorName) - }) + if (flowChartData) { + lineGroup.filter(cfg => cfg.isShape && cfg.xAccessorName === lineCfg.xAccessorName).forEach(areaCfg => { + const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, areaCfg) + dataset.data = GetLimitShape(flowChartData, lineData, areaCfg.xAccessorName) + }) + } }) - preDataParams.yStart = new Date(Math.max(new Date(dataLast.date), preDataParams.yStart ?? new Date(0))) - preDataParams.yStart.setSeconds(preDataParams.yStart.getSeconds() - interval * 0.97) + preDataParams.yStart = yStart ?? new Date(Math.max(new Date(dataLast.date), preDataParams.yStart ?? new Date(0))) + if (!yStart) + preDataParams.yStart.setSeconds(preDataParams.yStart.getSeconds() - interval * 0.97) preDataParams.yInterval = interval preDataParams.displayLabels = yDisplay ?? false return {...preDataParams} }) - }, [data, lineGroup, interval, yDisplay, flowChartData, dataLast]) + }, [data, lineGroup, interval, yDisplay, yStart, flowChartData, dataLast, pointCount]) return (
@@ -118,14 +121,22 @@ export const Column = ({ lineGroup, data, flowChartData, interval, showBorder, s ))}
- - {pv?.map((v, idx) => ( - {v.value?.toFixed(2) ?? '--'} {v.unit} - ))} - + {showLastValues && ( + + {pv?.map((v, idx) => ( + {v.value?.toFixed(2) ?? '--'} {v.unit} + ))} + + )}
- + {showLastValues && ( + + )}
) } + +Column.defaultProps = { + pointCount: 2048 +} diff --git a/src/pages/TelemetryView/index.jsx b/src/pages/TelemetryView/index.jsx index f3056c8..80cb9e7 100644 --- a/src/pages/TelemetryView/index.jsx +++ b/src/pages/TelemetryView/index.jsx @@ -250,7 +250,14 @@ const rotorTorqueGroup = [ } ] -const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup] +export const paramsGroups = [ + blockHeightGroup, + blockSpeedGroup, + pressureGroup, + axialLoadGroup, + hookWeightGroup, + rotorTorqueGroup +] const timePeriodCollection = [ { value: '60', label: '1 минута' }, @@ -400,6 +407,7 @@ export default function TelemetryView({ idWell }) { {paramsGroups.map((group, index) => Date: Tue, 2 Nov 2021 09:51:32 +0500 Subject: [PATCH 02/17] =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D1=8B=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/api/index.ts | 8 +++++++ .../models/ClusterDtoPaginationContainer.ts | 12 +++++++++++ .../models/CompanyDtoPaginationContainer.ts | 12 +++++++++++ .../models/DepositDtoPaginationContainer.ts | 12 +++++++++++ src/services/api/models/FileInfoDto.ts | 2 ++ src/services/api/models/FilePublishInfoDto.ts | 9 ++++++++ .../models/TelemetryDtoPaginationContainer.ts | 12 +++++++++++ .../api/models/UserDtoPaginationContainer.ts | 12 +++++++++++ .../models/UserRoleDtoPaginationContainer.ts | 12 +++++++++++ .../api/models/WellDtoPaginationContainer.ts | 12 +++++++++++ .../api/services/AdminClusterService.ts | 21 ++++++++++--------- .../api/services/AdminCompanyService.ts | 21 ++++++++++--------- .../api/services/AdminDepositService.ts | 21 ++++++++++--------- .../api/services/AdminTelemetryService.ts | 21 ++++++++++--------- .../api/services/AdminUserRoleService.ts | 21 ++++++++++--------- src/services/api/services/AdminUserService.ts | 21 ++++++++++--------- src/services/api/services/AdminWellService.ts | 21 ++++++++++--------- src/services/api/services/AuthService.ts | 4 ++-- .../api/services/DrillingProgramService.ts | 19 ++++++++++++++++- .../api/services/TelemetryDataSaubService.ts | 4 ++-- .../api/services/TelemetryDataSpinService.ts | 4 ++-- 21 files changed, 204 insertions(+), 77 deletions(-) create mode 100644 src/services/api/models/ClusterDtoPaginationContainer.ts create mode 100644 src/services/api/models/CompanyDtoPaginationContainer.ts create mode 100644 src/services/api/models/DepositDtoPaginationContainer.ts create mode 100644 src/services/api/models/FilePublishInfoDto.ts create mode 100644 src/services/api/models/TelemetryDtoPaginationContainer.ts create mode 100644 src/services/api/models/UserDtoPaginationContainer.ts create mode 100644 src/services/api/models/UserRoleDtoPaginationContainer.ts create mode 100644 src/services/api/models/WellDtoPaginationContainer.ts diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 36b4c1c..9f443ce 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -6,14 +6,18 @@ export { OpenAPI } from './core/OpenAPI'; export type { AuthDto } from './models/AuthDto'; export type { ClusterDto } from './models/ClusterDto'; +export type { ClusterDtoPaginationContainer } from './models/ClusterDtoPaginationContainer'; export type { CompanyDto } from './models/CompanyDto'; +export type { CompanyDtoPaginationContainer } from './models/CompanyDtoPaginationContainer'; export type { DatesRangeDto } from './models/DatesRangeDto'; export type { DepositDto } from './models/DepositDto'; +export type { DepositDtoPaginationContainer } from './models/DepositDtoPaginationContainer'; export type { DrillFlowChartDto } from './models/DrillFlowChartDto'; export type { DrillParamsDto } from './models/DrillParamsDto'; export type { EventDto } from './models/EventDto'; export type { FileInfoDto } from './models/FileInfoDto'; export type { FileInfoDtoPaginationContainer } from './models/FileInfoDtoPaginationContainer'; +export type { FilePublishInfoDto } from './models/FilePublishInfoDto'; export type { MeasureDto } from './models/MeasureDto'; export type { MessageDto } from './models/MessageDto'; export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer'; @@ -25,6 +29,7 @@ export type { StatWellDto } from './models/StatWellDto'; export type { TelemetryDataSaubDto } from './models/TelemetryDataSaubDto'; export type { TelemetryDataSpinDto } from './models/TelemetryDataSpinDto'; export type { TelemetryDto } from './models/TelemetryDto'; +export type { TelemetryDtoPaginationContainer } from './models/TelemetryDtoPaginationContainer'; export type { TelemetryInfoDto } from './models/TelemetryInfoDto'; export type { TelemetryMessageDto } from './models/TelemetryMessageDto'; export type { TelemetryOperationDto } from './models/TelemetryOperationDto'; @@ -32,12 +37,15 @@ export type { TelemetryOperationDtoPaginationContainer } from './models/Telemetr export type { TelemetryOperationDurationDto } from './models/TelemetryOperationDurationDto'; export type { TelemetryUserDto } from './models/TelemetryUserDto'; export type { UserDto } from './models/UserDto'; +export type { UserDtoPaginationContainer } from './models/UserDtoPaginationContainer'; export type { UserRoleDto } from './models/UserRoleDto'; +export type { UserRoleDtoPaginationContainer } from './models/UserRoleDtoPaginationContainer'; export type { UserTokenDto } from './models/UserTokenDto'; export type { WellCompositeDto } from './models/WellCompositeDto'; export type { WellDepthToDayDto } from './models/WellDepthToDayDto'; export type { WellDepthToIntervalDto } from './models/WellDepthToIntervalDto'; export type { WellDto } from './models/WellDto'; +export type { WellDtoPaginationContainer } from './models/WellDtoPaginationContainer'; export type { WellOperationCategoryDto } from './models/WellOperationCategoryDto'; export type { WellOperationDto } from './models/WellOperationDto'; export type { WellOperationDtoPaginationContainer } from './models/WellOperationDtoPaginationContainer'; diff --git a/src/services/api/models/ClusterDtoPaginationContainer.ts b/src/services/api/models/ClusterDtoPaginationContainer.ts new file mode 100644 index 0000000..5b6d4e3 --- /dev/null +++ b/src/services/api/models/ClusterDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ClusterDto } from './ClusterDto'; + +export type ClusterDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/CompanyDtoPaginationContainer.ts b/src/services/api/models/CompanyDtoPaginationContainer.ts new file mode 100644 index 0000000..e3a7dcc --- /dev/null +++ b/src/services/api/models/CompanyDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CompanyDto } from './CompanyDto'; + +export type CompanyDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/DepositDtoPaginationContainer.ts b/src/services/api/models/DepositDtoPaginationContainer.ts new file mode 100644 index 0000000..704269c --- /dev/null +++ b/src/services/api/models/DepositDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DepositDto } from './DepositDto'; + +export type DepositDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/FileInfoDto.ts b/src/services/api/models/FileInfoDto.ts index d727028..93cef3b 100644 --- a/src/services/api/models/FileInfoDto.ts +++ b/src/services/api/models/FileInfoDto.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ +import type { FilePublishInfoDto } from './FilePublishInfoDto'; import type { UserDto } from './UserDto'; export type FileInfoDto = { @@ -12,5 +13,6 @@ export type FileInfoDto = { name?: string | null; uploadDate?: string; size?: number; + publishInfo?: FilePublishInfoDto; author?: UserDto; } diff --git a/src/services/api/models/FilePublishInfoDto.ts b/src/services/api/models/FilePublishInfoDto.ts new file mode 100644 index 0000000..59099f9 --- /dev/null +++ b/src/services/api/models/FilePublishInfoDto.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type FilePublishInfoDto = { + publisherLogin?: string | null; + date?: string; + webStorageFileUrl?: string | null; +} diff --git a/src/services/api/models/TelemetryDtoPaginationContainer.ts b/src/services/api/models/TelemetryDtoPaginationContainer.ts new file mode 100644 index 0000000..ef7a641 --- /dev/null +++ b/src/services/api/models/TelemetryDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TelemetryDto } from './TelemetryDto'; + +export type TelemetryDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/UserDtoPaginationContainer.ts b/src/services/api/models/UserDtoPaginationContainer.ts new file mode 100644 index 0000000..d1b285d --- /dev/null +++ b/src/services/api/models/UserDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserDto } from './UserDto'; + +export type UserDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/UserRoleDtoPaginationContainer.ts b/src/services/api/models/UserRoleDtoPaginationContainer.ts new file mode 100644 index 0000000..aa0e25a --- /dev/null +++ b/src/services/api/models/UserRoleDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserRoleDto } from './UserRoleDto'; + +export type UserRoleDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/models/WellDtoPaginationContainer.ts b/src/services/api/models/WellDtoPaginationContainer.ts new file mode 100644 index 0000000..d0bec27 --- /dev/null +++ b/src/services/api/models/WellDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { WellDto } from './WellDto'; + +export type WellDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} diff --git a/src/services/api/services/AdminClusterService.ts b/src/services/api/services/AdminClusterService.ts index f4ded6c..f76b7bb 100644 --- a/src/services/api/services/AdminClusterService.ts +++ b/src/services/api/services/AdminClusterService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { ClusterDto } from '../models/ClusterDto'; +import type { ClusterDtoPaginationContainer } from '../models/ClusterDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminClusterService { @@ -10,13 +11,13 @@ export class AdminClusterService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns ClusterDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/cluster`, @@ -31,12 +32,12 @@ export class AdminClusterService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: ClusterDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/cluster`, @@ -48,12 +49,12 @@ export class AdminClusterService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns ClusterDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/cluster/${id}`, @@ -65,13 +66,13 @@ export class AdminClusterService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: ClusterDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/cluster/${id}`, @@ -83,12 +84,12 @@ export class AdminClusterService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/cluster/${id}`, diff --git a/src/services/api/services/AdminCompanyService.ts b/src/services/api/services/AdminCompanyService.ts index fb8d668..fd07059 100644 --- a/src/services/api/services/AdminCompanyService.ts +++ b/src/services/api/services/AdminCompanyService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { CompanyDto } from '../models/CompanyDto'; +import type { CompanyDtoPaginationContainer } from '../models/CompanyDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminCompanyService { @@ -10,13 +11,13 @@ export class AdminCompanyService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns CompanyDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/company`, @@ -31,12 +32,12 @@ export class AdminCompanyService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: CompanyDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/company`, @@ -48,12 +49,12 @@ export class AdminCompanyService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns CompanyDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/company/${id}`, @@ -65,13 +66,13 @@ export class AdminCompanyService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: CompanyDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/company/${id}`, @@ -83,12 +84,12 @@ export class AdminCompanyService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/company/${id}`, diff --git a/src/services/api/services/AdminDepositService.ts b/src/services/api/services/AdminDepositService.ts index 8878335..eca13dc 100644 --- a/src/services/api/services/AdminDepositService.ts +++ b/src/services/api/services/AdminDepositService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { DepositDto } from '../models/DepositDto'; +import type { DepositDtoPaginationContainer } from '../models/DepositDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminDepositService { @@ -10,13 +11,13 @@ export class AdminDepositService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns DepositDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/deposit`, @@ -31,12 +32,12 @@ export class AdminDepositService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: DepositDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/deposit`, @@ -48,12 +49,12 @@ export class AdminDepositService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns DepositDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/deposit/${id}`, @@ -65,13 +66,13 @@ export class AdminDepositService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: DepositDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/deposit/${id}`, @@ -83,12 +84,12 @@ export class AdminDepositService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/deposit/${id}`, diff --git a/src/services/api/services/AdminTelemetryService.ts b/src/services/api/services/AdminTelemetryService.ts index ce158b8..ce56002 100644 --- a/src/services/api/services/AdminTelemetryService.ts +++ b/src/services/api/services/AdminTelemetryService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { TelemetryDto } from '../models/TelemetryDto'; +import type { TelemetryDtoPaginationContainer } from '../models/TelemetryDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminTelemetryService { @@ -39,13 +40,13 @@ export class AdminTelemetryService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns TelemetryDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/telemetry`, @@ -60,12 +61,12 @@ export class AdminTelemetryService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: TelemetryDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/telemetry`, @@ -77,12 +78,12 @@ export class AdminTelemetryService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns TelemetryDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/telemetry/${id}`, @@ -94,13 +95,13 @@ export class AdminTelemetryService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: TelemetryDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/telemetry/${id}`, @@ -112,12 +113,12 @@ export class AdminTelemetryService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/telemetry/${id}`, diff --git a/src/services/api/services/AdminUserRoleService.ts b/src/services/api/services/AdminUserRoleService.ts index 5a5333b..0abe50b 100644 --- a/src/services/api/services/AdminUserRoleService.ts +++ b/src/services/api/services/AdminUserRoleService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { UserRoleDto } from '../models/UserRoleDto'; +import type { UserRoleDtoPaginationContainer } from '../models/UserRoleDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminUserRoleService { @@ -10,13 +11,13 @@ export class AdminUserRoleService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns UserRoleDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/user/role`, @@ -31,12 +32,12 @@ export class AdminUserRoleService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: UserRoleDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/user/role`, @@ -48,12 +49,12 @@ export class AdminUserRoleService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns UserRoleDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/user/role/${id}`, @@ -65,13 +66,13 @@ export class AdminUserRoleService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: UserRoleDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/user/role/${id}`, @@ -83,12 +84,12 @@ export class AdminUserRoleService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/user/role/${id}`, diff --git a/src/services/api/services/AdminUserService.ts b/src/services/api/services/AdminUserService.ts index f4dba1d..7f4e2bb 100644 --- a/src/services/api/services/AdminUserService.ts +++ b/src/services/api/services/AdminUserService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { UserDto } from '../models/UserDto'; +import type { UserDtoPaginationContainer } from '../models/UserDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminUserService { @@ -10,13 +11,13 @@ export class AdminUserService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns UserDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/user`, @@ -31,12 +32,12 @@ export class AdminUserService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: UserDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/user`, @@ -48,12 +49,12 @@ export class AdminUserService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns UserDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/user/${id}`, @@ -65,13 +66,13 @@ export class AdminUserService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: UserDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/user/${id}`, @@ -83,12 +84,12 @@ export class AdminUserService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/user/${id}`, diff --git a/src/services/api/services/AdminWellService.ts b/src/services/api/services/AdminWellService.ts index cbabf24..6c4a54d 100644 --- a/src/services/api/services/AdminWellService.ts +++ b/src/services/api/services/AdminWellService.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ import type { WellDto } from '../models/WellDto'; +import type { WellDtoPaginationContainer } from '../models/WellDtoPaginationContainer'; import { request as __request } from '../core/request'; export class AdminWellService { @@ -10,13 +11,13 @@ export class AdminWellService { * Получить страницу с записями в PaginationContainer * @param skip пропустить skip записей * @param take получить take записей - * @returns any Success + * @returns WellDtoPaginationContainer Success * @throws ApiError */ public static async getPage( skip: number, take: number = 32, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/well`, @@ -31,12 +32,12 @@ export class AdminWellService { /** * Добавить запись * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async insert( requestBody?: WellDto, - ): Promise { + ): Promise { const result = await __request({ method: 'POST', path: `/api/admin/well`, @@ -48,12 +49,12 @@ export class AdminWellService { /** * Получить одну запись по Id * @param id id записи - * @returns any Success + * @returns WellDto Success * @throws ApiError */ public static async get( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/admin/well/${id}`, @@ -65,13 +66,13 @@ export class AdminWellService { * Редактировать запись по id * @param id id записи * @param requestBody запись - * @returns any Success + * @returns number Success * @throws ApiError */ public static async put( id: number, requestBody?: WellDto, - ): Promise { + ): Promise { const result = await __request({ method: 'PUT', path: `/api/admin/well/${id}`, @@ -83,12 +84,12 @@ export class AdminWellService { /** * Удалить запись по id * @param id id записи - * @returns any Success + * @returns number Success * @throws ApiError */ public static async delete( id: number, - ): Promise { + ): Promise { const result = await __request({ method: 'DELETE', path: `/api/admin/well/${id}`, diff --git a/src/services/api/services/AuthService.ts b/src/services/api/services/AuthService.ts index 27732bd..8a58e6a 100644 --- a/src/services/api/services/AuthService.ts +++ b/src/services/api/services/AuthService.ts @@ -42,8 +42,8 @@ export class AuthService { } /** - * Регистрация пользователя. Доступна администратору - * @param requestBody + * Отправить заявку на регистрацию. Заявка подтверждается администратором. + * @param requestBody Информация о новом пользователе * @returns any Success * @throws ApiError */ diff --git a/src/services/api/services/DrillingProgramService.ts b/src/services/api/services/DrillingProgramService.ts index 9aaaea1..c460cfc 100644 --- a/src/services/api/services/DrillingProgramService.ts +++ b/src/services/api/services/DrillingProgramService.ts @@ -6,7 +6,8 @@ import { request as __request } from '../core/request'; export class DrillingProgramService { /** - * @param idWell + * Создает программу бурения + * @param idWell id скважины * @returns string Success * @throws ApiError */ @@ -20,4 +21,20 @@ export class DrillingProgramService { return result.body; } + /** + * Создает программу бурения + * @param idWell id скважины + * @returns string Success + * @throws ApiError + */ + public static async getFileWebLink( + idWell: number, + ): Promise { + const result = await __request({ + method: 'GET', + path: `/api/well/${idWell}/drillingProgram/webUrl`, + }); + return result.body; + } + } \ No newline at end of file diff --git a/src/services/api/services/TelemetryDataSaubService.ts b/src/services/api/services/TelemetryDataSaubService.ts index 8854704..0503708 100644 --- a/src/services/api/services/TelemetryDataSaubService.ts +++ b/src/services/api/services/TelemetryDataSaubService.ts @@ -33,7 +33,7 @@ export class TelemetryDataSaubService { * @param begin дата начала выборки. По умолчанию: текущее время - intervalSec * @param intervalSec интервал времени даты начала выборки, секунды * @param approxPointsCount желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. - * @returns any Success + * @returns TelemetryDataSaubDto Success * @throws ApiError */ public static async getData( @@ -41,7 +41,7 @@ export class TelemetryDataSaubService { begin?: string, intervalSec: number = 600, approxPointsCount: number = 1024, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/TelemetryDataSaub/${idWell}`, diff --git a/src/services/api/services/TelemetryDataSpinService.ts b/src/services/api/services/TelemetryDataSpinService.ts index 71add2c..b01606d 100644 --- a/src/services/api/services/TelemetryDataSpinService.ts +++ b/src/services/api/services/TelemetryDataSpinService.ts @@ -33,7 +33,7 @@ export class TelemetryDataSpinService { * @param begin дата начала выборки. По умолчанию: текущее время - intervalSec * @param intervalSec интервал времени даты начала выборки, секунды * @param approxPointsCount желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. - * @returns any Success + * @returns TelemetryDataSpinDto Success * @throws ApiError */ public static async getData( @@ -41,7 +41,7 @@ export class TelemetryDataSpinService { begin?: string, intervalSec: number = 600, approxPointsCount: number = 1024, - ): Promise { + ): Promise { const result = await __request({ method: 'GET', path: `/api/TelemetryDataSpin/${idWell}`, From 565bc1e1e71d6687a55739c3436fbeaf5912adc9 Mon Sep 17 00:00:00 2001 From: goodmice Date: Thu, 11 Nov 2021 19:24:13 +0500 Subject: [PATCH 03/17] =?UTF-8?q?=D0=9D=D0=B5=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D1=83=D0=B5=D0=BC=D1=8B=D0=B9=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20=D1=83=D0=B4=D0=B0?= =?UTF-8?q?=D0=BB=D1=91=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/charts/ChartTimeArchive.jsx | 73 ---------------------- 1 file changed, 73 deletions(-) delete mode 100644 src/components/charts/ChartTimeArchive.jsx diff --git a/src/components/charts/ChartTimeArchive.jsx b/src/components/charts/ChartTimeArchive.jsx deleted file mode 100644 index e2bffa7..0000000 --- a/src/components/charts/ChartTimeArchive.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import moment from 'moment'; -import { useEffect, useState} from 'react'; -import {ChartTimeBase} from './ChartTimeBase' - -export const GetRandomColor = () => "#" + Math.floor(Math.random()*16777215).toString(16) - -export const CreateDataset = (lineConfig) => { - let color = lineConfig.borderColor - ?? lineConfig.backgroundColor - ?? lineConfig.color - ?? GetRandomColor() - - let datasets = { - label: lineConfig.label, - data: [], - backgroundColor: lineConfig.backgroundColor ?? color, - borderColor: lineConfig.borderColor ?? color, - borderWidth: lineConfig.borderWidth ?? 1, - borderDash: lineConfig.dash ?? [], - } - return datasets -} - -const ChartOptions = { - // responsive: true, - // plugins:{ - // legend:{ - // display: false, - // maxHeight: 64, - // fullSize: true, - // position: 'chartArea', - // align: 'start', - // } - // } -} - -export const ChartTimeArchive = ({lines, data, yDisplay, rangeDate, chartRatio}) => { - const [dataParams, setDataParams] = useState({data:{datasets: []}}) - - useEffect(() => { - if ((!lines) - || (!data)) - return - - let newDatasets = lines.map(lineCfg => { - let dataset = CreateDataset(lineCfg) - dataset.data = data.map(dataItem => { - return { - x: dataItem[lineCfg.xAccessorName], - y: new Date(dataItem[lineCfg.yAccessorName??'date']) - } - }) - return dataset - }) - - let interval = rangeDate ? (rangeDate[1] - rangeDate[0]) / 1000 : null - let startDate = rangeDate ? rangeDate[0] : moment() - let newParams = { - yInterval: interval, - yStart: startDate, - displayLabels: yDisplay??false, - data: { - datasets: newDatasets - } - } - setDataParams(newParams) - }, [data, lines, yDisplay, rangeDate, chartRatio]) - - const opt = ChartOptions - opt.aspectRatio = chartRatio - - return () -} \ No newline at end of file From 274c56dcf7aeb2705c4430826e0d0a5c90fc7aa9 Mon Sep 17 00:00:00 2001 From: goodmice Date: Thu, 11 Nov 2021 19:28:07 +0500 Subject: [PATCH 04/17] =?UTF-8?q?*=20=D0=9A=D0=BE=D0=BB=D0=BE=D0=BD=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=89=D0=B8=D0=B9=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20=D0=B8=20=D1=87?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D0=BD=D1=8B=D0=B5=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=D0=B0=20*=20?= =?UTF-8?q?=D0=92=D1=8B=D0=B1=D0=BE=D1=80=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=D0=B0/=D0=BF=D0=B5=D1=80=D0=B8=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=20=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20*=20?= =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=20ChartTimeBase=20*=20Archive=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=B4=D0=B5=D0=BB=D1=91=D0=BD=20=D0=BD=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83?= =?UTF-8?q?,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D1=80=D0=BB=D0=BB=20=D0=B8=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PeriodPicker.tsx | 31 ++++ src/components/charts/ChartTimeBase.tsx | 42 +++--- src/components/charts/Column.jsx | 91 ++++++++++++ src/pages/Archive.jsx | 62 -------- src/pages/Archive/ArchiveColumn.jsx | 29 ++++ src/pages/Archive/ArchiveDisplay.jsx | 30 ++++ src/pages/Archive/index.jsx | 140 ++++++++++++++++++ src/pages/TelemetryView/Column.jsx | 142 ------------------- src/pages/TelemetryView/MonitoringColumn.jsx | 80 +++++++++++ src/pages/TelemetryView/index.jsx | 29 +--- 10 files changed, 427 insertions(+), 249 deletions(-) create mode 100644 src/components/PeriodPicker.tsx create mode 100644 src/components/charts/Column.jsx delete mode 100644 src/pages/Archive.jsx create mode 100644 src/pages/Archive/ArchiveColumn.jsx create mode 100644 src/pages/Archive/ArchiveDisplay.jsx create mode 100644 src/pages/Archive/index.jsx delete mode 100644 src/pages/TelemetryView/Column.jsx create mode 100644 src/pages/TelemetryView/MonitoringColumn.jsx diff --git a/src/components/PeriodPicker.tsx b/src/components/PeriodPicker.tsx new file mode 100644 index 0000000..615caa8 --- /dev/null +++ b/src/components/PeriodPicker.tsx @@ -0,0 +1,31 @@ +import { Select } from 'antd' + +export const defaultPeriod = '600' + +const timePeriodCollection = [ + { value: '60', label: '1 минута' }, + { value: '300', label: '5 минут' }, + { value: '600', label: '10 минут' }, + { value: '1800', label: '30 минут' }, + { value: '3600', label: '1 час' }, + { value: '21600', label: '6 часов' }, + { value: '43200', label: '12 часов' }, + { value: '86400', label: '24 часа' } +] + +interface PeriodPickerProps { + defaultValue?: string + onChange?: (value: string, option: any) => void +} + +export const PeriodPicker = ({ defaultValue = defaultPeriod, onChange }: PeriodPickerProps) => ( + +) + +export default PeriodPicker diff --git a/src/components/charts/ChartTimeBase.tsx b/src/components/charts/ChartTimeBase.tsx index 5c7ff02..7bd701e 100644 --- a/src/components/charts/ChartTimeBase.tsx +++ b/src/components/charts/ChartTimeBase.tsx @@ -71,6 +71,7 @@ const defaultOptions = { position:'top' } }, + parsing: false, elements:{ point:{ radius:0, @@ -108,7 +109,6 @@ export type ChartTimeData = ChartData = ({options, dataParams const chartRef = useRef(null) const [chart, setChart] = useState() - useEffect(()=>{ - if((chartRef.current)&&(!chart)){ - let thisOptions = {} - Object.assign(thisOptions, defaultOptions, options) + useEffect(() => { + let thisOptions = {} + Object.assign(thisOptions, defaultOptions, options) - let newChart = new Chart(chartRef.current, { - type: 'line', - plugins: [ChartDataLabels], - options: thisOptions, - data: dataParams.data - }) - setChart(newChart) - - return () => chart?.destroy() - } - - if(!chart) return + let newChart = new Chart(chartRef.current, { + type: 'line', + plugins: [ChartDataLabels], + options: thisOptions, + data: { datasets: [] } + }) + setChart(newChart) + return () => newChart?.destroy() + }, [options]) + useEffect(() => { + if (!chart) return; chart.data = dataParams.data - chart.options.aspectRatio = options?.aspectRatio if(dataParams.yStart){ const start = new Date(dataParams.yStart) - const end = new Date(dataParams.yEnd ?? dataParams.yStart) - const interval = Number(dataParams.yInterval ?? (dataParams.yEnd ? end.getSeconds() - start.getSeconds() : 600)) - if (!dataParams.yEnd) - end.setSeconds(end.getSeconds() + interval) + const end = new Date(dataParams.yStart) + const interval = Number(dataParams.yInterval ?? 600) + end.setSeconds(end.getSeconds() + interval) const { unit, stepSize } = timeParamsByInterval(interval) if(chart.options.scales?.y){ @@ -235,7 +231,7 @@ export const ChartTimeBase: React.FC = ({options, dataParams } chart.update() - }, [chart, dataParams, options]) + }, [chart, dataParams]) return() } diff --git a/src/components/charts/Column.jsx b/src/components/charts/Column.jsx new file mode 100644 index 0000000..a278b7e --- /dev/null +++ b/src/components/charts/Column.jsx @@ -0,0 +1,91 @@ +import { useState, useEffect } from 'react' +import { ChartTimeBase } from './ChartTimeBase' + +const chartPluginsOptions = { + plugins: { + datalabels: { + backgroundColor: 'transparent', + borderRadius: 4, + color: '#000B', + display: context => (context.dataset.label === 'wellDepth') && 'auto', + formatter: value => `${value.y.toLocaleTimeString()} ${value.label.toPrecision(4)}`, + padding: 6, + align: 'left', + anchor: 'center', + clip: true + }, + legend: { display: false }, + tooltip: { enable: true } + } +} + +const GetRandomColor = () => '#' + Math.floor(Math.random()*(16**6-1)).toString(16) + +export const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { + let dataset = data?.datasets.find(d => d.label === lineConfig.label) + if(!dataset) { + let color = lineConfig.borderColor + ?? lineConfig.backgroundColor + ?? lineConfig.color + ?? GetRandomColor() + + dataset = { + label: lineConfig.label, + data: [], + backgroundColor: lineConfig.backgroundColor ?? color, + borderColor: lineConfig.borderColor ?? color, + borderWidth: lineConfig.borderWidth ?? 1, + borderDash: lineConfig.dash ?? [], + showLine: lineConfig.showLine ?? !lineConfig.isShape, + fill: lineConfig.fill ?? (lineConfig.isShape ? 'shape' : 'none') + } + + data.datasets.push(dataset) + } + return dataset +} + +export const Column = ({ lineGroup, data, postParsing, interval, yDisplay, yStart, pointCount, savePreviousData }) => { + const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart, }) + + useEffect(()=>{ + if((lineGroup.length === 0) || (data.length === 0)) return + + setDataParams((preDataParams) => { + lineGroup.forEach(lineCfg => { + const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, lineCfg) + let points = data.map(dataItem => ({ + x: lineCfg.xConstValue ?? dataItem[lineCfg.xAccessorName], + label: dataItem[lineCfg.xAccessorName], + y: new Date(dataItem[lineCfg.yAccessorName]), + depth: dataItem.wellDepth + })).filter(point => (point.x ?? null) !== null && (point.y ?? null) !== null) + + if (savePreviousData) + points = [...dataset.data, ...points] + + if(points?.length > 2) + points.sort((a,b) => a.y > b.y ? 1 : -1) + if(points.length > pointCount) + points.splice(0, (pointCount - points.length)) + + dataset.data = points + }) + + preDataParams.yStart = yStart + preDataParams.yInterval = interval + preDataParams.displayLabels = yDisplay + + postParsing?.(preDataParams) + return {...preDataParams} + }) + + }, [data, lineGroup, interval, yDisplay, yStart, postParsing, pointCount, savePreviousData]) + + return +} + +Column.defaultProps = { + pointCount: 2048, + savePreviousData: false +} diff --git a/src/pages/Archive.jsx b/src/pages/Archive.jsx deleted file mode 100644 index 8abd9de..0000000 --- a/src/pages/Archive.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useState, useEffect } from 'react' -import { DatePicker } from 'antd' -import { TelemetryDataSaubService } from '../services/api' -import moment from 'moment' -import { invokeWebApiWrapperAsync } from "../components/factory" -import LoaderPortal from '../components/LoaderPortal' -import { Grid, GridItem } from '../components/Grid' -import { Column } from './TelemetryView/Column' -import { paramsGroups } from './TelemetryView' - -const { RangePicker } = DatePicker - -export default function Archive({idWell}) { - const [dataSaub, setDataSaub] = useState([]) - const [rangeDate, setRangeDate] = useState([moment().subtract(3,'hours'), moment()]) - const [showLoader, setShowLoader] = useState(false) - const [chartInterval, setChartInterval] = useState(600) - - const onChangeRange = (range) => { - setRangeDate(range) - } - - useEffect(() => invokeWebApiWrapperAsync( - async () => { - const interval = (rangeDate[1] - rangeDate[0]) / 1000 - let startDate = rangeDate[0].toISOString() - - const data = await TelemetryDataSaubService.getData(idWell, startDate, interval, 2048) - data?.sort((a, b) => a.date > b.date ? 1 : -1) - setDataSaub(data ?? []) - setChartInterval(interval) - }, - setShowLoader, - `Не удалось загрузить данные по скважине "${idWell}" c ${rangeDate[0]} по ${rangeDate[1]}` - ), [idWell, rangeDate]) - - return ( - <> - - - console.log(e)}> - {paramsGroups.map((group, index) => ( - - - - ))} - - - - ) -} diff --git a/src/pages/Archive/ArchiveColumn.jsx b/src/pages/Archive/ArchiveColumn.jsx new file mode 100644 index 0000000..b3e7909 --- /dev/null +++ b/src/pages/Archive/ArchiveColumn.jsx @@ -0,0 +1,29 @@ +import { Grid, GridItem } from '../../components/Grid' +import { Column } from '../../components/charts/Column' + +export const ArchiveColumn = ({ lineGroup, data, interval, style, headerHeight, yStart }) => { + const dataLast = data?.[data.length - 1] + const pv = lineGroup.filter(line => line.showLabels).map(line => ({ + color: line.color, + label: line.label, + unit: line.units, + value: dataLast?.[line.xAccessorName] + })) + + return ( +
+ + {pv?.map((v, idx) => ( + {v.label} + ))} + + +
+ ) +} diff --git a/src/pages/Archive/ArchiveDisplay.jsx b/src/pages/Archive/ArchiveDisplay.jsx new file mode 100644 index 0000000..54db8b7 --- /dev/null +++ b/src/pages/Archive/ArchiveDisplay.jsx @@ -0,0 +1,30 @@ +import { useEffect, useState } from 'react' +import { Grid, GridItem } from '../../components/Grid' +import { ArchiveColumn } from './ArchiveColumn' +import { paramsGroups } from '../TelemetryView' + +export const ArchiveDisplay = ({data, startDate, interval, onWheel}) => { + const [chartData, setChartData] = useState([]) + + useEffect(() => { + const endDate = new Date(+startDate + interval) + setChartData(data.filter(elm => elm.date >= startDate && elm.date <= endDate)) + }, [data, startDate, interval]) + + return ( + + {paramsGroups.map((group, index) => ( + + + + ))} + + ) +} diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx new file mode 100644 index 0000000..2ee941a --- /dev/null +++ b/src/pages/Archive/index.jsx @@ -0,0 +1,140 @@ +import moment from 'moment' +import { DatePicker } from 'antd' +import { useState, useEffect } from 'react' +import { TelemetryDataSaubService } from '../../services/api' +import { invokeWebApiWrapperAsync } from '../../components/factory' +import LoaderPortal from '../../components/LoaderPortal' +import { Flex } from '../../components/Grid' +import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker' +import { ArchiveDisplay } from './ArchiveDisplay' + +const DATA_COUNT = 2048 // Колличество точек на подгрузку графика +const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков +const LOADING_TRIGGER = 0.5 +const MOUSE_SENSITIVITY = 1 / 530 + +const getLoadingInterval = (loaded, startDate, interval) => { + // Если данные загружены и дата не заходит за тригер дозагрузка не требуется + if ( + loaded && + +startDate - interval * LOADING_TRIGGER > loaded.start && + +startDate + interval * (LOADING_TRIGGER + 1) < loaded.end + ) + return { loadingStartDate: startDate, newLoaded: loaded, loadingInterval: 0 } + + let loadingStartDate = new Date(+startDate - interval * ADDITIVE_PAGES) + let loadingEndDate = new Date(+startDate + interval * (ADDITIVE_PAGES + 1)) + + const newLoaded = { + start: loadingStartDate, + end: loadingEndDate + } + + if (loaded) { + if (loadingStartDate >= loaded.start) + loadingStartDate = new Date(loaded.end) + if (loadingEndDate <= loaded.end) + loadingEndDate = new Date(loaded.start) + newLoaded.start = new Date(Math.min(loaded.start, loadingStartDate)) + newLoaded.end = new Date(Math.max(loaded.end, loadingEndDate)) + } + + const loadingInterval = Math.trunc((loadingEndDate - loadingStartDate) / 1000) + + return { + loadingStartDate, + newLoaded, + loadingInterval + } +} + +export default function Archive({idWell}) { + const [dataSaub, setDataSaub] = useState([]) + const [chartInterval, setChartInterval] = useState(parseInt(defaultPeriod) * 1000) + const [startDate, setStartDate] = useState(new Date(+new Date() - chartInterval)) + const [showLoader, setShowLoader] = useState(false) + const [loaded, setLoaded] = useState(null) + const [dateMinLimit, setDateMinLimit] = useState(0) + + const onGraphWheel = (e) => { + if (loaded) { + setStartDate((prevStartDate) => { + const offset = e.deltaY * chartInterval * MOUSE_SENSITIVITY + const nextStartDate = new Date(+prevStartDate + offset) + return new Date(Math.max(loaded.start, Math.min(nextStartDate, +loaded.end - chartInterval))) + }) + } + } + + useEffect(() => invokeWebApiWrapperAsync( + async () => { + const dates = await TelemetryDataSaubService.getDataDatesRange(idWell) + setDateMinLimit(new Date(dates?.from ?? 0)) + setStartDate(new Date(+new Date(dates?.to ?? new Date()) - chartInterval)) + }, + setShowLoader, + `Не удалось загрузить диапозон телеметрии для скважины "${idWell}"` + ), []) + + useEffect(() => { + setStartDate((startDate) => new Date(Math.min(+new Date() - chartInterval, startDate))) + }, [chartInterval]) + + useEffect(() => { + if (showLoader) return + const { loadingStartDate, loadingInterval, newLoaded } = getLoadingInterval(loaded, startDate, chartInterval) + if (loadingInterval <= 0) return + invokeWebApiWrapperAsync( + async () => { + const data = await TelemetryDataSaubService.getData(idWell, loadingStartDate.toISOString(), loadingInterval, DATA_COUNT) + + 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))) + setLoaded({ start: loadedStartDate, end: loadedEndDate }) + + if (data) { + data.forEach(elm => elm.date = new Date(elm.date)) + setDataSaub((prevDataSaub) => { + const newData = [...prevDataSaub, ...data] + newData.sort((a, b) => a.date > b.date ? 1 : -1) + return newData.filter(val => { + const date = new Date(val.date) + return loadedStartDate < date && date < loadedEndDate + }) + }) + } + + }, + setShowLoader, + `Не удалось загрузить данные по скважине "${idWell}" c ${startDate.toISOString()} по ${new Date(+startDate + chartInterval).toISOString()}` + ) + }, [idWell, chartInterval, loaded, startDate]) + + return ( + <> + +
+ Начальная дата:  + setStartDate(new Date(startDate))} + value={moment(startDate)} + /> +
+
+ Период:  + setChartInterval(parseInt(val) * 1000)} /> +
+
+ + + + + ) +} diff --git a/src/pages/TelemetryView/Column.jsx b/src/pages/TelemetryView/Column.jsx deleted file mode 100644 index d67194e..0000000 --- a/src/pages/TelemetryView/Column.jsx +++ /dev/null @@ -1,142 +0,0 @@ -import { useState, useEffect } from 'react' -import { Grid, GridItem } from '../../components/Grid' -import { ChartTimeBase } from '../../components/charts/ChartTimeBase' -import { ChartTimeOnlineFooter } from './ChartTimeOnlineFooter' - -const stroke = (sz = '2px', c = 'white') => ({ textShadow: `-${sz} -${sz} 0 ${c}, ${sz} -${sz} 0 ${c}, -${sz} ${sz} 0 ${c}, ${sz} ${sz} 0 ${c}` }) - -const chartPluginsOptions = { - plugins: { - datalabels: { - backgroundColor: 'transparent', - borderRadius: 4, - color: '#000B', - display: context => (context.dataset.label === 'wellDepth') && 'auto', - formatter: value => `${value.y.toLocaleTimeString()} ${value.label.toPrecision(4)}`, - padding: 6, - align: 'left', - anchor: 'center', - clip: true - }, - legend: { display: false }, - tooltip: { enable: true } - } -} - -const GetLimitShape = (flowChartData, points, accessor) => { - const min = [], max = [] - - for (let 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 GetRandomColor = () => '#' + Math.floor(Math.random()*16777215).toString(16) -const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { - let dataset = data?.datasets.find(d => d.label === lineConfig.label) - if(!dataset) { - let color = lineConfig.borderColor - ?? lineConfig.backgroundColor - ?? lineConfig.color - ?? GetRandomColor() - - dataset = { - label: lineConfig.label, - data: [], - backgroundColor: lineConfig.backgroundColor ?? color, - borderColor: lineConfig.borderColor ?? color, - borderWidth: lineConfig.borderWidth ?? 1, - borderDash: lineConfig.dash ?? [], - showLine: lineConfig.showLine ?? !lineConfig.isShape, - fill: lineConfig.fill ?? (lineConfig.isShape ? 'shape' : 'none') - } - data.datasets.push(dataset); - } - return dataset -} - -export const Column = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, yDisplay, yStart, showLastValues, pointCount }) => { - const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart: new Date(), }) - - let dataLast = data?.[data.length - 1] - let pv = lineGroup.filter(line => line.showLabels).map(line => ({ - color: line.color, - label: line.label, - unit: line.units, - value: dataLast?.[line.xAccessorName] - })) - - useEffect(()=>{ - if((lineGroup.length === 0) || (data.length === 0)) return - - setDataParams((preDataParams) => { - lineGroup.forEach(lineCfg => { - if (lineCfg.isShape) return - const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, lineCfg) - const points = data.map(dataItem => ({ - x: lineCfg.xConstValue ?? dataItem[lineCfg.xAccessorName], - label: dataItem[lineCfg.xAccessorName], - y: new Date(dataItem[lineCfg.yAccessorName]), - depth: dataItem.wellDepth - })).filter(point => (point.x ?? null) !== null && (point.y ?? null) !== null) - - const lineData = [ ...dataset.data, ...points,] - if(points?.length > 2) - lineData.sort((a,b) => a.y > b.y ? 1 : -1) - if(lineData.length > pointCount) - lineData.splice(0, (pointCount - lineData.length)) - - dataset.data = lineData - - //Area - if (flowChartData) { - lineGroup.filter(cfg => cfg.isShape && cfg.xAccessorName === lineCfg.xAccessorName).forEach(areaCfg => { - const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, areaCfg) - dataset.data = GetLimitShape(flowChartData, lineData, areaCfg.xAccessorName) - }) - } - }) - - preDataParams.yStart = yStart ?? new Date(Math.max(new Date(dataLast.date), preDataParams.yStart ?? new Date(0))) - if (!yStart) - preDataParams.yStart.setSeconds(preDataParams.yStart.getSeconds() - interval * 0.97) - preDataParams.yInterval = interval - preDataParams.displayLabels = yDisplay ?? false - return {...preDataParams} - }) - - }, [data, lineGroup, interval, yDisplay, yStart, flowChartData, dataLast, pointCount]) - - return ( -
- - {pv?.map((v, idx) => ( - {v.label} - ))} - -
- {showLastValues && ( - - {pv?.map((v, idx) => ( - {v.value?.toFixed(2) ?? '--'} {v.unit} - ))} - - )} - -
- {showLastValues && ( - - )} -
- ) -} - -Column.defaultProps = { - pointCount: 2048 -} diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx new file mode 100644 index 0000000..2d7aa5d --- /dev/null +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -0,0 +1,80 @@ +import { Grid, GridItem } from '../../components/Grid' +import { Column, GetOrCreateDatasetByLineConfig } from '../../components/charts/Column' +import { ChartTimeOnlineFooter } from './ChartTimeOnlineFooter' +import { useEffect, useState } from 'react' + +const stroke = (sz = '2px', c = 'white') => ({ textShadow: `-${sz} -${sz} 0 ${c}, ${sz} -${sz} 0 ${c}, -${sz} ${sz} 0 ${c}, ${sz} ${sz} 0 ${c}` }) + +const GetLimitShape = (flowChartData, points, accessor) => { + const min = [], max = [] + + for (let 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()) ?? [] +} + +export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight }) => { + const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) + const dataLast = data?.[data.length - 1] + const yStart = new Date(+(dataLast?.date ? dataLast.date : new Date()) - interval) + const pv = lineGroup.filter(line => line.showLabels).map(line => ({ + color: line.color, + label: line.label, + unit: line.units, + value: dataLast?.[line.xAccessorName] + })) + + const postParsing = (data) => { + if (flowChartData) { + lineGroupWithoutShapes.forEach(lineCfg => { + const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg) + + 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) + }) + }) + } + } + + useEffect(() => { + setLineGroupWithoutShapes(lineGroup.filter(cfg => !cfg.isShape)) + }, [lineGroup]) + + return ( +
+ + {pv?.map((v, idx) => ( + {v.label} + ))} + +
+ + {pv?.map((v, idx) => ( + {v.value?.toFixed(2) ?? '--'} {v.unit} + ))} + + +
+ +
+ ) +} + +MonitoringColumn.defaultProps = { + pointCount: 2048 +} diff --git a/src/pages/TelemetryView/index.jsx b/src/pages/TelemetryView/index.jsx index 80cb9e7..8f81e94 100644 --- a/src/pages/TelemetryView/index.jsx +++ b/src/pages/TelemetryView/index.jsx @@ -1,7 +1,7 @@ import { useState, useEffect } from 'react' import { Select } from 'antd' -import { Column } from './Column' +import { MonitoringColumn } from './MonitoringColumn' import { CustomColumn } from './CustomColumn' import ActiveMessagesOnline from './ActiveMessagesOnline' import { ModeDisplay } from './ModeDisplay' @@ -22,6 +22,7 @@ import MomentStabPicEnabled from '../../images/DempherOn.png' import MomentStabPicDisabled from '../../images/DempherOff.png' import SpinPicEnabled from '../../images/SpinEnabled.png' import SpinPicDisabled from '../../images/SpinDisabled.png' +import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker' import '../../styles/message.css' @@ -259,19 +260,6 @@ export const paramsGroups = [ rotorTorqueGroup ] -const timePeriodCollection = [ - { value: '60', label: '1 минута' }, - { value: '300', label: '5 минут' }, - { value: '600', label: '10 минут' }, - { value: '1800', label: '30 минут' }, - { value: '3600', label: '1 час' }, - { value: '21600', label: '6 часов' }, - { value: '43200', label: '12 часов' }, - { value: '86400', label: '24 часа' } -] - -const defaultChartInterval = '600' - const getLast = (data) => Array.isArray(data) ? data.slice(-1)[0] : data @@ -305,13 +293,11 @@ const getIndexOfDrillingBy = (dataSaub) => { export default function TelemetryView({ idWell }) { const [dataSaub, setDataSaub] = useState([]) const [dataSpin, setDataSpin] = useState([]) - const [chartInterval, setChartInterval] = useState(defaultChartInterval) + const [chartInterval, setChartInterval] = useState(defaultPeriod) const [wellData, setWellData] = useState({ idState: 0 }) const [showLoader, setShowLoader] = useState(false) const [flowChartData, setFlowChartData] = useState([]) - const options = timePeriodCollection.map((line) => ) - const handleDataSaub = (data) => { if (data) { data.forEach((_, idx) => { @@ -382,9 +368,7 @@ export default function TelemetryView({ idWell }) {
Интервал:  - +
Статус:  @@ -406,7 +390,7 @@ export default function TelemetryView({ idWell }) { {paramsGroups.map((group, index) => - + showBorder={getIndexOfDrillingBy(dataSaub) === index} + /> )} From 7a95007f448bc4701a87283f9e92b911e838c904 Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 16:00:57 +0500 Subject: [PATCH 05/17] =?UTF-8?q?=D0=9E=D0=B1=D1=80=D0=B5=D0=B7=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=87=D0=B8=D1=81=D0=BB=D0=B0=20=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=B5=D0=BA=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/charts/Column.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/charts/Column.jsx b/src/components/charts/Column.jsx index a278b7e..4be6328 100644 --- a/src/components/charts/Column.jsx +++ b/src/components/charts/Column.jsx @@ -67,7 +67,7 @@ export const Column = ({ lineGroup, data, postParsing, interval, yDisplay, yStar if(points?.length > 2) points.sort((a,b) => a.y > b.y ? 1 : -1) if(points.length > pointCount) - points.splice(0, (pointCount - points.length)) + points.splice(0, points.length - pointCount) dataset.data = points }) From 809dbb42fbe0e969dbb95a6067b89262423f5588 Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 16:01:29 +0500 Subject: [PATCH 06/17] =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=87=D1=91=D1=82=D0=B0=20=D0=BD=D0=B0=D1=87?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9=20=D0=B4=D0=B0=D1=82=D1=8B?= =?UTF-8?q?=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView/MonitoringColumn.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index 2d7aa5d..7b1607b 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -22,7 +22,7 @@ const GetLimitShape = (flowChartData, points, accessor) => { export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight }) => { const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) const dataLast = data?.[data.length - 1] - const yStart = new Date(+(dataLast?.date ? dataLast.date : new Date()) - interval) + const yStart = new Date(+(dataLast?.date ? new Date(dataLast.date) : new Date()) - interval * 1000) const pv = lineGroup.filter(line => line.showLabels).map(line => ({ color: line.color, label: line.label, From f9d019ffda82bed25f72ccedb5d29865419fa3dc Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 16:22:53 +0500 Subject: [PATCH 07/17] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8?= =?UTF-8?q?=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=B8=D0=BD=D0=B8=D0=B9?= =?UTF-8?q?=20=D0=B0=D1=80=D1=85=D0=B8=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Archive/ArchiveColumn.jsx | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/pages/Archive/ArchiveColumn.jsx b/src/pages/Archive/ArchiveColumn.jsx index b3e7909..0118086 100644 --- a/src/pages/Archive/ArchiveColumn.jsx +++ b/src/pages/Archive/ArchiveColumn.jsx @@ -1,14 +1,20 @@ +import { useEffect, useState } from 'react' import { Grid, GridItem } from '../../components/Grid' import { Column } from '../../components/charts/Column' export const ArchiveColumn = ({ lineGroup, data, interval, style, headerHeight, yStart }) => { - const dataLast = data?.[data.length - 1] - const pv = lineGroup.filter(line => line.showLabels).map(line => ({ - color: line.color, - label: line.label, - unit: line.units, - value: dataLast?.[line.xAccessorName] - })) + const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) + const [pv, setPV] = useState([]) + + useEffect(() => { + const lgws = lineGroup.filter(cfg => !cfg.isShape) + setLineGroupWithoutShapes(lgws) + setPV(lgws.filter(line => line.showLabels).map(line => ({ + color: line.color, + label: line.label + }))) + }, [lineGroup]) + return (
@@ -19,7 +25,7 @@ export const ArchiveColumn = ({ lineGroup, data, interval, style, headerHeight, Date: Fri, 12 Nov 2021 16:23:26 +0500 Subject: [PATCH 08/17] =?UTF-8?q?filter=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=91=D0=BD=20=D0=BD=D0=B0=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8F=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Archive/ArchiveDisplay.jsx | 38 +++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/pages/Archive/ArchiveDisplay.jsx b/src/pages/Archive/ArchiveDisplay.jsx index 54db8b7..7035c82 100644 --- a/src/pages/Archive/ArchiveDisplay.jsx +++ b/src/pages/Archive/ArchiveDisplay.jsx @@ -3,12 +3,48 @@ import { Grid, GridItem } from '../../components/Grid' import { ArchiveColumn } from './ArchiveColumn' import { paramsGroups } from '../TelemetryView' +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 = ({data, startDate, interval, onWheel}) => { const [chartData, setChartData] = useState([]) useEffect(() => { const endDate = new Date(+startDate + interval) - setChartData(data.filter(elm => elm.date >= startDate && elm.date <= endDate)) + setChartData(cutData(data, startDate, endDate)) }, [data, startDate, interval]) return ( From 80622351f8b4d21ffca60485cc200a42fc8f2c6b Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 16:24:07 +0500 Subject: [PATCH 09/17] =?UTF-8?q?=D0=93=D1=80=D0=B0=D1=84=D0=B8=D0=BA=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D0=B3=D0=B5=20=D1=81=D0=B4=D0=B2=D0=B8=D0=BD=D1=83=D1=82?= =?UTF-8?q?=20=D0=BD=D0=B0=203%=20=D0=B2=D0=B2=D0=B5=D1=80=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView/MonitoringColumn.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index 7b1607b..702e42c 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -22,7 +22,7 @@ const GetLimitShape = (flowChartData, points, accessor) => { export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight }) => { const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) const dataLast = data?.[data.length - 1] - const yStart = new Date(+(dataLast?.date ? new Date(dataLast.date) : new Date()) - interval * 1000) + const yStart = new Date(+(dataLast?.date ? new Date(dataLast.date) : new Date()) - interval * 1000 * 0.97) const pv = lineGroup.filter(line => line.showLabels).map(line => ({ color: line.color, label: line.label, From e803a9172b6bee53dc689466bc81f8d385d6b671 Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 18:06:39 +0500 Subject: [PATCH 10/17] Column use memo added --- src/components/charts/Column.jsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/charts/Column.jsx b/src/components/charts/Column.jsx index 4be6328..0a7eea5 100644 --- a/src/components/charts/Column.jsx +++ b/src/components/charts/Column.jsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import { ChartTimeBase } from './ChartTimeBase' const chartPluginsOptions = { @@ -45,8 +45,10 @@ export const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { return dataset } -export const Column = ({ lineGroup, data, postParsing, interval, yDisplay, yStart, pointCount, savePreviousData }) => { +export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDisplay, yStart, pointCount, savePreviousData }) => { const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart, }) + if (!pointCount || !Number.isInteger(pointCount)) + pointCount = 2048 useEffect(()=>{ if((lineGroup.length === 0) || (data.length === 0)) return @@ -83,9 +85,4 @@ export const Column = ({ lineGroup, data, postParsing, interval, yDisplay, yStar }, [data, lineGroup, interval, yDisplay, yStart, postParsing, pointCount, savePreviousData]) return -} - -Column.defaultProps = { - pointCount: 2048, - savePreviousData: false -} +}) \ No newline at end of file From a9c148d891ca256e5cf97225baa5dd4371ced871 Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 18:08:22 +0500 Subject: [PATCH 11/17] =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D1=80=D0=BB=20=D0=BE?= =?UTF-8?q?=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=20=D0=B4=D0=BE?= =?UTF-8?q?=20=D1=82=D0=B5=D0=BA=D1=83=D1=89=D0=B5=D0=B3=D0=BE=20=D0=B2?= =?UTF-8?q?=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20filter=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=91=D0=BD=20=D0=BD=D0=B0=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=BF=D0=BE=D0=BB=D1=8F=D1=86=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Archive/index.jsx | 43 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx index 2ee941a..da660f4 100644 --- a/src/pages/Archive/index.jsx +++ b/src/pages/Archive/index.jsx @@ -6,12 +6,12 @@ import { invokeWebApiWrapperAsync } from '../../components/factory' import LoaderPortal from '../../components/LoaderPortal' import { Flex } from '../../components/Grid' import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker' -import { ArchiveDisplay } from './ArchiveDisplay' +import { ArchiveDisplay, cutData } from './ArchiveDisplay' const DATA_COUNT = 2048 // Колличество точек на подгрузку графика const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков const LOADING_TRIGGER = 0.5 -const MOUSE_SENSITIVITY = 1 / 530 +const WHEEL_SENSITIVITY = 1 / 530 const getLoadingInterval = (loaded, startDate, interval) => { // Если данные загружены и дата не заходит за тригер дозагрузка не требуется @@ -22,8 +22,8 @@ const getLoadingInterval = (loaded, startDate, interval) => { ) return { loadingStartDate: startDate, newLoaded: loaded, loadingInterval: 0 } - let loadingStartDate = new Date(+startDate - interval * ADDITIVE_PAGES) - let loadingEndDate = new Date(+startDate + interval * (ADDITIVE_PAGES + 1)) + let loadingStartDate = +startDate - interval * ADDITIVE_PAGES + let loadingEndDate = +startDate + interval * (ADDITIVE_PAGES + 1) const newLoaded = { start: loadingStartDate, @@ -32,18 +32,21 @@ const getLoadingInterval = (loaded, startDate, interval) => { if (loaded) { if (loadingStartDate >= loaded.start) - loadingStartDate = new Date(loaded.end) + loadingStartDate = loaded.end if (loadingEndDate <= loaded.end) - loadingEndDate = new Date(loaded.start) - newLoaded.start = new Date(Math.min(loaded.start, loadingStartDate)) - newLoaded.end = new Date(Math.max(loaded.end, loadingEndDate)) + loadingEndDate = loaded.start + newLoaded.start = Math.min(loaded.start, loadingStartDate) + newLoaded.end = Math.max(loaded.end, loadingEndDate) } const loadingInterval = Math.trunc((loadingEndDate - loadingStartDate) / 1000) return { - loadingStartDate, - newLoaded, + loadingStartDate: new Date(loadingStartDate), + newLoaded: { + start: new Date(newLoaded.start), + end: new Date(newLoaded.end) + }, loadingInterval } } @@ -54,14 +57,14 @@ export default function Archive({idWell}) { const [startDate, setStartDate] = useState(new Date(+new Date() - chartInterval)) const [showLoader, setShowLoader] = useState(false) const [loaded, setLoaded] = useState(null) - const [dateMinLimit, setDateMinLimit] = useState(0) const onGraphWheel = (e) => { if (loaded) { setStartDate((prevStartDate) => { - const offset = e.deltaY * chartInterval * MOUSE_SENSITIVITY + const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY const nextStartDate = new Date(+prevStartDate + offset) - return new Date(Math.max(loaded.start, Math.min(nextStartDate, +loaded.end - chartInterval))) + const lastPossibleDate = new Date(Math.min(loaded.end, new Date()) - chartInterval) + return new Date(Math.max(loaded.start, Math.min(nextStartDate, lastPossibleDate))) }) } } @@ -69,8 +72,12 @@ export default function Archive({idWell}) { useEffect(() => invokeWebApiWrapperAsync( async () => { const dates = await TelemetryDataSaubService.getDataDatesRange(idWell) - setDateMinLimit(new Date(dates?.from ?? 0)) - setStartDate(new Date(+new Date(dates?.to ?? new Date()) - chartInterval)) + let startDate + if (dates?.from && dates?.to) + startDate = Math.max(new Date(dates.from), +new Date(dates.to) - chartInterval) + else + startDate = +new Date() - chartInterval + setStartDate(new Date(startDate)) }, setShowLoader, `Не удалось загрузить диапозон телеметрии для скважины "${idWell}"` @@ -78,6 +85,7 @@ export default function Archive({idWell}) { useEffect(() => { setStartDate((startDate) => new Date(Math.min(+new Date() - chartInterval, startDate))) + setDataSaub([]) }, [chartInterval]) useEffect(() => { @@ -97,10 +105,7 @@ export default function Archive({idWell}) { setDataSaub((prevDataSaub) => { const newData = [...prevDataSaub, ...data] newData.sort((a, b) => a.date > b.date ? 1 : -1) - return newData.filter(val => { - const date = new Date(val.date) - return loadedStartDate < date && date < loadedEndDate - }) + return cutData(newData, loadedStartDate, loadedEndDate) }) } From e553c4c67fdc9ca5fb4de98de0c6dc2fccb5215a Mon Sep 17 00:00:00 2001 From: goodmice Date: Fri, 12 Nov 2021 18:08:40 +0500 Subject: [PATCH 12/17] =?UTF-8?q?pointCount=20=D0=B2=D1=8B=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D0=B5=D0=BD=20=D0=B2=20props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView/MonitoringColumn.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index 702e42c..91ef8ed 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -19,7 +19,7 @@ const GetLimitShape = (flowChartData, points, accessor) => { return min.concat(max.reverse()) ?? [] } -export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight }) => { +export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, pointCount }) => { const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) const dataLast = data?.[data.length - 1] const yStart = new Date(+(dataLast?.date ? new Date(dataLast.date) : new Date()) - interval * 1000 * 0.97) @@ -68,6 +68,7 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho yDisplay={false} yStart={yStart} savePreviousData={true} + pointCount={pointCount} />
From 6d962a89e3763d3f303215c2c1bbf93acd475d48 Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 15 Nov 2021 10:57:37 +0500 Subject: [PATCH 13/17] =?UTF-8?q?=D0=97=D0=BD=D0=B0=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20pointCount=20=D0=BF=D0=BE=20=D1=83=D0=BC=D0=BE?= =?UTF-8?q?=D0=BB=D1=87=D0=B0=D0=BD=D0=B8=D1=8E=20=D1=83=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=B8=D0=B7=20components/charts/Column?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/charts/Column.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/charts/Column.jsx b/src/components/charts/Column.jsx index 0a7eea5..5ede01c 100644 --- a/src/components/charts/Column.jsx +++ b/src/components/charts/Column.jsx @@ -47,8 +47,6 @@ export const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDisplay, yStart, pointCount, savePreviousData }) => { const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart, }) - if (!pointCount || !Number.isInteger(pointCount)) - pointCount = 2048 useEffect(()=>{ if((lineGroup.length === 0) || (data.length === 0)) return From 0a27ccdfef70a9c07c55889271f4ceaf949fd2af Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 15 Nov 2021 10:58:22 +0500 Subject: [PATCH 14/17] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=B4=D0=B8=D0=BD=D0=B0=D0=BA=D0=BE=D0=B2=D1=8B?= =?UTF-8?q?=D1=85=20=D1=82=D0=BE=D1=87=D0=B5=D0=BA=20=D0=B8=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B5=D0=B7=D0=BA=D0=B0=20=D0=BF=D0=BE=20pointCount?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView/MonitoringColumn.jsx | 23 +++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index 91ef8ed..fab0fc3 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -19,6 +19,14 @@ const GetLimitShape = (flowChartData, points, accessor) => { return min.concat(max.reverse()) ?? [] } +const RemoveSimilar = (input) => { + const data = [input[0]] + for (let i = 1; i < input.length; i++) + if (input[i].y !== input[i - 1].y) + data.push(input[i]) + return data +} + export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, pointCount }) => { const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) const dataLast = data?.[data.length - 1] @@ -31,16 +39,20 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho })) const postParsing = (data) => { - if (flowChartData) { - lineGroupWithoutShapes.forEach(lineCfg => { - const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg) + lineGroupWithoutShapes.forEach(lineCfg => { + const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg) + lineDataSet.data = RemoveSimilar(lineDataSet.data) + if (lineDataSet.data.length > pointCount) + lineDataSet.data.splice(0, pointCount - lineDataSet.data.length) + + 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) }) - }) - } + } + }) } useEffect(() => { @@ -68,7 +80,6 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho yDisplay={false} yStart={yStart} savePreviousData={true} - pointCount={pointCount} />
From 5ce80f0446b16693299ed497f05b86714e26b02e Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 15 Nov 2021 11:42:09 +0500 Subject: [PATCH 15/17] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=B2=20=D1=82=D0=BE?= =?UTF-8?q?=D1=87=D0=BA=D0=B0=D1=85=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=B2=20=D0=BF=D1=80=D0=BE=D0=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/charts/Column.jsx | 11 +++++------ src/pages/TelemetryView/MonitoringColumn.jsx | 3 +++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/charts/Column.jsx b/src/components/charts/Column.jsx index 5ede01c..cc48d04 100644 --- a/src/components/charts/Column.jsx +++ b/src/components/charts/Column.jsx @@ -45,7 +45,7 @@ export const GetOrCreateDatasetByLineConfig = (data, lineConfig) => { return dataset } -export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDisplay, yStart, pointCount, savePreviousData }) => { +export const Column = ({ lineGroup, data, postParsing, additionalPointData, interval, yDisplay, yStart, savePreviousData }) => { const [dataParams, setDataParams] = useState({data: {datasets:[]}, yStart, }) useEffect(()=>{ @@ -58,7 +58,8 @@ export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDis x: lineCfg.xConstValue ?? dataItem[lineCfg.xAccessorName], label: dataItem[lineCfg.xAccessorName], y: new Date(dataItem[lineCfg.yAccessorName]), - depth: dataItem.wellDepth + depth: dataItem.wellDepth, + ...additionalPointData?.(dataItem, lineCfg) })).filter(point => (point.x ?? null) !== null && (point.y ?? null) !== null) if (savePreviousData) @@ -66,8 +67,6 @@ export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDis if(points?.length > 2) points.sort((a,b) => a.y > b.y ? 1 : -1) - if(points.length > pointCount) - points.splice(0, points.length - pointCount) dataset.data = points }) @@ -80,7 +79,7 @@ export const Column = React.memo(({ lineGroup, data, postParsing, interval, yDis return {...preDataParams} }) - }, [data, lineGroup, interval, yDisplay, yStart, postParsing, pointCount, savePreviousData]) + }, [data, lineGroup, interval, yDisplay, yStart, postParsing, savePreviousData, additionalPointData]) return -}) \ No newline at end of file +} diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index fab0fc3..97e4be0 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -38,6 +38,8 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho value: dataLast?.[line.xAccessorName] })) + const addPointData = (point) => ({ depth: point.wellDepth }) + const postParsing = (data) => { lineGroupWithoutShapes.forEach(lineCfg => { const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg) @@ -76,6 +78,7 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho data={data} lineGroup={lineGroupWithoutShapes} postParsing={postParsing} + additionalPointData={addPointData} interval={interval} yDisplay={false} yStart={yStart} From 909ed39fafbde0f52af8c1e48f4e8341ac78ebef Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 15 Nov 2021 12:51:33 +0500 Subject: [PATCH 16/17] =?UTF-8?q?=D0=9D=D0=BE=D1=80=D0=BC=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B7=D0=BD=D0=B0=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=B8=20=D1=81=D0=BE=D1=80=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=B2=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView/index.jsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/pages/TelemetryView/index.jsx b/src/pages/TelemetryView/index.jsx index 8f81e94..a4bc8f1 100644 --- a/src/pages/TelemetryView/index.jsx +++ b/src/pages/TelemetryView/index.jsx @@ -290,6 +290,14 @@ const getIndexOfDrillingBy = (dataSaub) => { return order[idFeedRegulator] ?? -1 } +export const sortByDate = (a, b) => a.date > b.date ? 1 : -1 +export const normalizeData = (data) => data?.map(item => ({ + ...item, + rotorSpeed: item.rotorSpeed < 1 ? 0 : item.rotorSpeed, + rotorTorque: item.rotorTorque < 1 ? 0 : item.rotorTorque, + blockSpeed: Math.abs(item.blockSpeed) +})) ?? [] + export default function TelemetryView({ idWell }) { const [dataSaub, setDataSaub] = useState([]) const [dataSpin, setDataSpin] = useState([]) @@ -300,15 +308,9 @@ export default function TelemetryView({ idWell }) { const handleDataSaub = (data) => { if (data) { - data.forEach((_, idx) => { - if (data[idx].rotorSpeed < 1) - data[idx].rotorSpeed = 0; - if (data[idx].rotorTorque < 1) - data[idx].rotorTorque = 0; - data[idx].blockSpeed = Math.abs(data[idx].blockSpeed) - }) - data.sort((a, b) => a.date > b.date ? 1 : -1) - setDataSaub(data) + const dataSaub = normalizeData(data) + dataSaub.sort(sortByDate) + setDataSaub(dataSaub) } } From 95cfc930486480e04327e29bf10bcdefae76eaec Mon Sep 17 00:00:00 2001 From: goodmice Date: Mon, 15 Nov 2021 12:52:02 +0500 Subject: [PATCH 17/17] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Archive/index.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Archive/index.jsx b/src/pages/Archive/index.jsx index da660f4..f22a53b 100644 --- a/src/pages/Archive/index.jsx +++ b/src/pages/Archive/index.jsx @@ -7,6 +7,7 @@ import LoaderPortal from '../../components/LoaderPortal' import { Flex } from '../../components/Grid' import { PeriodPicker, defaultPeriod } from '../../components/PeriodPicker' import { ArchiveDisplay, cutData } from './ArchiveDisplay' +import { normalizeData, sortByDate } from '../TelemetryView' const DATA_COUNT = 2048 // Колличество точек на подгрузку графика const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков @@ -103,8 +104,8 @@ export default function Archive({idWell}) { if (data) { data.forEach(elm => elm.date = new Date(elm.date)) setDataSaub((prevDataSaub) => { - const newData = [...prevDataSaub, ...data] - newData.sort((a, b) => a.date > b.date ? 1 : -1) + const newData = [...prevDataSaub, ...normalizeData(data)] + newData.sort(sortByDate) return cutData(newData, loadedStartDate, loadedEndDate) }) }