Close Editor Run Reset Auto Update CJS const lcjs = require('@arction/lcjs')
const xydata = require('@arction/xydata')
const { AxisScrollStrategies, AxisTickStrategies, lightningChart, LegendBoxBuilders, Themes } = lcjs
const { createProgressiveTraceGenerator } = xydata
const dashboard = lightningChart().Dashboard({
// theme: Themes.darkGold
numberOfRows: 1,
numberOfColumns: 2,
})
const chartXY = dashboard
.createChartXY({
columnIndex: 0,
rowIndex: 0,
columnSpan: 1,
rowSpan: 1,
})
.setTitle('ChartXY')
const timeOriginDate = new Date()
timeOriginDate.setHours(0)
timeOriginDate.setMinutes(0)
timeOriginDate.setSeconds(0)
const timeOrigin = timeOriginDate.getTime()
chartXY
.getDefaultAxisX()
.setTickStrategy(AxisTickStrategies.Time, (ticks) =>
ticks.setTimeOrigin(((timeOriginDate.getHours() * 60 + timeOriginDate.getMinutes()) * 60 + timeOriginDate.getSeconds()) * 1000),
)
.setScrollStrategy(AxisScrollStrategies.progressive)
.setInterval({ start: -10 * 1000, end: 0, stopAxisAfter: false })
.setAnimationScroll(false)
const seriesSMA = chartXY
.addLineSeries({
dataPattern: {
pattern: 'ProgressiveX',
},
automaticColorIndex: 3,
})
.setDataCleaning({ minDataPointCount: 1 })
.setName('Moving average')
const seriesValue = chartXY
.addLineSeries({
dataPattern: {
pattern: 'ProgressiveX',
},
automaticColorIndex: 0,
})
.setDataCleaning({ minDataPointCount: 1 })
.setName('Value')
const legend = chartXY.addLegendBox(LegendBoxBuilders.HorizontalLegendBox).add(chartXY)
const dataGrid = dashboard
.createDataGrid({
columnIndex: 1,
rowIndex: 0,
columnSpan: 1,
rowSpan: 1,
})
.setTitle('DataGrid')
.setColumnWidth(0, { min: 140 })
.setColumnWidth(1, { min: 140 })
.setColumnWidth(2, { min: 140 })
// Stream live timestamp data into series.
// Application displays timestamps as offset from when application started (starts at 00:00:00).
const dataGridContent = [['Time', 'Value', 'Moving Average']]
const smaPeriodSize = 50
const lastNSamples = []
createProgressiveTraceGenerator()
.setNumberOfPoints(10 * 1000)
.generate()
.setStreamBatchSize(1)
.setStreamInterval(20)
.toStream()
.forEach((p) => {
const sample = {
// TimeTickStrategy interprets values as milliseconds (UNIX timestamp).
// Exactly same as JavaScript Date APIs.
x: Date.now() - timeOrigin,
y: p.y,
}
lastNSamples.push(sample.y)
if (lastNSamples.length > smaPeriodSize) {
lastNSamples.shift()
}
const sma = lastNSamples.reduce((prev, cur) => prev + cur, 0) / lastNSamples.length
// Add new data point to XY line series.
seriesValue.add(sample)
seriesSMA.add({ x: sample.x, y: sma })
// Add new Row into DataGrid for the data point.
const sampleDateTime = new Date(sample.x + timeOrigin)
dataGridContent.splice(1, 0, [
`${sampleDateTime.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hour12: false,
})}:${milliSeconds(sampleDateTime)}`,
`${sample.y.toFixed(2)}`,
`${sma.toFixed(2)}`,
])
// Limit number of rows.
dataGridContent.length = Math.min(dataGridContent.length, 25)
dataGrid.removeCells().setTableContent(dataGridContent)
})
const milliSeconds = (date) => {
let str = String(date.getMilliseconds())
while (str.length < 3) {
str = `0${str}`
}
return str
}
JavaScript Monitoring Data Grid - Editor Example showcasing use of LightningChart JS Data Grid in a real-time monitoring use case.
This application simulates real-time data coming in at high speed. Data is then displayed both in a scrolling line chart and a Data Grid.
At such high input rate, the information may be very difficult to spot from the Data Grid. To aid this, the Data Grid cells may be color coded similarly to a heat map . For example, for potentially problematic values the cell text or background could be colored red.
In this kind of case, the Data Grid allows displaying data that traditional line charts can not, for example supplementary measurements like temperature, streaming latency, etc.
For more information about LightningChart JS Data Grid, click here