TVD переработан

* в getOperations добавлена обработка дня с начала бурения
* поле горизонтальной оси использует день с начала бурения
* позиция tooltip теперь определяется как 'nearest'
* частота вертикальных полос установлена в 3 дня
* тип вертикальной оси изменён на 'linear' с min 0
* код ChartTvD перенесён в Tvd
This commit is contained in:
Александр Сироткин 2022-01-12 23:51:39 +05:00
parent 702e994e64
commit b2a8189ed8
3 changed files with 125 additions and 151 deletions

View File

@ -13,7 +13,8 @@ export const getOperations = async (idWell) => {
const convert = wellOperationDto => ({
key: wellOperationDto?.id,
depth: wellOperationDto?.depthStart,
date: wellOperationDto?.dateStart
date: wellOperationDto?.dateStart,
day: wellOperationDto?.day,
})
const planData = ops

View File

@ -1,133 +0,0 @@
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,
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: {
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: false,
text: ''
},
}
},
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 ChartTvD({dataPlan, dataFact, dataPredict}) {
const chartRef = useRef(null)
const [chart, setChart] = useState()
useEffect(() => {
let data = {
datasets: [
makeDataset(dataFact, 'Факт', '#0A0'),
makeDataset(dataPredict, 'Прогноз', '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, dataPredict])
return (<canvas ref={chartRef} />)
}

View File

@ -1,43 +1,149 @@
import ChartTvD from './ChartTvD'
import { useState, useEffect } from 'react'
import { memo, useState, useRef, useEffect } from 'react'
import {
Chart,
TimeScale,
LinearScale,
Legend,
LineController,
PointElement,
LineElement
} from 'chart.js'
import 'chartjs-adapter-moment'
import zoomPlugin from 'chartjs-plugin-zoom'
import ChartDataLabels from 'chartjs-plugin-datalabels'
import { invokeWebApiWrapperAsync } from '../../components/factory'
import { getOperations } from '../Cluster/functions'
import LoaderPortal from '../../components/LoaderPortal'
Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin)
export const Tvd = ({ idWell, title }) => {
const [dataPlan, setDataPlan] = useState([])
const [dataFact, setDataFact] = useState([])
const [dataPredict, setDataPredict] = useState([])
const defaultOptions = {
responsive: true,
aspectRatio: 2.6,
interaction: {
intersect: false,
mode: 'index',
},
scales: {
x: {
min: 0,
type: 'linear',
display: true,
title: {
display: false,
text: '',
},
ticks: {
stepSize: 1,
}
},
y:{
type: 'linear',
position: 'top',
reverse: true,
display: true,
title: {
display: false,
text: '',
}
}
},
parsing: {
xAxisKey: 'day',
yAxisKey: 'depth',
},
elements: {
point: {
radius: 1.7,
//backgroundColor:'#aaa',
//pointStyle:'triangle',
},
},
plugins: {
legend: {
display: true,
},
datalabels: {
display: false,
},
tooltip: {
enabled: true,
callbacks: {
label: (tooltipItem) => tooltipItem.yLabel,
},
position: 'nearest',
},
}
}
const makeDataset = (data, label, color, borderWidth = 1.5, borderDash) => ({
label,
data,
backgroundColor: color,
borderColor: color,
borderWidth,
borderDash,
})
export const Tvd = memo(({ idWell, title }) => {
const [operations, setOperations] = useState([])
const [showLoader, setShowLoader] = useState(false)
const [chart, setChart] = useState()
const chartRef = useRef(null)
useEffect(() => {
invokeWebApiWrapperAsync(
async () => {
const operations = await getOperations(idWell)
setDataPlan(operations.plan)
setDataFact(operations.fact)
setDataPredict(operations.predict)
setOperations(operations)
},
setShowLoader,
`Не удалось загрузить операции по скважине "${idWell}"`,
)
}, [idWell])
useEffect(() => {
const data = {
datasets: [
makeDataset(operations?.fact, 'Факт', '#0A0'),
makeDataset(operations?.predict, 'Прогноз', 'purple', 1, [7, 3]),
makeDataset(operations?.plan, 'План', '#C004', 4),
]
}
if (chartRef.current && !chart) {
const thisOptions = {}
Object.assign(thisOptions, defaultOptions)
const 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, operations])
return (
<div className='container'>
<div className={'container'}>
<div>
{title ? title : (
{title || (
<h2 className={'mt-20px'}>График Глубина-день</h2>
)}
<LoaderPortal show={showLoader}>
<ChartTvD
dataPlan={dataPlan}
dataFact={dataFact}
dataPredict={dataPredict}
/>
<canvas ref={chartRef} />
</LoaderPortal>
</div>
</div>
)
}
})