diff --git a/src/pages/Telemetry/Messages.jsx b/src/pages/Telemetry/Messages.jsx index 824e38d..bc845d4 100755 --- a/src/pages/Telemetry/Messages.jsx +++ b/src/pages/Telemetry/Messages.jsx @@ -11,6 +11,7 @@ import { makeColumn, makeDateColumn, makeNumericColumn, makeNumericSorter, makeT import { wrapPrivateComponent } from '@utils' import { MessageService } from '@api' +import '@styles/filter.less' import '@styles/message.less' const pageSize = 26 diff --git a/src/pages/Telemetry/OperationTime/index.jsx b/src/pages/Telemetry/OperationTime/index.jsx new file mode 100644 index 0000000..9351aae --- /dev/null +++ b/src/pages/Telemetry/OperationTime/index.jsx @@ -0,0 +1,128 @@ +import { memo, useEffect, useMemo, useState } from 'react' +import { Select } from 'antd' +import moment from 'moment' + +import { useWell } from '@asb/context' +import LoaderPortal from '@components/LoaderPortal' +import { invokeWebApiWrapperAsync } from '@components/factory' +import D3HorizontalPercentChart from '@components/d3/D3HorizontalPercentChart' +import { DateRangeWrapper, makeColumn, makeNumericColumn, makeNumericRender, makeTextColumn, Table } from '@components/Table' +import { arrayOrDefault, range, wrapPrivateComponent } from '@utils' +import { SubsystemOperationTimeService } from '@api' + +import '@styles/filter.less' +import '@styles/operation_time.less' + +const subsystemColors = [ + '#1abc9c', '#16a085', '#2ecc71', '#27ae60', + '#3498db', '#2980b9', '#9b59b6', '#8e44ad', + '#34495e', '#2c3e50', '#f1c40f', '#f39c12', + '#e67e22', '#d35400', '#e74c3c', '#c0392b', + '#ecf0f1', '#bdc3c7', '#95a5a6', '#7f8c8d', +] + +const tableColumns = [ + makeColumn('Цвет', 'color', { width: 50, render: (backgroundColor) => ( +
+ )}), + makeTextColumn('Подсистема', 'subsystemName'), + makeNumericColumn('Использование, %', 'kUsage', undefined, undefined, val => (+val * 100).toFixed(2)), + makeNumericColumn('Проходка, м', 'sumDepthInterval'), + makeNumericColumn('Время работы, ч', 'usedTimeHours'), + makeNumericColumn('Кол-во запусков', 'operationCount', undefined, undefined, makeNumericRender(0)), +] + +// Выбор доступен только до текущей даты +const disabledDates = (current) => current && moment(current).isAfter(moment(), 'day', '[]') +// Выбор доступен только до текущего времени +const disabledTimes = (date) => ({ + disabledHours: () => range(24).filter(h => date && moment(date).hours(h).isAfter(moment(), 'hour', '[]')), + disabledMinutes: () => range(60).filter(m => date && moment(date).minutes(m).isAfter(moment(), 'minute', '[]')), + disabledSeconds: () => range(60).filter(s => date && moment(date).seconds(s).isBetween(moment(), 'second', '[]')) +}) + +export const OperationTime = memo(() => { + const [showLoader, setShowLoader] = useState(false) + const [data, setData] = useState([]) + const [selected, setSelected] = useState([]) + const [dateRange, setDateRange] = useState([]) + const [well] = useWell() + + // Создаём массив пунктов для селектора подсистем + const typeOptions = useMemo(() => data.map((d) => ({ label: d.subsystemName, value: d.idSubsystem })), [data]) + // Фильтруем данные по выбранным подсистемам + const selectedData = useMemo(() => data.filter((d) => selected.includes(d.idSubsystem)), [selected, data]) + // Подготавливаем данные для отображения на графике + const chartData = useMemo(() => selectedData.map((d) => ({ + name: d.subsystemName, + percent: d.kUsage * 100, + color: d.color, + })), [selectedData]) + + useEffect(() => { + invokeWebApiWrapperAsync( + async () => { + if (!well.id) return + + // Ограничение задаётся только если выбраны обе даты + const startDate = dateRange[1] ? dateRange[0]?.toISOString() : undefined + const endDate = dateRange[1]?.toISOString() + + const data = await SubsystemOperationTimeService.getStat(well.id, undefined, startDate, endDate) + // Выбираем цвета для подсистем (если цветов не хватает начинаем сначала) + const coloredData = arrayOrDefault(data).map((d, i) => ({ ...d, color: subsystemColors[i % subsystemColors.length] })) + + setData(coloredData) + setSelected(data.map((d) => d.idSubsystem)) // По-умолчанию выбираем все подсистемы + }, + setShowLoader, + `Не удалось загрузить данные`, + { actionName: 'Получение данных по скважине', well } + ) + }, [dateRange, well]) + + return ( + +
+

Фильтр подсистем

+
+ d.subsystemName)} - onChange={selectChange} - style={{ width: '100%' }} - > - {childrenData} - - - - setDateRange(dateRange)} - value={[dateRange[0], dateRange[1]]} - /> - - -
- ({name: item.subsystemName, percent: item.kUsage * 100}))} - colors={subsystemColors} - width={'100%'} - height={'50vh'} - /> -
- ({...d, color: subsystemColors[i]}))} - scroll={{ y: '25vh', x: true }} - pagination={false} - /> - - ) -} - -export default wrapPrivateComponent(OperationTime, { - requirements: [], - title: 'Наработка', - route: 'operation_time', -}) \ No newline at end of file diff --git a/src/styles/d3.less b/src/styles/d3.less index 2e48ca4..90db40d 100644 --- a/src/styles/d3.less +++ b/src/styles/d3.less @@ -116,9 +116,9 @@ } } -.grid-line line { +.grid-line:not(:first-of-type):not(:last-of-type) line { stroke: #ddd; - stroke-dasharray: 4 + stroke-dasharray: 4; } @media (max-width: 1800px) { diff --git a/src/styles/filter.less b/src/styles/filter.less new file mode 100644 index 0000000..16618cc --- /dev/null +++ b/src/styles/filter.less @@ -0,0 +1,22 @@ +.filter-group { + margin: 0 0 5px 0; + + & .head { + margin: 5px auto; + align-items: center; + } + + & .body { + width: 100%; + display: flex; + gap: 5px; + + & .type-filter { + width: 25%; + } + + & .filter-selector { + flex: 1; + } + } +} diff --git a/src/styles/message.less b/src/styles/message.less index 513d06f..be78867 100644 --- a/src/styles/message.less +++ b/src/styles/message.less @@ -39,29 +39,6 @@ background: #505060; } -.filter-group { - margin: 0 0 5px 0; - - & .head { - margin: 5px auto; - align-items: center; - } - - & .body { - width: 100%; - display: flex; - gap: 5px; - - & .type-filter { - width: 25%; - } - - & .filter-selector { - flex: 1; - } - } -} - td.ant-table-column-sort { color: black; background-color: #fafafa; diff --git a/src/styles/operation_time.less b/src/styles/operation_time.less new file mode 100644 index 0000000..d35e54f --- /dev/null +++ b/src/styles/operation_time.less @@ -0,0 +1,3 @@ +.table_color { + padding: 5px 0; +}