英文:
Drawing Real Time Timeseries Line Chart with Lightning Chart JS?
问题
我正在尝试使用来自Websockets的数据绘制实时图表,这一切都很顺利,但我无法使X轴按照我想要的方式工作,目前我将其设置为:
const axisX = chart
.getDefaultAxisX()
// 启用X轴的TimeTickStrategy。
.setTickStrategy(AxisTickStrategies.Time)
以及我的数据如下:
socket.on('data', (data) => {
console.log(data)
series.add({ x: data.x - timeBegin, y: data.y })
})
目前,X轴从我的React应用程序加载的时间开始,并且实际上可以缩放到毫秒,并且工具提示显示包含毫秒的时间,但我希望数据中的X是数据的实际时间戳,该如何实现?另外,我如何使图表组件仅占用其容器的大小?尽管我将其放在React-Bootstrap容器中并尝试各种方法来使其小而居中,但它仍占据整个屏幕。
import {
lightningChart, AxisScrollStrategies, AxisTickStrategies, UIElementBuilders, Themes, IndividualPointFill, emptyLine,
PointShape
} from '@arction/lcjs'
import React, { useRef, useEffect } from 'react'
import { io } from 'socket.io-client'
const timeBegin = new Date().getTime()
const Chart = ({ data, id }) => {
const count = useRef(0)
const chartRef = useRef(undefined)
const DEFAULT_X_RANGE_MS = 30 * 1000; // 30 seconds
useEffect(() => {
// 创建图表、系列和任何其他静态组件。
// 注意:使用控制台日志确保图表仅创建一次,即使数据发生变化!
console.log('create chart')
// 创建XY图表。
const chart = lightningChart()
.ChartXY({
theme: Themes.light,
})
.setTitle('Custom X ticks with scrolling Axis')
const fillStyle = new IndividualPointFill({ color: 'red' })
// 创建适用于常规渐进X数据的线系列。
const series = chart.addPointLineSeries({
pointShape: PointShape.Circle,
})
.setDataCleaning({ minDataPointCount: 120000 });
series.setPointSize(10)
const axisX = chart
.getDefaultAxisX()
// 启用X轴的TimeTickStrategy。
.setTickStrategy(AxisTickStrategies.Time)
chart.getDefaultAxisY().setTitle('Y Axis')
chart.setAutoCursor((cursor) =>
cursor.setResultTableAutoTextStyle(true).setTickMarkerXAutoTextStyle(true).setTickMarkerYAutoTextStyle(true),
)
// 存储对图表组件的引用。
chartRef.current = { chart, series }
// 返回在组件卸载时销毁图表的函数。
return () => {
// 销毁图表。
console.log('destroy chart')
chart.dispose()
chartRef.current = undefined
}
}, [id])
useEffect(() => {
const components = chartRef.current
if (!components) return
// 设置图表数据。
const { series } = components
console.log('set chart data', data)
const socket = io('http://localhost:8080')
socket.on('data', (data) => {
console.log(data)
series.add({ x: data.x - timeBegin, y: data.y })
})
}, [data, chartRef])
return <div id={id} className='chart'></div>
}
export default Chart
我已经尝试过减去数据的时间戳与应用程序加载的时间,这个方法效果很好,但我想要X轴的实际时间戳。
英文:
I'm trying to draw real time chart with data coming Websockets, it's been great but I can't get the X axis to work like I want it to, right now I got it as
const axisX = chart
.getDefaultAxisX()
// Enable TimeTickStrategy for X Axis.
.setTickStrategy(AxisTickStrategies.Time)
and with my data as:
socket.on('data', (data) => {
console.log(data)
series.add({ x: data.x - timeBegin, y: data.y })
})
So right now the X axis starts from the time my React app loaded and are actually zoomable into the miliseconds and the tooltip does show time in with ms included but I want the x in the data to be the actual timestamp of the data, how do I make it work? Also, how do I make it so that the chart component only takes up the size of its container? it takes up the whole screen even though I put it in a React-Bootstrap Container and tried to do various methods to make it small and centered to no avail.
import {
lightningChart, AxisScrollStrategies, AxisTickStrategies, UIElementBuilders, Themes, IndividualPointFill, emptyLine,
PointShape
} from '@arction/lcjs'
import React, { useRef, useEffect } from 'react'
import { io } from 'socket.io-client'
const timeBegin = new Date().getTime()
const Chart = ({ data, id }) => {
const count = useRef(0)
const chartRef = useRef(undefined)
const DEFAULT_X_RANGE_MS = 30 * 1000; // 30 seconds
useEffect(() => {
// Create chart, series and any other static components.
// NOTE: console log is used to make sure that chart is only created once, even if data is changed!
console.log('create chart')
// Create a XY Chart.
const chart = lightningChart()
.ChartXY({
theme: Themes.light,
})
.setTitle('Custom X ticks with scrolling Axis')
const fillStyle = new IndividualPointFill({ color: 'red' })
// Create line series optimized for regular progressive X data.
const series = chart.addPointLineSeries({
pointShape: PointShape.Circle,
// dataPattern: {
// // pattern: 'ProgressiveX' => Each consecutive data point has increased X coordinate.
// pattern: 'ProgressiveX',
// // regularProgressiveStep: true => The X step between each consecutive data point is regular (for example, always `1.0`).
// regularProgressiveStep: true,
// },
})
.setDataCleaning({ minDataPointCount: 120000 });
series.setPointSize(10)
const axisX = chart
.getDefaultAxisX()
// Enable TimeTickStrategy for X Axis.
.setTickStrategy(AxisTickStrategies.Time)
chart.getDefaultAxisY().setTitle('Y Axis')
chart.setAutoCursor((cursor) =>
cursor.setResultTableAutoTextStyle(true).setTickMarkerXAutoTextStyle(true).setTickMarkerYAutoTextStyle(true),
)
// Store references to chart components.
chartRef.current = { chart, series }
// Return function that will destroy the chart when component is unmounted.
return () => {
// Destroy chart.
console.log('destroy chart')
chart.dispose()
chartRef.current = undefined
}
}, [id])
useEffect(() => {
const components = chartRef.current
if (!components) return
// Set chart data.
const { series } = components
console.log('set chart data', data)
const socket = io('http://localhost:8080')
socket.on('data', (data) => {
console.log(data)
series.add({ x: data.x - timeBegin, y: data.y })
})
}, [data, chartRef])
return <div id={id} className='chart'></div>
}
export default Chart
I have tried to substract the timestamp of the data with the time the app loaded which works great but I want the actual timestamp as X.
答案1
得分: 1
要在你的LightningChart中将实际时间戳显示为X轴数值,请按照以下方式修改你的代码:
在向系列添加数据时,删除x值中的timeBegin减法操作:
series.add({ x: data.x, y: data.y });
将X轴刻度策略设置为显示实际时间戳:
axisX.setTickStrategy(AxisTickStrategies.DateTime, (tickStrategy) =>
tickStrategy.setDateOrigin(new Date())
);
为了使图表组件占用其容器的大小,请设置容器元素的尺寸并应用以下CSS规则:
.chart-container {
width: 100%;
height: 400px; /* 根据需要调整高度 */
}
.chart {
width: 100%;
height: 100%;
}
在你的组件中:
import React from 'react';
const Chart = ({ data, id }) => {
return (
<div className="chart-container">
<div id={id} className="chart"></div>
</div>
);
}
英文:
To display the actual timestamp as the X-axis values in your lightningChart, modify your code as follows:
Remove the subtraction of timeBegin from the x value when adding data to the series:
series.add({ x: data.x, y: data.y });
Set the X-axis tick strategy to display the actual timestamp:
axisX.setTickStrategy(AxisTickStrategies.DateTime, (tickStrategy) =>
tickStrategy.setDateOrigin(new Date())
);
For making the chart component take up the size of its container, set the dimensions of the container element and apply the following CSS rules:
.chart-container {
width: 100%;
height: 400px; /* Adjust the height as needed */
}
.chart {
width: 100%;
height: 100%;
}
In your component:
import React from 'react';
const Chart = ({ data, id }) => {
return (
<div className="chart-container">
<div id={id} className="chart"></div>
</div>
);
}
答案2
得分: 0
AxisTickStrategies.DateTime
的最小单位是1分钟,这就是为什么它不起作用,您需要使用 AxisTickStrategies.Time
并将其设置为
// 保存“总”时间(以毫秒为单位)
const timeBeginSince1970 = new Date().getTime()
// 这样做是为了获取当天的时间(以毫秒为单位)
const timeBegin = new Date().getHours() * 3600 * 1000 + new Date().getMinutes() * 60 * 1000 + new Date().getSeconds() * 1000 + new Date().getMilliseconds()
// 将起始时间设置为原点
chart.setTickStrategy(AxisTickStrategies.Time, (tickStrategy) => tickStrategy.setTimeOrigin(timeBegin))
// 向系列添加数据
const timeStamp = data.x - timeBeginInMS
series.add({ x: timeStamp, y: data.y })
假设您的 data.x
是自1970年以来的总毫秒数,data.x - timeBeginMS
将等于数据的当天时间,适用于图表的X轴。
我忘了将id作为div的props传递给图表,这就是为什么它没有附加到 'root' 元素,这解释了为什么CSS没有应用于图表,这是新手的错误。
英文:
The minimum for AxisTickStrategies.DateTime
is 1 minute which is why it didn't work, you need AxisTickStrategies.Time
and have it set up as
// Save the "total" time in ms
const timeBeginSince1970 = new Date().getTime()
// Do this to get the time of the day in ms
const timeBegin = new Date().getHours() * 3600 * 1000 + new Date().getMinutes() * 60 * 1000 + new Date().getSeconds() * 1000 + new Date().getMilliseconds()
// Set the origin equal to the starting time
chart.setTickStrategy(AxisTickStrategies.Time, (tickStrategy) => tickStrategy.setTimeOrigin(timeBegin))
// Adding data to the series
const timeStamp = data.x - timeBeginInMS
series.add({ x: timeStamp, y: data.y })
Assuming that your data.x is total time since 1970 in ms, data.x - timeBeginMS
will equal the time of the day of the data which will fit right on to the X axis of the chart.
I forgot to pass an id as props for the div of the chart which is why it didnt get appended to the 'root' element which explains why the CSS didnt apply to the chart, rookies' mistake.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论