asb_cloud_front/src/components/charts/ChartTimeOnline.tsx

120 lines
3.4 KiB
TypeScript

import { useEffect, useState} from 'react';
import {ChartTimeBase, ChartTimeData, ChartTimeDataParams} from './ChartTimeBase'
const GetRandomColor = () => "#" + Math.floor(Math.random()*16777215).toString(16)
function GetOrCreateDatasetByLineConfig (data: ChartTimeData, lineConfig: LineConfig) {
let dataset = 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 ?? [],
showLine: lineConfig.showLine,
}
data.datasets.push(dataset);
}
return dataset
}
export type LineConfig = {
type?: string
label: string
units?: string
xAccessorName: string
yAccessorName: string
color?:string
borderColor?: string
backgroundColor?: string
borderWidth?: number
dash?:number[]
labels?: any[]
showLine: boolean
xConstValue?: number|null
}
export type ChartTimeProps = {
label?: string,
yDisplay: Boolean,
// linePv?: LineConfig,
// lineSp?: LineConfig,
// lineIdle?: LineConfig,
lines: LineConfig[],
data: any[],
interval: number,
}
export const ChartTimeOnline: React.FC<ChartTimeProps> = (props) => {
const [dataParams, setDataParams] = useState<ChartTimeDataParams>({data: {datasets:[]}, yStart: new Date(), })
useEffect(()=>{
if( (!props?.lines)
|| (!props?.data)
|| (props.lines.length === 0)
|| (props.data.length === 0))
return
setDataParams((preDataParams) => {
props.lines.forEach(lineCfg => {
let dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, lineCfg)
let points = props.data.map(dataItem => {return{
x: lineCfg.xConstValue ?? dataItem[lineCfg.xAccessorName],
label: dataItem[lineCfg.xAccessorName],
y: new Date(dataItem[lineCfg.yAccessorName])}
})
//dataset.data = [ ...dataset.data, ...points,].slice(-1024)
let data = [ ...dataset.data, ...points,]
if(points?.length > 2)
data.sort((a,b) => a.y > b.y ? 1 : -1)
if(data.length > 1024)
data.splice(0, (1024 - data.length))
dataset.data = data;
});
preDataParams.yStart = new Date()
preDataParams.yStart.setSeconds(preDataParams.yStart.getSeconds() - props.interval)
preDataParams.yInterval = props.interval
preDataParams.displayLabels = props.yDisplay
return preDataParams
})
}, [ props.data, props.lines, props.interval, props.yDisplay])
const chartPluginsOptions = {
plugins:{
legend:{
display: false,
},
datalabels: {
backgroundColor: 'transparent',
borderRadius: 4,
color: '#000B',
display: function(context:any) {
return context.dataset.label === 'wellDepth'
? 'auto'
: false
},
formatter: function(value: any, context: any) {
return `${value.y.toLocaleTimeString()} ${value.label.toPrecision(4)}`
},
padding: 6,
align: 'left',
anchor: 'center',
clip: true
},
}
}
return(<ChartTimeBase dataParams = {dataParams} options = { chartPluginsOptions } />)
}