diff --git a/src/components/charts/ChartTime.js b/src/components/charts/ChartTime.js deleted file mode 100644 index 4ba7a08..0000000 --- a/src/components/charts/ChartTime.js +++ /dev/null @@ -1,79 +0,0 @@ -import React, { useEffect, useRef} from 'react'; - -import { Chart, TimeScale, LinearScale, Legend, LineController, PointElement, LineElement } from 'chart.js' -//import Chart from 'chart.js/auto'; -import 'chartjs-adapter-date-fns'; -Chart.register( TimeScale, LinearScale, LineController, LineElement, PointElement, Legend ); - -const options = { - //showLine :true, - //indexAxis:'y', - //maintainAspectRatio: false, - //responsive:false, - scales: { - y:{ - type: 'time', - time: { - unit: 'second', - 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', - }, - }, - }, - - x:{ - type:'linear' - } - }, -} - -const data= { - datasets: [{ - label: 'Torque', - data: [ - {x: 10, y: '2021-04-09T17:50:34.021679+05:00'}, - {x: 15, y: '2021-04-09T17:50:33.021679+05:00'}, - {x: 20, y: '2021-04-09T17:50:32.021679+05:00'}], - backgroundColor: 'rgb(255, 99, 132)', - borderColor: 'rgb(255, 99, 132)', - }, - { - label: 'Pressure', - data: [ - {x: 11, y: '2021-04-09T17:50:34.021679+05:00'}, - {x: 14, y: '2021-04-09T17:50:33.021679+05:00'}, - {x: 21, y: '2021-04-09T17:50:32.021679+05:00'}], - - borderColor: 'rgba(0, 99, 132, 0.5)', - - } - ] -} - -// export type LineConfig = { -// login?: string | null; -// password?: string | null; -// } - -export function ChartTime(/*props*/){ - const chartRef = useRef(null) - - useEffect(()=>{ - let chart = new Chart(chartRef.current, { - type: 'line', - data, - options}) - //chart.canvas.parentNode.style.height = '128px'; - return () => chart.destroy() - },[]) - - return() -} \ No newline at end of file diff --git a/src/components/charts/ChartTime.jsx b/src/components/charts/ChartTime.jsx new file mode 100644 index 0000000..a48e8ef --- /dev/null +++ b/src/components/charts/ChartTime.jsx @@ -0,0 +1,127 @@ +import React, { useEffect, useRef, useState} from 'react'; +import { Chart, TimeScale, LinearScale, Legend, LineController, PointElement, LineElement} from 'chart.js' +import 'chartjs-adapter-date-fns'; + +Chart.register( TimeScale, LinearScale, LineController, LineElement, PointElement, Legend ); + +const options = { + maintainAspectRatio: false, + //responsive:false, + aspectRatio:0.4, + animation: false, + scales: { + y:{ + type: 'time', + reverse:true, + time: { + unit: 'second', + 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', + }, + }, + position:{ x: 20 }, + grid:{ + drawTicks: false, + }, + ticks: { + z: 1, + textStrokeColor : "#ffff", + textStrokeWidth : 1, + color:"#000" + } + }, + + x:{ + type:'linear', + position:'top' + } + }, + elements:{ + point:{ + radius:0, + hoverRadius:5, + }, + }, +} + +const GetRandomColor = () => "#" + Math.floor(Math.random()*16777215).toString(16) + +function GetOrCreateDatasetByLineConfig (chart, lineConfig) { + let dataset = chart?.data?.datasets.find(d=>d.label === lineConfig.label) + if(!dataset) + { + let color = lineConfig.borderColor + ?? lineConfig.backgroundColor + ?? lineConfig.color + ?? GetRandomColor() + + dataset = { + label:lineConfig.label, + data:[], + backgroundColor: lineConfig.backgroundColor ?? color, + borderColor: lineConfig.borderColor ?? color, + borderWidth: lineConfig.borderWidth ?? 1, + borderDash: lineConfig.dash ?? [], + } + chart.data.datasets.push(dataset); + } + return dataset +} + +export const ChartTime = (props) => { + const chartRef = useRef(null) + const [chart, setChart] = useState(null) + + useEffect(()=>{ + if(chartRef.current && (!chart)){ + let thisOptions = {} + Object.assign(thisOptions, options, props.options) + let newChart = new Chart(chartRef.current, { + type: 'line', + options: thisOptions, + }) + setChart(newChart) + return () => chart?.destroy() + } + }, [chart, props.options]) + + useEffect(()=>{ + if((!chart) + || (!props?.config?.lines) + || (!props?.data) + || (props.config.lines.length === 0) + || (props.data.length === 0)) + return + + props.config.lines.forEach(lineCfg => { + let dataset = GetOrCreateDatasetByLineConfig(chart, lineCfg) + let points = props.data.map(dataItem => {return{ + x: dataItem[lineCfg.xAcessorName], + y: new Date(dataItem[lineCfg.yAcessorName])} + }) + dataset.data = [ ...dataset.data, ...points, ].slice(-1024) + }); + + let now = new Date() + let max = new Date() + max.setSeconds(now.getSeconds() - props.config.interval) + + let yAxes = chart.options.scales.y + yAxes.ticks.display = props.config.yDisplay ?? true + yAxes.min = max.getTime() + yAxes.max = now.getTime() + + chart.update() + }, [ chart, props.data, props.config]) + return() +} + diff --git a/src/components/charts/__ChartTime.__tsx b/src/components/charts/__ChartTime.__tsx new file mode 100644 index 0000000..de88cfc --- /dev/null +++ b/src/components/charts/__ChartTime.__tsx @@ -0,0 +1,84 @@ +import React, { useEffect, useRef, useState} from 'react'; +import { Chart, TimeScale, LinearScale, Legend, LineController, PointElement, LineElement, ChartConfiguration, ChartData, ChartOptions, ScatterDataPoint, ChartTypeRegistry } from 'chart.js' +//import Chart from 'chart.js/auto'; +import 'chartjs-adapter-date-fns'; +Chart.register( TimeScale, LinearScale, LineController, LineElement, PointElement, Legend ); +const options: ChartOptions = { + //showLine :true, + //indexAxis:'y', + //maintainAspectRatio: false, + //responsive:false, + scales: { + y:{ + type: 'time', + time: { + unit: 'second', + 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', + }, + }, + }, + + x:{ + type:'linear' + } + }, +} +type ChartTimeData = ChartData +const data: ChartTimeData = { + datasets: [{ + label: 'Torque', + data: [ + {x: 10, y: new Date('2021-04-09T17:50:34.021679+05:00')}, + {x: 15, y: new Date('2021-04-09T17:50:33.021679+05:00')}, + {x: 20, y: new Date('2021-04-09T17:50:32.021679+05:00')}], + backgroundColor: 'rgb(255, 99, 132)', + borderColor: 'rgb(255, 99, 132)', + } + ] +} +export type LineConfig = { + type?: string + label: string + xAcessorName: string + yAcessorName: string + labels?: any[] +} +export type ChartTimeProps = { + data: any[], + config: LineConfig[], + options?:ChartOptions, +} +const ChartTime: React.FC = (props) => { + const chartRef = useRef(null) + props.config.forEach(lineCfg => { + let dataset = {} + dataset.data = props.data.map(dataItem => {return { + x: dataItem[lineCfg.xAcessorName], + y: new Date(dataItem[lineCfg.yAcessorName]) + }}); + }); + useEffect(()=>{ + if(chartRef.current){ + let chart = new Chart(chartRef.current, { + type: 'line', + data:[], + options: props.options ?? options}) + //chart.canvas.parentNode.style.height = '128px'; + return () => chart.destroy() + } + },[]) + return() +} +export {ChartTime} \ No newline at end of file diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 3e116ac..b257c45 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -1,17 +1,65 @@ -import React, { useState, useEffect} from 'react'; +import React, { useState, useEffect,} from 'react'; +import { Row, Col} from 'antd' import {ChartTime} from '../components/charts/ChartTime' import {useParams} from 'react-router-dom' import {Subscribe} from '../services/signalr' import {DataService} from '../services/api' +const dash = [7,3] + +const lineParameters = [ + { + yDisplay: true, + lines:[ + { label:"blockHeight", xAcessorName : "blockHeight", yAcessorName : "date", color:'#aaf' }, + ], + }, + { + yDisplay: false, + lines:[ + { label:"blockSpeed", xAcessorName : "blockSpeed", yAcessorName : "date", color:'#0a0' }, + { label:"blockSpeedSp", xAcessorName : "blockSpeedSp", yAcessorName : "date", color:'#0a0', dash }, + ], + }, + { + yDisplay: false, + lines:[ + { label:"pressure", xAcessorName : "pressure", yAcessorName : "date", color:'#a00' }, + { label:"pressureSp", xAcessorName : "pressureSp", yAcessorName : "date", color:'#a00', dash }, + ], + }, + { + yDisplay: false, + lines:[ + { label:"axialLoad", xAcessorName : "axialLoad", yAcessorName : "date", color:'#00a' }, + { label:"axialLoadSp", xAcessorName : "axialLoadSp", yAcessorName : "date", color:'#00a', dash }, + ], + }, + { + yDisplay: false, + lines:[ + { label:"вес", xAcessorName : "hookWeight", yAcessorName : "date", color:'#0aa' }, + { label:"вес макс", xAcessorName : "hookWeightLimitMax", yAcessorName : "date", color:'#0aa', dash }, + ], + }, + { + yDisplay: false, + lines:[ + { label:"rotorTorque", xAcessorName : "rotorTorque", yAcessorName : "date", color:'#a0a' }, + { label:"rotorTorqueSp", xAcessorName : "rotorTorqueSp", yAcessorName : "date", color:'#a0a', dash }, + ], + } +] + export default function Well(props){ let { id } = useParams(); const [saubData, setSaubData] = useState([]) + const [interval, setInterval] = useState(600) const handleReceiveDataSaub = (data)=>{ if(data) - setSaubData(pre => [...pre, ...data].slice(-1024)) + setSaubData(data) } useEffect( ()=> { @@ -20,12 +68,19 @@ export default function Well(props){ .catch(error=>console.error(error)) return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub) - }, + }, [id]); - + + let colSpan = 24/lineParameters.length + let cols = lineParameters.map(line => + + + ) + return( - Well id: {id}; points count: {saubData.length} - + Well id: {id}; points count: {saubData.length} + {cols} + ) } \ No newline at end of file