diff --git a/src/pages/Telemetry/Archive/ArchiveColumn.jsx b/src/pages/Telemetry/Archive/ArchiveColumn.jsx deleted file mode 100755 index 6f7ebfb..0000000 --- a/src/pages/Telemetry/Archive/ArchiveColumn.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { memo, useMemo } from 'react' - -import { Grid, GridItem } from '@components/Grid' -import { Column } from '@components/charts/Column' - -export const ArchiveColumn = memo(({ lineGroup, data, interval, style, headerHeight, yStart }) => { - const lgws = useMemo(() => lineGroup.filter(cfg => !cfg.isShape), [lineGroup]) - const pv = useMemo(() => lgws.filter(line => line.showLabels).map(line => ({ - color: line.color, - label: line.label - })), [lgws]) - - return ( -
- - {pv?.map((v, idx) => ( - {v.label} - ))} - - -
- ) -}) - -export default ArchiveColumn diff --git a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx b/src/pages/Telemetry/Archive/ArchiveDisplay.jsx deleted file mode 100755 index c3310ba..0000000 --- a/src/pages/Telemetry/Archive/ArchiveDisplay.jsx +++ /dev/null @@ -1,66 +0,0 @@ -import { memo, useMemo } from 'react' - -import { Grid, GridItem } from '@components/Grid' - -import { paramsGroups } from '../TelemetryView' -import { ArchiveColumn } from './ArchiveColumn' - -const interpolationSearch = (data, begin, end, accessor) => { - const fy = (i) => new Date(data[i]?.[accessor] ?? 0) - const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b))) - const findIdx = (val, startIdx, c) => { - let x = startIdx - let endIdx = data.length - 1 - if(val < fy(startIdx)) - return startIdx - if(val > fy(endIdx)) - return endIdx - for(let i = 0; i < c; i++){ - x = fx(val, startIdx, endIdx) - if(fy(x) < val) - startIdx = x - else - endIdx = x - if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx))) - return x - } - return x - } - let x0 = findIdx(begin, 0, 5) - let x1 = findIdx(end, x0, 3) - return { start: x0, end: x1, count: x1 - x0 } -} - -export const cutData = (data, beginDate, endDate) => { - if (data?.length > 0) { - let { start, end } = interpolationSearch(data, beginDate, endDate, 'date') - if (start > 0) start-- - if (end + 1 < end.length) end++ - return data.slice(start, end) - } - return data -} - -export const ArchiveDisplay = memo(({data, startDate, interval, onWheel}) => { - const endDate = useMemo(() => new Date(+startDate + interval), [startDate, interval]) - const chartData = useMemo(() => cutData(data, startDate, endDate), [data, startDate, endDate]) - - return ( - - {paramsGroups.map((group, index) => ( - - - - ))} - - ) -}) - -export default ArchiveDisplay diff --git a/src/pages/Telemetry/Archive/index.jsx b/src/pages/Telemetry/Archive/index.jsx index 909a480..4608520 100755 --- a/src/pages/Telemetry/Archive/index.jsx +++ b/src/pages/Telemetry/Archive/index.jsx @@ -1,24 +1,30 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import { useState, useEffect, memo, useCallback } from 'react' +import { useState, useEffect, memo, useCallback, useMemo } from 'react' import { useSearchParams } from 'react-router-dom' import { useIdWell } from '@asb/context' import { Flex } from '@components/Grid' +import { D3MonitoringCharts } from '@components/d3' import { CopyUrlButton } from '@components/CopyUrl' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { DatePickerWrapper, makeDateSorter } from '@components/Table' import { PeriodPicker, defaultPeriod } from '@components/selectors/PeriodPicker' -import { range, wrapPrivateComponent } from '@utils' +import { formatDate, range, wrapPrivateComponent } from '@utils' import { TelemetryDataSaubService } from '@api' -import { normalizeData } from '../TelemetryView' -import { ArchiveDisplay, cutData } from './ArchiveDisplay' +import { chartGroups, normalizeData } from '../TelemetryView' +import { Select } from 'antd' const DATA_COUNT = 2048 // Колличество точек на подгрузку графика const ADDITIVE_PAGES = 2 // Дополнительные данные для графиков const LOADING_TRIGGER = 0.5 -const WHEEL_SENSITIVITY = 1 / 530 + +const scrollOptions = [ + { label: '10%', value: 0.1 }, + { label: '15%', value: 0.15 }, + { label: '25%', value: 0.25 }, +] const getLoadingInterval = (loaded, startDate, interval) => { // Если данные загружены и дата не заходит за тригер дозагрузка не требуется @@ -58,6 +64,42 @@ const getLoadingInterval = (loaded, startDate, interval) => { } } +const interpolationSearch = (data, begin, end, accessor) => { + const fy = (i) => new Date(data[i]?.[accessor] ?? 0) + const fx = (y, b, e) => Math.round(b + (y - fy(b)) * (e - b) / (fy(e) - fy(b))) + const findIdx = (val, startIdx, c) => { + let x = startIdx + let endIdx = data.length - 1 + if(val < fy(startIdx)) + return startIdx + if(val > fy(endIdx)) + return endIdx + for(let i = 0; i < c; i++){ + x = fx(val, startIdx, endIdx) + if(fy(x) < val) + startIdx = x + else + endIdx = x + if ((startIdx === endIdx)||(fy(startIdx) === fy(endIdx))) + return x + } + return x + } + let x0 = findIdx(begin, 0, 5) + let x1 = findIdx(end, x0, 3) + return { start: x0, end: x1, count: x1 - x0 } +} + +export const cutData = (data, beginDate, endDate) => { + if (data?.length > 0) { + let { start, end } = interpolationSearch(data, beginDate, endDate, 'date') + if (start > 0) start-- + if (end + 1 < end.length) end++ + return data.slice(start, end) + } + return data +} + const Archive = memo(() => { const [dataSaub, setDataSaub] = useState([]) const [dateLimit, setDateLimit] = useState({ from: 0, to: new Date() }) @@ -70,20 +112,21 @@ const Archive = memo(() => { const getInitialRange = useCallback(() => parseInt(search.get('range') ?? defaultPeriod) * 1000, [search]) const getInitialDate = useCallback(() => new Date(search.get('start') ?? (Date.now() - chartInterval)), [search]) + const [scrollPercent, setScrollPercent] = useState(0.15) const [chartInterval, setChartInterval] = useState(getInitialRange) const [startDate, setStartDate] = useState(getInitialDate) const onGraphWheel = useCallback((e) => { if (loaded && dateLimit.from && dateLimit.to) { setStartDate((prevStartDate) => { - const offset = e.deltaY * chartInterval * WHEEL_SENSITIVITY + const offset = e.deltaY / 100 * chartInterval * scrollPercent const nextStartDate = +prevStartDate + offset const firstPossibleDate = Math.max(loaded.start, dateLimit.from) const lastPossibleDate = Math.min(dateLimit.to, (loaded.end ?? Date.now())) - chartInterval return new Date(Math.max(firstPossibleDate, Math.min(nextStartDate, lastPossibleDate))) }) } - }, [loaded, dateLimit, chartInterval]) + }, [loaded, dateLimit, chartInterval, scrollPercent]) const isDateDisabled = useCallback((date) => { if (!date) return false @@ -171,6 +214,9 @@ const Archive = memo(() => { setDataSaub([]) }, []) + const domain = useMemo(() => ({ min: startDate, max: new Date(+startDate + chartInterval)}), [startDate, chartInterval]) + const chartData = useMemo(() => cutData(dataSaub, domain.min, domain.max), [dataSaub, domain]) + return ( <> @@ -187,13 +233,23 @@ const Archive = memo(() => { Период:  +
+ Прокрутка:  +