CF2-56: Added TVD chart to 'Wells operations' tab

This commit is contained in:
KharchenkoVV 2021-08-27 17:11:30 +05:00
parent 2a6a53a1ce
commit 3247ef5cf7
11 changed files with 591 additions and 154 deletions

View File

@ -1,4 +1,4 @@
import { ChartDepthToDay } from './charts/ChartDepthToDay'
import { ChartDepthToDay } from './charts/ChartDepthToDayOldVersion'
import { notify } from "./factory"
import { useState, useEffect } from 'react'
import { TelemetryAnalyticsService } from "../services/api"

View File

@ -174,7 +174,7 @@ export const timeParamsByInterval = (intervalSec:number) :TimeParams => {
return {unit, stepSize}
}
export const ChartDepthToDayBase: React.FC<ChartTimeBaseProps> = ({options, dataParams}) => {
export const ChartDepthToDayBaseOldVersion: React.FC<ChartTimeBaseProps> = ({options, dataParams}) => {
const chartRef = useRef<HTMLCanvasElement>(null)
const [chart, setChart] = useState<any>()

View File

@ -1,8 +1,8 @@
import { useEffect, useState } from 'react'
import { ChartDepthToDayBase } from './ChartDepthToDayBase'
import { ChartDepthToDayBase } from './ChartDepthToDayBaseOldVersion'
import { CreateDataset } from './ChartTimeArchive'
export const ChartDepthToDay = ({data, lines}) => {
export const ChartDepthToDayOldVersion = ({data, lines}) => {
const [depthToDayDataParams, setDepthToDayDataParams] = useState({data: {datasets: []}})
useEffect(() => {

View File

@ -0,0 +1,147 @@
import {useEffect, useRef, useState} from 'react';
import {
Chart,
TimeScale,
LinearScale,
Legend,
LineController,
PointElement,
LineElement
} from 'chart.js'
import 'chartjs-adapter-moment';
import ChartDataLabels from 'chartjs-plugin-datalabels';
import zoomPlugin from 'chartjs-plugin-zoom';
Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin);
const defaultOptions = {
responsive: true,
aspectRatio: 2.6,
//maintainAspectRatio: false,
//animation: false,
// tooltips: {
// enabled: true,
// callbacks: {
// label(tooltipItem) {
// return tooltipItem.yLabel;
// }
// }
// },
//events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
interaction: {
intersect: false,
mode: 'index',
},
scales: {
x:{
display: true,
title: {
display: true
},
type: 'time',
time: {
unit: 'hour',
displayFormats: {
'hour': 'MM.DD'
}
},
grid:{
drawTicks: true,
},
ticks: {
//count:24,
stepSize:3,
major:{enabled:true,},
z: 1,
display : true,
textStrokeColor : "#fff",
textStrokeWidth : 2,
color:"#000",
}
},
y:{
type:'linear',
position:'top',
reverse:true,
display: true,
title: {
display: true,
text: 'Value'
},
}
},
parsing: {
xAxisKey: 'date',
yAxisKey: 'depth'
},
elements:{
point:{
radius:1.7,
//backgroundColor:'#aaa',
//pointStyle:'triangle',
},
},
plugins:{
legend:{
display: true,
},
datalabels: {
display: false,
},
tooltip: {
enabled: true,
callbacks: {
label(tooltipItem) {
return tooltipItem.yLabel;
}
}
},
}
}
const makeDataset = (data, label, color, width=1.5, dash) => ({
label: label,
data: data,
backgroundColor: color,
borderColor: color,
borderWidth: width,
borderDash: dash,
})
export default function DepthToDay({dataPlan, dataFact, dataForecast}) {
const chartRef = useRef(null)
const [chart, setChart] = useState()
useEffect(() => {
let data = {
datasets: [
makeDataset(dataFact, 'Факт', '#0A0'),
makeDataset(dataForecast, 'Прогноз', 'purple', 1, [7,3]),
makeDataset(dataPlan, 'План', '#C004', 4),
]
}
if((chartRef.current)&&(!chart)) {
let thisOptions = {}
Object.assign(thisOptions, defaultOptions)
let newChart = new Chart(chartRef.current, {
type: 'line',
plugins: [ChartDataLabels],
options: thisOptions,
data: data
})
setChart(newChart)
return () => chart?.destroy()
}else{
chart.data = data
chart.update()
}
}, [chart, dataPlan, dataFact, dataForecast])
return (<canvas ref={chartRef} />)
}

View File

@ -1,158 +1,50 @@
import { useEffect, useRef, useState } from "react";
import {
Chart,
TimeScale,
LinearScale,
Legend,
LineController,
PointElement,
LineElement,
} from "chart.js";
import "chartjs-adapter-moment";
import ChartDataLabels from "chartjs-plugin-datalabels";
import zoomPlugin from "chartjs-plugin-zoom";
import { invokeWebApiWrapperAsync } from "../../components/factory";
import LoaderPortal from "../../components/LoaderPortal";
//import { TvdService} from '../../services/api'
import DepthToDay from '../../components/charts/DepthToDay';
import { useState, useEffect } from 'react';
import { invokeWebApiWrapperAsync } from '../../components/factory';
import { WellOperationStatService } from '../../services/api';
Chart.register(
TimeScale,
LinearScale,
LineController,
LineElement,
PointElement,
Legend,
ChartDataLabels,
zoomPlugin
);
const defaultOptions = {
responsive: true,
aspectRatio: 2.35,
interaction: {
intersect: false,
mode: "index",
},
scales: {
x: {
display: true,
title: {
display: true,
},
type: "linear", // был 'time' + его конфиг ниже
grid: {
drawTicks: true,
},
ticks: {
//count:24,
stepSize: 3,
major: { enabled: true },
z: 1,
display: true,
textStrokeColor: "#fff",
textStrokeWidth: 2,
color: "#000",
},
},
y: {
type: "linear",
position: "top",
reverse: true,
display: true,
title: {
display: true,
text: "Value",
},
},
},
parsing: {
xAxisKey: "date",
yAxisKey: "depth",
},
elements: {
point: {
radius: 1.7,
},
},
plugins: {
legend: {
display: true,
},
datalabels: {
display: false,
},
tooltip: {
enabled: true,
callbacks: {
label(tooltipItem) {
return tooltipItem.yLabel;
},
},
},
},
};
const makeDataset = (data, label, color, width = 1.5, dash) => ({
label: label,
data: data,
backgroundColor: color,
borderColor: color,
borderWidth: width,
borderDash: dash,
});
export const Tvd = ({ idWell }) => {
const chartRef = useRef(null);
const [chart, setChart] = useState();
const [data, setData] = useState({ datasets: [] });
const [showLoader, setShowLoader] = useState(false);
useEffect(
() =>
invokeWebApiWrapperAsync(
async () => {
const dataPlan = [];
const dataFact = [];
const dataPredict = [];
const data = {
datasets: [
makeDataset(dataPlan, "План", "#C004", 4),
makeDataset(dataFact, "Факт", "#0A0"),
makeDataset(dataPredict, "Прогноз", "purple", 1, [7, 3]),
],
};
setData(data);
},
setShowLoader,
`Не удалось загрузить данные TVD по скважине ${idWell}`
),
[idWell]
);
export const TVD = ({ idWell }) => {
const [dataPlan, setDataPlan] = useState([]);
const [dataFact, setDataFact] = useState([]);
const [dataForecast, setDataForecast] = useState([]);
useEffect(() => {
if (chartRef.current && !chart) {
let thisOptions = {};
Object.assign(thisOptions, defaultOptions);
invokeWebApiWrapperAsync(
async () => {
const operations = await WellOperationStatService.getTvd(idWell);
let newChart = new Chart(chartRef.current, {
type: "line",
plugins: [ChartDataLabels],
options: thisOptions,
data: data,
});
setChart(newChart);
const planData = operations.map(el => {
return {key: el.plan?.id, depth: el.plan?.wellDepth, date: el.plan?.startDate}
}).filter(el => el.key)
return () => chart?.destroy();
} else {
chart.data = data;
chart.update();
}
}, [chart, data]);
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,
`Не удалось загрузить операции по скважине "${idWell}"`,
);
}, [idWell]);
return (
<LoaderPortal show={showLoader}>
<canvas ref={chartRef} />
</LoaderPortal>
<div className="container">
<div>
<h2 className={'mt-20px'}>График Глубина-день</h2>
<DepthToDay
idWell={idWell}
dataPlan={dataPlan}
dataFact={dataFact}
dataForecast={dataForecast} />
</div>
</div>
);
};

View File

@ -0,0 +1,366 @@
// import { useEffect, useRef, useState } from "react";
// import {
// Chart,
// TimeScale,
// LinearScale,
// Legend,
// LineController,
// PointElement,
// LineElement,
// } from "chart.js";
// import "chartjs-adapter-moment";
// import ChartDataLabels from "chartjs-plugin-datalabels";
// import zoomPlugin from "chartjs-plugin-zoom";
// import { invokeWebApiWrapperAsync } from "../../components/factory";
// import LoaderPortal from "../../components/LoaderPortal";
// import { WellOperationDtoPlanFactPredictBase } from '../../services/api'
// const defaultDataPlan = [
// {"depth": 0, "date": 0.00},
// {"depth": 0, "date": 0.00},
// {"depth": 50, "date": 0.08},
// {"depth": 50, "date": 0.10},
// {"depth": 50, "date": 0.15},
// {"depth": 50, "date": 0.17},
// {"depth": 50, "date": 0.19},
// {"depth": 50, "date": 0.23},
// {"depth": 50, "date": 0.25},
// {"depth": 50, "date": 0.38},
// {"depth": 50, "date": 0.40},
// {"depth": 50, "date": 0.44},
// {"depth": 50, "date": 0.52},
// {"depth": 50, "date": 0.94},
// {"depth": 50, "date": 1.06},
// {"depth": 50, "date": 1.08},
// {"depth": 50, "date": 1.13},
// {"depth": 50, "date": 1.19},
// {"depth": 1324, "date": 3.02},
// {"depth": 1324, "date": 3.10},
// {"depth": 1324, "date": 3.27},
// {"depth": 1324, "date": 3.35},
// {"depth": 1324, "date": 3.65},
// {"depth": 1324, "date": 3.73},
// {"depth": 1324, "date": 3.90},
// {"depth": 1324, "date": 3.98},
// {"depth": 1324, "date": 4.27},
// {"depth": 1324, "date": 4.31},
// {"depth": 1324, "date": 4.81},
// {"depth": 1324, "date": 4.90},
// {"depth": 1324, "date": 4.94},
// {"depth": 1324, "date": 5.10},
// {"depth": 1324, "date": 5.60},
// {"depth": 1324, "date": 6.10},
// {"depth": 1324, "date": 6.23},
// {"depth": 1324, "date": 6.40},
// {"depth": 1324, "date": 6.65},
// {"depth": 1324, "date": 6.69},
// {"depth": 1324, "date": 6.73},
// {"depth": 1324, "date": 6.81},
// {"depth": 1324, "date": 6.85},
// {"depth": 2600, "date": 8.85},
// {"depth": 2600, "date": 8.94},
// {"depth": 2600, "date": 9.15},
// {"depth": 2600, "date": 9.35},
// {"depth": 2600, "date": 9.52},
// {"depth": 2600, "date": 9.60},
// {"depth": 3283, "date": 11.85},
// {"depth": 3283, "date": 11.98},
// {"depth": 3283, "date": 12.35},
// {"depth": 3283, "date": 12.48},
// {"depth": 3283, "date": 12.60},
// {"depth": 3283, "date": 12.85},
// {"depth": 3283, "date": 13.10},
// {"depth": 3283, "date": 13.27},
// {"depth": 3283, "date": 13.35},
// {"depth": 3500, "date": 15.02},
// {"depth": 3500, "date": 15.15},
// {"depth": 3500, "date": 15.23},
// {"depth": 3500, "date": 15.31},
// {"depth": 3500, "date": 15.48},
// {"depth": 3500, "date": 15.56},
// {"depth": 3780, "date": 17.40},
// {"depth": 3780, "date": 17.52},
// {"depth": 3780, "date": 17.94},
// {"depth": 3780, "date": 18.44},
// {"depth": 3780, "date": 18.60},
// {"depth": 3780, "date": 18.69},
// {"depth": 4050, "date": 20.69},
// {"depth": 4050, "date": 20.81},
// {"depth": 4050, "date": 21.06},
// {"depth": 4050, "date": 21.23},
// {"depth": 4050, "date": 21.31},
// {"depth": 4050, "date": 23.31},
// {"depth": 4327, "date": 23.44},
// {"depth": 4327, "date": 23.60},
// {"depth": 4327, "date": 23.77},
// {"depth": 4327, "date": 23.90},
// {"depth": 4327, "date": 24.35},
// {"depth": 4327, "date": 24.48},
// {"depth": 4327, "date": 25.73},
// {"depth": 4327, "date": 25.85},
// {"depth": 4327, "date": 26.31},
// {"depth": 4327, "date": 26.48},
// {"depth": 4327, "date": 26.94},
// {"depth": 4327, "date": 27.06},
// {"depth": 4327, "date": 27.15},
// {"depth": 4327, "date": 27.48},
// {"depth": 4327, "date": 27.60},
// {"depth": 4327, "date": 27.67},
// {"depth": 4327, "date": 28.42},
// {"depth": 4327, "date": 28.63},
// {"depth": 4327, "date": 28.67},
// {"depth": 4327, "date": 28.88},
// {"depth": 4327, "date": 29.29},
// {"depth": 4327, "date": 29.29}
// ]
// const defaultDataFact = [
// { "depth": 0, "date": 0.00 },
// { "depth": 55, "date": 0.04 },
// { "depth": 55, "date": 0.08 },
// { "depth": 55, "date": 0.14 },
// { "depth": 55, "date": 0.26 },
// { "depth": 55, "date": 0.71 },
// { "depth": 55, "date": 0.81 },
// { "depth": 55, "date": 0.83 },
// { "depth": 264, "date": 1.06 },
// { "depth": 547, "date": 1.39 },
// { "depth": 547, "date": 1.43 },
// { "depth": 947, "date": 2.06 },
// { "depth": 1285, "date": 2.51 },
// { "depth": 1285, "date": 2.58 },
// { "depth": 1285, "date": 2.81 },
// { "depth": 1285, "date": 2.87 },
// { "depth": 1285, "date": 3.07 },
// { "depth": 1285, "date": 3.08 },
// { "depth": 1285, "date": 3.10 },
// { "depth": 1285, "date": 3.26 },
// { "depth": 1285, "date": 3.34 },
// { "depth": 1285, "date": 3.60 },
// { "depth": 1285, "date": 3.65 },
// { "depth": 1285, "date": 3.90 },
// { "depth": 1285, "date": 3.91 },
// { "depth": 1285, "date": 4.00 },
// { "depth": 1285, "date": 4.06 },
// { "depth": 1285, "date": 4.08 },
// { "depth": 1285, "date": 4.26 },
// { "depth": 1285, "date": 4.76 },
// { "depth": 1285, "date": 4.87 },
// { "depth": 1285, "date": 5.01 },
// { "depth": 1285, "date": 5.03 },
// { "depth": 1285, "date": 5.08 },
// { "depth": 1285, "date": 5.12 },
// { "depth": 1285, "date": 5.14 },
// { "depth": 1285, "date": 5.16 },
// { "depth": 1285, "date": 5.20 },
// { "depth": 1289, "date": 5.21 },
// { "depth": 1289, "date": 5.23 },
// { "depth": 1289, "date": 5.27 },
// { "depth": 1872, "date": 6.08 },
// { "depth": 2357, "date": 7.08 },
// { "depth": 2614, "date": 7.73 },
// { "depth": 2614, "date": 7.81 },
// { "depth": 2614, "date": 7.98 },
// { "depth": 2614, "date": 8.03 },
// { "depth": 2614, "date": 8.08 },
// { "depth": 2614, "date": 8.11 },
// { "depth": 2614, "date": 8.14 },
// { "depth": 2918, "date": 9.08 },
// {"depth": 3230, "date": 9.12},
// ]
// const defaultDataForecast = [
// {"depth": 3230, "date": 9.12},
// {"depth": 3283, "date": 9.12},
// {"depth": 3283, "date": 9.21},
// {"depth": 3283, "date": 9.58},
// {"depth": 3283, "date": 9.71},
// {"depth": 3283, "date": 9.83},
// {"depth": 3283, "date": 10.08},
// {"depth": 3283, "date": 10.33},
// {"depth": 3283, "date": 10.50},
// {"depth": 3283, "date": 10.58},
// {"depth": 3500, "date": 12.25},
// {"depth": 3500, "date": 12.38},
// {"depth": 3500, "date": 12.46},
// {"depth": 3500, "date": 12.33},
// {"depth": 3500, "date": 12.71},
// {"depth": 3500, "date": 12.79},
// {"depth": 3780, "date": 14.63},
// {"depth": 3780, "date": 14.75},
// {"depth": 3780, "date": 15.17},
// {"depth": 3780, "date": 15.67},
// {"depth": 3780, "date": 15.83},
// {"depth": 3780, "date": 15.92},
// {"depth": 4050, "date": 17.92},
// {"depth": 4050, "date": 18.04},
// {"depth": 4050, "date": 18.29},
// {"depth": 4050, "date": 18.46},
// {"depth": 4050, "date": 18.54},
// {"depth": 4050, "date": 20.54},
// {"depth": 4327, "date": 20.67},
// {"depth": 4327, "date": 20.83},
// {"depth": 4327, "date": 21.00},
// {"depth": 4327, "date": 21.13},
// {"depth": 4327, "date": 21.58},
// {"depth": 4327, "date": 21.71},
// {"depth": 4327, "date": 22.96},
// {"depth": 4327, "date": 23.08},
// {"depth": 4327, "date": 23.54},
// {"depth": 4327, "date": 23.71},
// {"depth": 4327, "date": 24.17},
// {"depth": 4327, "date": 24.29},
// {"depth": 4327, "date": 24.61},
// {"depth": 4327, "date": 24.71},
// {"depth": 4327, "date": 24.83},
// {"depth": 4327, "date": 24.90},
// {"depth": 4327, "date": 25.65},
// {"depth": 4327, "date": 25.86},
// {"depth": 4327, "date": 25.90},
// {"depth": 4327, "date": 26.11},
// {"depth": 4327, "date": 26.52},
// {"depth": 4327, "date": 26.52}
// ]
// Chart.register(
// TimeScale,
// LinearScale,
// LineController,
// LineElement,
// PointElement,
// Legend,
// ChartDataLabels,
// zoomPlugin
// );
// const defaultOptions = {
// responsive: true,
// aspectRatio: 2.35,
// interaction: {
// intersect: false,
// mode: "index",
// },
// scales: {
// x: {
// display: true,
// title: {
// display: true,
// },
// type: "linear", // был 'time' + его конфиг ниже
// grid: {
// drawTicks: true,
// },
// ticks: {
// //count:24,
// stepSize: 3,
// major: { enabled: true },
// z: 1,
// display: true,
// textStrokeColor: "#fff",
// textStrokeWidth: 2,
// color: "#000",
// },
// },
// y: {
// type: "linear",
// position: "top",
// reverse: true,
// display: true,
// title: {
// display: true,
// text: "Value",
// },
// },
// },
// parsing: {
// xAxisKey: "date",
// yAxisKey: "depth",
// },
// elements: {
// point: {
// radius: 1.7,
// },
// },
// plugins: {
// legend: {
// display: true,
// },
// datalabels: {
// display: false,
// },
// tooltip: {
// enabled: true,
// callbacks: {
// label(tooltipItem) {
// return tooltipItem.yLabel;
// },
// },
// },
// },
// };
// const makeDataset = (data, label, color, width = 1.5, dash) => ({
// label: label,
// data: data,
// backgroundColor: color,
// borderColor: color,
// borderWidth: width,
// borderDash: dash,
// });
// export const TvdOldVersion = ({ idWell }) => {
// const chartRef = useRef(null);
// const [chart, setChart] = useState();
// const [data, setData] = useState({ datasets: [] });
// const [showLoader, setShowLoader] = useState(false);
// useEffect(
// () =>
// invokeWebApiWrapperAsync(
// async () => {
// const dataPlan = [];
// const dataFact = [];
// const dataPredict = [];
// const data = {
// datasets: [
// makeDataset(dataPlan, "План", "#C004", 4),
// makeDataset(dataFact, "Факт", "#0A0"),
// makeDataset(dataPredict, "Прогноз", "purple", 1, [7, 3]),
// ],
// };
// setData(data);
// },
// setShowLoader,
// `Не удалось загрузить данные TVD по скважине ${idWell}`
// ),
// [idWell]
// );
// useEffect(() => {
// if (chartRef.current && !chart) {
// let thisOptions = {};
// Object.assign(thisOptions, defaultOptions);
// let newChart = new Chart(chartRef.current, {
// type: "line",
// plugins: [ChartDataLabels],
// options: thisOptions,
// data: data,
// });
// setChart(newChart);
// return () => chart?.destroy();
// } else {
// chart.data = data;
// chart.update();
// }
// }, [chart, data]);
// return (
// <LoaderPortal show={showLoader}>
// <canvas ref={chartRef} />
// </LoaderPortal>
// );
// };

View File

@ -3,7 +3,7 @@ import {Switch, Link, Route, Redirect, useParams} from "react-router-dom";
import { FolderOutlined } from "@ant-design/icons";
import { WellOperationsEditor } from './WellOperationsEditor'
import { WellSectionsStat } from './WellSectionsStat'
import { Tvd } from './Tvd'
import { TVD } from './TVD'
const { Content } = Layout
@ -34,7 +34,7 @@ export default function WellOperations({idWell}) {
<Content className="site-layout-background">
<Switch>
<Route path={`${rootPath}/tvd`}>
<Tvd idWell={idWell}/>
<TVD idWell={idWell}/>
</Route>
<Route path={`${rootPath}/sections`}>
<WellSectionsStat idWell={idWell}/>

View File

@ -36,6 +36,7 @@ export type { WellDto } from './models/WellDto';
export type { WellOperationCategoryDto } from './models/WellOperationCategoryDto';
export type { WellOperationDto } from './models/WellOperationDto';
export type { WellOperationDtoPaginationContainer } from './models/WellOperationDtoPaginationContainer';
export type { WellOperationDtoPlanFactPredictBase } from './models/WellOperationDtoPlanFactPredictBase';
export { AuthService } from './services/AuthService';
export { ClusterService } from './services/ClusterService';

View File

@ -0,0 +1,11 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { WellOperationDto } from './WellOperationDto';
export type WellOperationDtoPlanFactPredictBase = {
plan?: WellOperationDto;
fact?: WellOperationDto;
predict?: WellOperationDto;
}

View File

@ -3,6 +3,7 @@
/* eslint-disable */
import type { StatClusterDto } from '../models/StatClusterDto';
import type { StatWellDto } from '../models/StatWellDto';
import type { WellOperationDtoPlanFactPredictBase } from '../models/WellOperationDtoPlanFactPredictBase';
import { request as __request } from '../core/request';
export class WellOperationStatService {
@ -37,4 +38,19 @@ idWell: number,
return result.body;
}
/**
* @param idWell
* @returns WellOperationDtoPlanFactPredictBase Success
* @throws ApiError
*/
public static async getTvd(
idWell: number,
): Promise<Array<WellOperationDtoPlanFactPredictBase>> {
const result = await __request({
method: 'GET',
path: `/api/well/${idWell}/tvd`,
});
return result.body;
}
}

View File

@ -60,3 +60,7 @@ code {
color: #c32828;
}
.container{
width: 100%;
}