diff --git a/src/components/Table/DateRangeWrapper.tsx b/src/components/Table/DateRangeWrapper.tsx index 506879f..1dfa23c 100644 --- a/src/components/Table/DateRangeWrapper.tsx +++ b/src/components/Table/DateRangeWrapper.tsx @@ -10,7 +10,6 @@ const { RangePicker } = DatePicker export type DateRangeWrapperProps = RangePickerSharedProps & { value: RangeValue, - onChange: (date: RangeValue) => any isUTC?: boolean } @@ -19,13 +18,15 @@ const normalizeDates = (value: RangeValue, isUTC?: boolean): RangeValue< value[1] ? (isUTC ? moment.utc(value[1]).local() : moment(value[1])) : null, ] -export const DateRangeWrapper = memo(({ value, onChange, isUTC, ...other }) => ( +export const DateRangeWrapper = memo(({ value, isUTC, ...other }) => ( onChange(date)} + defaultValue={[ + moment().subtract(1, 'days').startOf('day'), + moment().startOf('day'), + ]} value={normalizeDates(value)} {...other} /> diff --git a/src/components/charts/ChartTimeBase.tsx b/src/components/charts/ChartTimeBase.tsx index 8140a67..3c1b6db 100644 --- a/src/components/charts/ChartTimeBase.tsx +++ b/src/components/charts/ChartTimeBase.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { memo, useEffect, useRef, useState } from 'react' import { Chart, TimeScale, @@ -178,7 +178,7 @@ export const timeParamsByInterval = (intervalSec: number): TimeParams => { return { unit, stepSize } } -export const ChartTimeBase: React.FC = ({options, dataParams}) => { +export const ChartTimeBase = memo(({ options, dataParams }) => { const chartRef = useRef(null) const [chart, setChart] = useState() @@ -217,4 +217,4 @@ export const ChartTimeBase: React.FC = ({options, dataParams }, [chart, dataParams]) return() -} +}) diff --git a/src/components/charts/Column.tsx b/src/components/charts/Column.tsx index 872b2cf..9945d06 100644 --- a/src/components/charts/Column.tsx +++ b/src/components/charts/Column.tsx @@ -1,6 +1,7 @@ import { ChartOptions, Scriptable, ScriptableContext } from 'chart.js' import React, { useState, useEffect } from 'react' -import { makeDateSorter } from '../Table' + +import { makeDateSorter } from '@components/Table' import { ChartTimeBase, ChartTimeData, @@ -21,7 +22,8 @@ export type ColumnLineConfig = { dash?: Array borderColor?: string backgroundColor?: string - borderWidth?: Scriptable> + borderWidth?: Scriptable> + showDatalabels?: boolean fill?: string } export type ColumnPostParsing = (data: ChartTimeDataParams) => void @@ -44,7 +46,7 @@ const chartPluginsOptions: ChartOptions = { backgroundColor: 'transparent', borderRadius: 4, color: '#000B', - display: context => (context.dataset.label === 'wellDepth') && 'auto', + display: context => !!context.dataset.label?.endsWith(' ') && 'auto', formatter: value => `${value.y.toLocaleTimeString()} ${value.label.toPrecision(4)}`, padding: 6, align: 'left', @@ -67,14 +69,14 @@ export const GetOrCreateDatasetByLineConfig = (data: ChartTimeData, lineConfig: ?? GetRandomColor() dataset = { - label: lineConfig.label, + label: lineConfig.label?.trimEnd() + (lineConfig.showDatalabels ? ' ' : ''), 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') + fill: lineConfig.fill ?? (lineConfig.isShape ? 'shape' : 'none'), } data.datasets.push(dataset) diff --git a/src/pages/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/TelemetryView/ActiveMessagesOnline.jsx index 127f88d..ec888ea 100644 --- a/src/pages/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/TelemetryView/ActiveMessagesOnline.jsx @@ -1,5 +1,5 @@ import { Table } from 'antd' -import { useState, useEffect } from 'react' +import { useState, useEffect, useCallback, memo } from 'react' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' @@ -10,14 +10,14 @@ import { columns } from '@pages/Messages' import '@styles/message.css' -export const ActiveMessagesOnline = ({ idWell }) => { +export const ActiveMessagesOnline = memo(({ idWell }) => { const [messages, setMessages] = useState([]) const [loader, setLoader] = useState(false) - const handleReceiveMessages = (messages) => { + const handleReceiveMessages = useCallback((messages) => { if (messages) setMessages(messages.items.splice(0, 4)) - } + }, []) useEffect(() => { invokeWebApiWrapperAsync( @@ -30,7 +30,7 @@ export const ActiveMessagesOnline = ({ idWell }) => { 'Получение списка сообщений' ) return Subscribe('hubs/telemetry','ReceiveMessages', `well_${idWell}`, handleReceiveMessages) - }, [idWell]) + }, [idWell, handleReceiveMessages]) return ( @@ -46,6 +46,6 @@ export const ActiveMessagesOnline = ({ idWell }) => { /> ) -} +}) export default ActiveMessagesOnline diff --git a/src/pages/TelemetryView/ChartTimeOnlineFooter.jsx b/src/pages/TelemetryView/ChartTimeOnlineFooter.jsx index 253a384..af7d928 100644 --- a/src/pages/TelemetryView/ChartTimeOnlineFooter.jsx +++ b/src/pages/TelemetryView/ChartTimeOnlineFooter.jsx @@ -1,9 +1,10 @@ +import { memo } from 'react' import { Popover } from 'antd' import { ControlOutlined } from '@ant-design/icons' import { ValueDisplay } from '@components/Display' -export const ChartTimeOnlineFooter = ({ data, lineGroup }) => { +export const ChartTimeOnlineFooter = memo(({ data, lineGroup }) => { const getFooterData = (name) => { const dataIdx = data && lineGroup?.find(line => line?.footer === name)?.xAccessorName return () @@ -39,4 +40,6 @@ export const ChartTimeOnlineFooter = ({ data, lineGroup }) => { ) -} +}) + +export default ChartTimeOnlineFooter diff --git a/src/pages/TelemetryView/MonitoringColumn.jsx b/src/pages/TelemetryView/MonitoringColumn.jsx index 9698527..01c7504 100644 --- a/src/pages/TelemetryView/MonitoringColumn.jsx +++ b/src/pages/TelemetryView/MonitoringColumn.jsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { memo, useCallback, useEffect, useState } from 'react' import { Grid, GridItem } from '@components/Grid' import { makeDateSorter } from '@components/Table' @@ -9,7 +9,7 @@ import { ChartTimeOnlineFooter } from './ChartTimeOnlineFooter' const GetLimitShape = (flowChartData, points, accessor) => { const min = [], max = [] - for (let point of points) { + for (const point of points) { const program = flowChartData.find(v => v.depthStart < point.depth && point.depth < v.depthEnd) if (!program) continue @@ -29,7 +29,9 @@ const RemoveSimilar = (input, accessor) => { return data } -export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, pointCount = 2048, additionalLabels }) => { +const addPointData = (point) => ({ depth: point.wellDepth }) + +export const MonitoringColumn = memo(({ lineGroup, data, flowChartData, interval, showBorder, style, headerHeight, pointCount = 2048, additionalLabels }) => { const [dataStore, setDataStore] = useState([]) const [lineGroupWithoutShapes, setLineGroupWithoutShapes] = useState([]) const dataLast = data?.[data.length - 1] @@ -41,9 +43,7 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho value: dataLast?.[line.xAccessorName] })) - const addPointData = (point) => ({ depth: point.wellDepth }) - - const postParsing = (data) => { + const postParsing = useCallback((data) => { lineGroupWithoutShapes.forEach(lineCfg => { const lineDataSet = GetOrCreateDatasetByLineConfig(data.data, lineCfg) @@ -54,7 +54,7 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho }) } }) - } + }, [lineGroupWithoutShapes, flowChartData, lineGroup]) useEffect(() => { setDataStore(prevData => { @@ -119,6 +119,6 @@ export const MonitoringColumn = ({ lineGroup, data, flowChartData, interval, sho ) -} +}) export default MonitoringColumn diff --git a/src/pages/TelemetryView/index.jsx b/src/pages/TelemetryView/index.jsx index 2ec2564..b998289 100644 --- a/src/pages/TelemetryView/index.jsx +++ b/src/pages/TelemetryView/index.jsx @@ -1,5 +1,5 @@ import { Select } from 'antd' -import { useState, useEffect } from 'react' +import { useState, useEffect, useCallback } from 'react' import { DrillFlowChartService, @@ -49,7 +49,8 @@ const blockHeightGroup = [ yAccessorName: 'date', color: '#333', showLine: false, - xConstValue: 30, + showDatalabels: true, + xConstValue: 50, dash }, { label: 'Расход', @@ -310,19 +311,15 @@ export default function TelemetryView({ idWell }) { const [flowChartData, setFlowChartData] = useState([]) const [rop, setRop] = useState(null) - const handleDataSaub = (data) => { + const handleDataSaub = useCallback((data) => { if (data) { const dataSaub = normalizeData(data) dataSaub.sort(makeDateSorter('date')) setDataSaub(dataSaub) } - } + }, []) - const handleDataSpin = (data) => { - if (data) { - setDataSpin(data) - } - } + const handleDataSpin = useCallback((data) => data && setDataSpin(data), []) useEffect(() => { const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) @@ -344,7 +341,7 @@ export default function TelemetryView({ idWell }) { unsubscribeSaub() unsubscribeSpin() } - }, [idWell, chartInterval]) + }, [idWell, chartInterval, handleDataSpin, handleDataSaub]) useEffect(() => invokeWebApiWrapperAsync( async () => { @@ -358,18 +355,16 @@ export default function TelemetryView({ idWell }) { 'Получение данных по скважине' ), [idWell]) - const onStatusChanged = (value) => { - invokeWebApiWrapperAsync( - async () => { - const well = { ...wellData, idState: value } - await WellService.updateWell(idWell, well) - setWellData(well) - }, - setShowLoader, - `Не удалось задать состояние скважины "${idWell}"`, - 'Задание состояния скважины' - ) - } + const onStatusChanged = useCallback((value) => invokeWebApiWrapperAsync( + async () => { + const well = { ...wellData, idState: value } + await WellService.updateWell(idWell, well) + setWellData(well) + }, + setShowLoader, + `Не удалось задать состояние скважины "${idWell}"`, + 'Задание состояния скважины' + ), [idWell, wellData]) const columnAdditionalLabels = { 1: rop && [