настройка внешнего вида графиков

This commit is contained in:
Фролов 2021-04-12 18:05:40 +05:00
parent 34a73ec9b1
commit 09e5ec5179
4 changed files with 272 additions and 85 deletions

View File

@ -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(<canvas ref={chartRef} />)
}

View File

@ -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(<canvas ref={chartRef} />)
}

View File

@ -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<keyof ChartTypeRegistry, {
x: number;
y: Date;
}[], unknown>
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<ChartTimeProps> = (props) => {
const chartRef = useRef<HTMLCanvasElement>(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(<canvas ref={chartRef} />)
}
export {ChartTime}

View File

@ -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 {ChartTime} from '../components/charts/ChartTime'
import {useParams} from 'react-router-dom' import {useParams} from 'react-router-dom'
import {Subscribe} from '../services/signalr' import {Subscribe} from '../services/signalr'
import {DataService} from '../services/api' 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){ export default function Well(props){
let { id } = useParams(); let { id } = useParams();
const [saubData, setSaubData] = useState([]) const [saubData, setSaubData] = useState([])
const [interval, setInterval] = useState(600)
const handleReceiveDataSaub = (data)=>{ const handleReceiveDataSaub = (data)=>{
if(data) if(data)
setSaubData(pre => [...pre, ...data].slice(-1024)) setSaubData(data)
} }
useEffect( ()=> { useEffect( ()=> {
@ -20,12 +68,19 @@ export default function Well(props){
.catch(error=>console.error(error)) .catch(error=>console.error(error))
return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub) return Subscribe('ReceiveDataSaub', `well_${id}`, handleReceiveDataSaub)
}, },
[id]); [id]);
let colSpan = 24/lineParameters.length
let cols = lineParameters.map(line =>
<Col span={colSpan}>
<ChartTime data={saubData} config={line} interval={interval}/>
</Col>)
return(<div> return(<div>
Well id: {id}; points count: {saubData.length} <div>Well id: {id}; points count: {saubData.length}</div>
<ChartTime/> <Row height='100%'>{cols}</Row>
</div>) </div>)
} }