From 2855adefd7bc5bdc884a14a64b38068f76673011 Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Thu, 9 Sep 2021 11:13:32 +0500 Subject: [PATCH] Fixed Telemetry depth to day chart --- src/components/charts/ChartDepthToDay.jsx | 16 +- .../charts/ChartTelemetryDepthToDay.jsx | 146 +++++++++--- .../charts/ChartTelemetryDepthToDayBase.tsx | 225 ------------------ .../TelemetryAnalysisDepthToDay.jsx | 19 +- 4 files changed, 126 insertions(+), 280 deletions(-) delete mode 100644 src/components/charts/ChartTelemetryDepthToDayBase.tsx diff --git a/src/components/charts/ChartDepthToDay.jsx b/src/components/charts/ChartDepthToDay.jsx index 18b7217..dcd7cde 100644 --- a/src/components/charts/ChartDepthToDay.jsx +++ b/src/components/charts/ChartDepthToDay.jsx @@ -17,18 +17,6 @@ Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement 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', @@ -42,7 +30,6 @@ const defaultOptions = { type: 'time', time: { unit: 'hour', - displayFormats: { 'hour': 'MM.DD' } @@ -51,7 +38,6 @@ const defaultOptions = { drawTicks: true, }, ticks: { - //count:24, stepSize:3, major:{enabled:true,}, z: 1, @@ -137,7 +123,7 @@ export default function ChartDepthToDay({dataPlan, dataFact, dataForecast}) { setChart(newChart) return () => chart?.destroy() - }else{ + } else { chart.data = data chart.update() } diff --git a/src/components/charts/ChartTelemetryDepthToDay.jsx b/src/components/charts/ChartTelemetryDepthToDay.jsx index 08606a8..d357b15 100644 --- a/src/components/charts/ChartTelemetryDepthToDay.jsx +++ b/src/components/charts/ChartTelemetryDepthToDay.jsx @@ -1,37 +1,121 @@ -import { useEffect, useState } from 'react' -import { ChartTelemetryDepthToDayBase } from './ChartTelemetryDepthToDayBase' -import { CreateDataset } from './ChartTimeArchive' +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'; -export const ChartTelemetryDepthToDay = ({data, lines}) => { - const [depthToDayDataParams, setDepthToDayDataParams] = useState({data: {datasets: []}}) +Chart.register(TimeScale, LinearScale, LineController, LineElement, PointElement, Legend, ChartDataLabels, zoomPlugin); - useEffect(() => { - if (!lines || !data) - return - - let newDatasets = lines.map(lineCfg => { - let datasets = CreateDataset(lineCfg) - if(data.length !== 0) - datasets.data = data.map(dataItem => { - return { - x: new Date(dataItem[lineCfg.xAccessorName??'date']), - y: dataItem[lineCfg.yAccessorName], - label: dataItem[lineCfg.label] - } - }) - return datasets - }) - - let newParams = { - displayLabels: true, - data: { - datasets: newDatasets +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: { + z: 1, + display : true, + textStrokeColor : "#fff", + textStrokeWidth : 2, + color:"#000", } + }, + + y:{ + type:'linear', + position:'top', + reverse:true, + display: true, + title: { + display: false, + text: '' + }, } - setDepthToDayDataParams(newParams) - }, [data, lines]) + }, + parsing: { + xAxisKey: 'date', + yAxisKey: 'depth' + }, + elements:{ + point:{ + radius:1.7, + hoverRadius:5, + }, + }, + plugins:{ + legend:{ + display: true, + }, + datalabels: { + display: false, + }, + } +} - return ( - - ) +const makeDataset = (data, label, color, width=1.5, dash) => ({ + label: label, + data: data, + backgroundColor: color, + borderColor: color, + borderWidth: width, + borderDash: dash, +}) + +export const ChartTelemetryDepthToDay = ({depthData, bitPositionData}) => { + const chartRef = useRef(null) + const [chart, setChart] = useState() + + useEffect(() => { + let data = { + datasets: [ + makeDataset(depthData, 'Глубина', '#0A0'), + makeDataset(bitPositionData, 'Положение долота', 'blue') + ] + } + + 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, depthData, bitPositionData]) + + return() } \ No newline at end of file diff --git a/src/components/charts/ChartTelemetryDepthToDayBase.tsx b/src/components/charts/ChartTelemetryDepthToDayBase.tsx deleted file mode 100644 index 6168ae6..0000000 --- a/src/components/charts/ChartTelemetryDepthToDayBase.tsx +++ /dev/null @@ -1,225 +0,0 @@ -import {useEffect, useRef, useState} from 'react'; -import { - Chart, - TimeScale, - LinearScale, - Legend, - LineController, - PointElement, - LineElement, - ChartData, - ChartTypeRegistry, - ChartOptions -} 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: 6, - animation: false, - tooltips: { - enabled: true, - callbacks: { - label(tooltipItem:any) { - return tooltipItem.yLabel; - } - } - }, - events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'], - scales: { - x:{ - type: 'time', - reverse: false, - time: { - stepSize: 20, - displayFormats: { - millisecond: 'HH:mm:ss.SSS', - second: 'HH:mm:ss', - minute: 'HH:mm:ss', - hour: 'DD HH:mm:ss', - day: 'MM.DD HH:mm', - week: 'yy.MM.DD HH:mm', - month: 'yyyy.MM.DD', - quarter: 'yyyy.MM.DD', - year: 'yyyy.MM', - }, - }, - grid:{ - drawTicks: false, - }, - ticks: { - z: 1, - display : true, - textStrokeColor : "#fff", - textStrokeWidth : 2, - color:"#000", - } - }, - - y:{ - type:'linear', - position:'top', - reverse: true, - } - }, - elements:{ - point:{ - radius:0, - hoverRadius:5, - }, - }, - plugins:{ - legend:{ - display: true, - }, - datalabels: { - display: false, - }, - } -} - -export type ChartTimeData = ChartData - -export type ChartTimeDataParams = { - data: ChartTimeData, - xStart?: Date, - xInterval?: number, - displayLabels?: Boolean, -} - -export type ChartTimeBaseProps = { - dataParams: ChartTimeDataParams, - // TODO: Create good type for options - options?: ChartOptions | any, -} - -export type TimeParams = { - unit: String - stepSize: number -} - -const linesPerInterval = 32 - -export const timeUnitByInterval = (intervalSec:number):String => { - if(intervalSec <= 60) - return 'millisecond' - - if(intervalSec <= 32*60) - return 'second' - - if(intervalSec <= 32*60*60) - return 'minute' - - if(intervalSec <= 32*12*60*60) - return 'hour' - - if(intervalSec <= 32*24*60*60) - return 'day' - - if(intervalSec <= 32*7*24*60*60) - return 'week' - - if(intervalSec <= 32*30.4375*24*60*60) - return 'month' - - if(intervalSec <= 32*121.75*24*60*60) - return 'quarter' - else - return 'year' -} - -export const timeParamsByInterval = (intervalSec:number) :TimeParams => { - let stepSize = intervalSec - let unit = timeUnitByInterval(intervalSec) - - switch(unit){ - case "millisecond": - stepSize *= 1000 - break; - case "second": - //stepSize *= 1 - break; - case "minute": - stepSize /= 60 - break; - case "hour": - stepSize /= 60*60 - break; - case "day": - stepSize /= 24*60*60 - break; - case "week": - stepSize /= 7*24*60*60 - break; - case "month": - stepSize /= 30*24*60*60 - break; - case "quarter": - stepSize /= 91*24*60*60 - break; - case "year": - stepSize /= 365.25*24*60*60 - break; - } - - stepSize = Math.round(stepSize/linesPerInterval) - stepSize = stepSize > 0 ? stepSize : 1; - return {unit, stepSize} -} - -export const ChartTelemetryDepthToDayBase: React.FC = ({options, dataParams}) => { - const chartRef = useRef(null) - const [chart, setChart] = useState() - - useEffect(() => { - if((chartRef.current)&&(!chart)) { - let thisOptions = {} - Object.assign(thisOptions, defaultOptions, options) - - let newChart = new Chart(chartRef.current, { - type: 'line', - plugins: [ChartDataLabels], - options: thisOptions, - data: dataParams.data - }) - setChart(newChart) - - return () => chart?.destroy() - } - }, [chart, options, dataParams]) - - useEffect(() => { - if (!chart) - return - - chart.data = dataParams.data - chart.options.aspectRatio = options?.aspectRatio - if (dataParams.xStart) { - let interval = Number(dataParams.xInterval ?? 600) - let start = new Date(dataParams.xStart) - let end = new Date(dataParams.xStart) - end.setSeconds(end.getSeconds() + interval) - let {unit, stepSize} = timeParamsByInterval(interval) - - if(chart.options.scales?.x){ - chart.options.scales.x.max = end.getTime() - chart.options.scales.x.min = start.getTime() - chart.options.scales.x.ticks.display = dataParams.displayLabels ?? true - chart.options.scales.x.time.unit = unit - chart.options.scales.x.time.stepSize = stepSize - } - } - - chart.update() - }, [chart, dataParams, options]) - - return() -} \ No newline at end of file diff --git a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx index 4a2fc98..53b3301 100644 --- a/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx +++ b/src/pages/TelemetryAnalysis/TelemetryAnalysisDepthToDay.jsx @@ -4,13 +4,9 @@ import { invokeWebApiWrapperAsync } from '../../components/factory' import { TelemetryAnalyticsService } from "../../services/api" import LoaderPortal from '../../components/LoaderPortal' -const lines = [ - { label: "Глубина забоя", yAccessorName: "wellDepth", color: '#f00' }, - { label: "Положение инструмента", yAccessorName: "bitDepth", color: '#ff0' } -] - export default function TelemetryAnalysisDepthToDay({idWell}) { - const [depthToDayData, setDepthToDayData] = useState([]) + const [depthData, setDepthData] = useState([]) + const [bitPositionData, setBitPositionData] = useState([]) const [loader, setLoader] = useState(false) useEffect(() => { @@ -18,7 +14,12 @@ export default function TelemetryAnalysisDepthToDay({idWell}) { invokeWebApiWrapperAsync( async () => { const depthToDayData = await TelemetryAnalyticsService.getWellDepthToDay(idWell) - setDepthToDayData(depthToDayData) + + const depths = depthToDayData.map(el => ({depth: el.wellDepth, date: el.date})) + setDepthData(depths) + + const bitPositions = depthToDayData.map(el => ({depth: el.bitDepth, date: el.date})) + setBitPositionData(bitPositions) }, setLoader, `Не удалось получить данные для Анализа Глубина-День по скважине "${idWell}"`) @@ -27,8 +28,8 @@ export default function TelemetryAnalysisDepthToDay({idWell}) { return ( )