diff --git a/src/components/Table/index.ts b/src/components/Table/index.ts index f080b59..b252ae4 100644 --- a/src/components/Table/index.ts +++ b/src/components/Table/index.ts @@ -74,17 +74,6 @@ export const makeColumnsPlanFact = (title:string|any, key:string|string[], colum } } -const maxPrefix = "isMax" -const minPrefix = "isMin" - -export const makeFilterMinMaxFunction = (key: string | number) => (filterValue: string | number, - dataItem: any) => - filterValue === "max" - ? dataItem[maxPrefix + key] - : filterValue === "min" - ? dataItem[minPrefix + key] - : false - export const makeFilterTextMatch = (key: string | number) => (filterValue: string | number, dataItem: any) => dataItem[key] === filterValue @@ -118,56 +107,22 @@ export const makeTextColumn = (title: any, dataIndex: any, filters: any, sorter: ...other }) -export const makeNumericColumn = (title: any, dataIndex: any, filters: any, width: string) => ({ +export const makeNumericColumn = (title: any, dataIndex: any, filters: any, filterDelegate: (key: string | number) => any, width: string) => ({ title: title, dataIndex: dataIndex, key: dataIndex, filters: filters, - onFilter: makeFilterMinMaxFunction(dataIndex), + onFilter: filterDelegate ? filterDelegate(dataIndex) : null, sorter: makeNumericSorter(dataIndex), width: width }) -export const makeNumericColumnPlanFact = (title: any, dataIndex: any, filters: any, width: string) => +export const makeNumericColumnPlanFact = (title: any, dataIndex: any, filters: any, filterDelegate: (key: string | number) => any, width: string) => makeGroupColumn( title, [ - makeNumericColumn('п', dataIndex + 'Plan', filters, width), - makeNumericColumn('ф', dataIndex + 'Fact', filters, width), + makeNumericColumn('п', dataIndex + 'Plan', filters, filterDelegate, width), + makeNumericColumn('ф', dataIndex + 'Fact', filters, filterDelegate, width), ]) -export const calcAndUpdateStats = (data: any, keys: any) => { - let mins: any = {} - let maxs: any = {} - - keys.forEach((key: any) => { - maxs[key] = Number.MIN_VALUE - mins[key] = Number.MAX_VALUE - }) - - data.forEach((item: any) => { - keys.forEach((key: any) => { - if (mins[key] > item[key]) mins[key] = item[key] - - if (maxs[key] < item[key]) maxs[key] = item[key] - }) - }) - - for (let i = 0; i < data.length; i++) { - keys.forEach((key: any) => { - data[i][maxPrefix + key] = data[i][key] === maxs[key] - data[i][minPrefix + key] = data[i][key] === mins[key] - }) - } -} - -export const calcAndUpdateStatsBySections = (data: any, keys: any) => { - const sectionTypes = new Set() - data.forEach((item: any) => sectionTypes.add(item.sectionType)) - sectionTypes.forEach(sectionType => { - const filteredBySectionData = data.filter((item: any) => item.sectionType === sectionType) - calcAndUpdateStats(filteredBySectionData, keys) - }) -} - type PaginationContainer = { skip?: number; take?: number; diff --git a/src/components/charts/DepthToDay.jsx b/src/components/charts/ChartDepthToDay.jsx similarity index 96% rename from src/components/charts/DepthToDay.jsx rename to src/components/charts/ChartDepthToDay.jsx index 694df1a..18b7217 100644 --- a/src/components/charts/DepthToDay.jsx +++ b/src/components/charts/ChartDepthToDay.jsx @@ -68,8 +68,8 @@ const defaultOptions = { reverse:true, display: true, title: { - display: true, - text: 'Value' + display: false, + text: '' }, } }, @@ -111,7 +111,7 @@ const makeDataset = (data, label, color, width=1.5, dash) => ({ borderDash: dash, }) -export default function DepthToDay({dataPlan, dataFact, dataForecast}) { +export default function ChartDepthToDay({dataPlan, dataFact, dataForecast}) { const chartRef = useRef(null) const [chart, setChart] = useState() diff --git a/src/pages/Cluster/ClusterSections.jsx b/src/pages/Cluster/ClusterSections.jsx index 194a774..05a2fd9 100644 --- a/src/pages/Cluster/ClusterSections.jsx +++ b/src/pages/Cluster/ClusterSections.jsx @@ -4,9 +4,10 @@ import { LineChartOutlined, ProfileOutlined } from "@ant-design/icons"; import { useState, useEffect } from "react"; import { makeTextColumn, - makeNumericColumnPlanFact, - calcAndUpdateStatsBySections, + makeNumericColumnPlanFact } from "../../components/Table"; +import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction } from "./functions"; + const filtersMinMax = [ { @@ -62,29 +63,33 @@ const ModalWindowButton = ({ const columns = [ makeTextColumn("скв №", "caption"), makeTextColumn("Секция", "sectionType", filtersSectionsType), - makeNumericColumnPlanFact("Глубина", "sectionWellDepth", filtersMinMax), + makeNumericColumnPlanFact("Глубина", "sectionWellDepth", filtersMinMax, makeFilterMinMaxFunction), makeNumericColumnPlanFact( "Продолжительность", "sectionBuildDays", - filtersMinMax + filtersMinMax, + makeFilterMinMaxFunction ), //Цикл строительства - makeNumericColumnPlanFact("МСП", "sectionRateOfPenetration", filtersMinMax), + makeNumericColumnPlanFact("МСП", "sectionRateOfPenetration", filtersMinMax, makeFilterMinMaxFunction), makeNumericColumnPlanFact( "Рейсовая скорость", "sectionRouteSpeed", - filtersMinMax + filtersMinMax, + makeFilterMinMaxFunction ), - makeNumericColumnPlanFact("Спуск КНБК", "sectionBhaDownSpeed", filtersMinMax), //Скорость спуска КНБК - makeNumericColumnPlanFact("Подъем КНБК", "sectionBhaUpSpeed", filtersMinMax), //Скорость подъема КНБК + makeNumericColumnPlanFact("Спуск КНБК", "sectionBhaDownSpeed", filtersMinMax, makeFilterMinMaxFunction), //Скорость спуска КНБК + makeNumericColumnPlanFact("Подъем КНБК", "sectionBhaUpSpeed", filtersMinMax, makeFilterMinMaxFunction), //Скорость подъема КНБК makeNumericColumnPlanFact( "Скорость спуска ОК", "sectionCasingDownSpeed", - filtersMinMax + filtersMinMax, + makeFilterMinMaxFunction ), makeNumericColumnPlanFact( "НПВ, сут", "nonProductiveTime", filtersMinMax, + makeFilterMinMaxFunction, "70px" ), { @@ -143,26 +148,22 @@ export default function ClusterSections({ clusterData }) { useEffect(() => { let rows = []; - clusterData.statsWells?.forEach((el) => { - el.sections.forEach((section) => { + clusterData.statsWells?.forEach((well) => { + well.sections.forEach((section) => { let row = { - key: el.caption + section.id, - id: el.caption + section.id, - caption: el.caption, + key: well.caption + section.id, + id: well.caption + section.id, + caption: well.caption, sectionType: section.caption, sectionWellDepthPlan: section.plan.wellDepthEnd, sectionWellDepthFact: section.fact.wellDepthEnd, sectionBuildDaysPlan: ( - Math.abs( - new Date(section.plan.start) - new Date(section.plan.end) - ) / - (1000 * 60 * 60 * 24) + (new Date(section.plan.end) - new Date(section.plan.start)) / + (1000 * 60 * 60 * 24) ).toFixed(2), sectionBuildDaysFact: ( - Math.abs( - new Date(section.fact.start) - new Date(section.fact.end) - ) / - (1000 * 60 * 60 * 24) + (new Date(section.fact.end) - new Date(section.fact.start)) / + (1000 * 60 * 60 * 24) ).toFixed(2), sectionRateOfPenetrationPlan: section.plan.rop.toFixed(2), sectionRateOfPenetrationFact: section.fact.rop.toFixed(2), @@ -176,7 +177,7 @@ export default function ClusterSections({ clusterData }) { sectionCasingDownSpeedFact: section.fact.casingDownSpeed.toFixed(2), nonProductiveTimePlan: section.plan.nonProductiveHours.toFixed(2), nonProductiveTimeFact: section.fact.nonProductiveHours.toFixed(2), - companies: el.companies, + companies: well.companies, }; rows.push(row); diff --git a/src/pages/Cluster/ClusterWells.jsx b/src/pages/Cluster/ClusterWells.jsx index 088ebe5..dd54110 100644 --- a/src/pages/Cluster/ClusterWells.jsx +++ b/src/pages/Cluster/ClusterWells.jsx @@ -6,12 +6,12 @@ import { makeTextColumn, makeGroupColumn, makeNumericColumn, - makeNumericColumnPlanFact, - calcAndUpdateStatsBySections, + makeNumericColumnPlanFact } from "../../components/Table"; +import { calcAndUpdateStatsBySections, makeFilterMinMaxFunction } from "./functions"; import { invokeWebApiWrapperAsync } from '../../components/factory'; import { WellOperationStatService } from '../../services/api'; -import DepthToDay from '../../components/charts/DepthToDay'; +import ChartDepthToDay from '../../components/charts/ChartDepthToDay'; const filtersMinMax = [ { @@ -45,31 +45,33 @@ export default function ClusterWells({ clusterData }) { const [dataForecast, setDataForecast] = useState([]); useEffect(() => { - invokeWebApiWrapperAsync( - async () => { - const operations = await WellOperationStatService.getTvd(selectedWellId); - - const planData = operations.map(el => { - return {key: el.plan?.id, depth: el.plan?.wellDepth, date: el.plan?.startDate} - }).filter(el => el.key) - - setDataPlan(planData) - - const factData = operations.map(el => { - return {key: el.fact?.id, depth: el.fact?.wellDepth, date: el.fact?.startDate} - }).filter(el => el.key) - - setDataFact(factData) - - const predictData = operations.map(el => { - return {key: el.predict?.id, depth: el.predict?.wellDepth, date: el.predict?.startDate} - }).filter(el => el.key) - - setDataForecast(predictData) - }, - null, - `Не удалось загрузить операции по скважине "${selectedWellId}"`, - ); + if (selectedWellId > 0) { + invokeWebApiWrapperAsync( + async () => { + const operations = await WellOperationStatService.getTvd(selectedWellId); + + const planData = operations.map(el => { + return {key: el.plan?.id, depth: el.plan?.wellDepth, date: el.plan?.startDate} + }).filter(el => el.key) + + setDataPlan(planData) + + const factData = operations.map(el => { + return {key: el.fact?.id, depth: el.fact?.wellDepth, date: el.fact?.startDate} + }).filter(el => el.key) + + setDataFact(factData) + + const predictData = operations.map(el => { + return {key: el.predict?.id, depth: el.predict?.wellDepth, date: el.predict?.startDate} + }).filter(el => el.key) + + setDataForecast(predictData) + }, + null, + `Не удалось загрузить операции по скважине "${selectedWellId}"`, + ); + } }, [selectedWellId]); const closeModal = () => { @@ -89,33 +91,29 @@ export default function ClusterWells({ clusterData }) { ]); useEffect(() => { - let tableData = clusterData.statsWells?.map((el) => { + let tableData = clusterData.statsWells?.map((well) => { return { - key: el.id, - id: el.id, - caption: el.caption, - wellType: el.wellType, - factStart: new Date(el.total.fact.start).toLocaleString(), - factEnd: new Date(el.total.fact.end).toLocaleString(), + key: well.id, + id: well.id, + caption: well.caption, + wellType: well.wellType, + factStart: new Date(well.total.fact.start).toLocaleString(), + factEnd: new Date(well.total.fact.end).toLocaleString(), periodPlan: ( - Math.abs( - new Date(el.total.plan.start) - new Date(el.total.plan.end) - ) / - (1000 * 60 * 60 * 24) + (new Date(well.total.plan.end) - new Date(well.total.plan.start)) / + (1000 * 60 * 60 * 24) ).toFixed(2), periodFact: ( - Math.abs( - new Date(el.total.fact.start) - new Date(el.total.fact.end) - ) / - (1000 * 60 * 60 * 24) + (new Date(well.total.fact.end) - new Date(well.total.fact.start)) / + (1000 * 60 * 60 * 24) ).toFixed(2), - rateOfPenetrationPlan: el.total.plan.rop.toFixed(2), - rateOfPenetrationFact: el.total.fact.rop.toFixed(2), - routeSpeedPlan: el.total.plan.routeSpeed.toFixed(2), - routeSpeedFact: el.total.fact.routeSpeed.toFixed(2), - notProductiveTimePlan: el.total.plan.nonProductiveHours.toFixed(2), - notProductiveTimeFact: el.total.fact.nonProductiveHours.toFixed(2), - companies: el.companies, + rateOfPenetrationPlan: well.total.plan.rop.toFixed(2), + rateOfPenetrationFact: well.total.fact.rop.toFixed(2), + routeSpeedPlan: well.total.plan.routeSpeed.toFixed(2), + routeSpeedFact: well.total.fact.routeSpeed.toFixed(2), + notProductiveTimePlan: well.total.plan.nonProductiveHours.toFixed(2), + notProductiveTimeFact: well.total.fact.nonProductiveHours.toFixed(2), + companies: well.companies, }; }); @@ -131,10 +129,10 @@ export default function ClusterWells({ clusterData }) { makeNumericColumn("начало", "factStart"), makeNumericColumn("окончание", "factEnd"), ]), - makeNumericColumnPlanFact("Продолжительность", "period", filtersMinMax), - makeNumericColumnPlanFact("МСП", "rateOfPenetration", filtersMinMax), - makeNumericColumnPlanFact("Рейсовая скорость", "routeSpeed", filtersMinMax), - makeNumericColumnPlanFact("НПВ, сут", "notProductiveTime", filtersMinMax), + makeNumericColumnPlanFact("Продолжительность", "period", filtersMinMax, makeFilterMinMaxFunction), + makeNumericColumnPlanFact("МСП", "rateOfPenetration", filtersMinMax, makeFilterMinMaxFunction), + makeNumericColumnPlanFact("Рейсовая скорость", "routeSpeed", filtersMinMax, makeFilterMinMaxFunction), + makeNumericColumnPlanFact("НПВ, сут", "notProductiveTime", filtersMinMax, makeFilterMinMaxFunction), { title: "График глубина-день", render: (_, item) =>