From f0ea4423adb3de3ac6c2b63f092053e27dec3529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 13 Apr 2021 18:02:25 +0500 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B0=D0=BB=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=81=20js=20=D0=BD=D0=B0=20ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/charts/ChartTimeBase.tsx | 152 ++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/components/charts/ChartTimeBase.tsx diff --git a/src/components/charts/ChartTimeBase.tsx b/src/components/charts/ChartTimeBase.tsx new file mode 100644 index 0000000..243fd47 --- /dev/null +++ b/src/components/charts/ChartTimeBase.tsx @@ -0,0 +1,152 @@ +import { useEffect, useRef, useState} from 'react'; +import { + Chart, + TimeScale, + LinearScale, + Legend, + LineController, + PointElement, + LineElement, + ChartData, + ChartTypeRegistry, + ChartOptions} from 'chart.js' +import 'chartjs-adapter-date-fns'; + +Chart.register( TimeScale, LinearScale, LineController, LineElement, PointElement, Legend ); + +const defailtOptions = { + maintainAspectRatio: 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, + }, + }, + plugins:{ + legend:{ + display: false, + } + } +} + +export type ChartTimeData = ChartData + +export type ChartTimeDataParams = { + data: ChartTimeData, + yStart?: Date, + yInterval?: number, + displayLabels?: Boolean, +} + +export type ChartTimeBaseProps = { + dataParams: ChartTimeDataParams, + options?: ChartOptions, +} + +// const mergeDataSets = (target: {datasets:any[]}, source: {datasets:any[]})=>{ +// source.datasets.forEach(sds=>{ +// let tds = target.datasets.find(o=>o.label === sds.label) +// if(!tds) +// target.datasets.push(sds) +// else +// tds.data = sds.data +// }) + +// target.datasets.forEach(tds=>{ +// let sdsIdx = target.datasets.findIndex(o=>o.label === tds.label) +// if(sdsIdx === -1) +// target.datasets.splice(sdsIdx, 1) +// }) +// } + +export const ChartTimeBase: React.FC = (props) => { + const chartRef = useRef(null) + + const [chart, setChart] = useState() + // const [chart, setChart] = useState>() + + useEffect(()=>{ + if(chartRef.current && (!chart)){ + let thisOptions = {} + Object.assign(thisOptions, defailtOptions, props.options) + + let newChart = new Chart(chartRef.current, { + type: 'line', + options: thisOptions, + data: props.dataParams.data + }) + setChart(newChart) + return () => chart?.destroy() + } + }, [chart, props.options, props.dataParams]) + + + + useEffect(()=>{ + if(!chart) + return + + //mergeDataSets(chart.data, props.dataParams.data) + chart.data = props.dataParams.data + + if(props.dataParams.yStart){ + let interval = props.dataParams.yInterval ?? 600 + let start = new Date(props.dataParams.yStart) + let end = new Date(props.dataParams.yStart) + end.setSeconds(end.getSeconds() + interval) + + if(chart.options.scales?.y){ + chart.options.scales.y.max = end.getTime() + chart.options.scales.y.min = start.getTime() + } + } + + chart.update() + }, [chart, props]) + + return() +} \ No newline at end of file