Skip to content

Commit 57b36b3

Browse files
author
Niilo Keinänen
committed
LCJS v7.0.1
1 parent 497d1cc commit 57b36b3

8 files changed

+64
-46
lines changed

README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ Direct developer email support can be purchased through a [Support Plan][4] or b
8484
© LightningChart Ltd 2009-2022. All rights reserved.
8585

8686

87-
[3D chart]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/Chart3D.html
88-
[3D axis]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/Axis3D.html
89-
[Paletted Fill]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/PalettedFill.html
90-
[Color lookup table]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/LUT.html
91-
[Color HSV factory]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/functions/ColorHSV.html
92-
[Color shading styles (3D)]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/variables/ColorShadingStyles.html
93-
[Surface Grid Series]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/SurfaceGridSeries3D.html
94-
[Heatmap Grid Series]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/HeatmapGridSeriesIntensityValues.html
95-
[Legend Box]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/classes/Chart.html#addLegendBox
96-
[Axis scroll strategies]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/variables/AxisScrollStrategies.html
97-
[Axis tick strategies]: https://lightningchart.com/js-charts/api-documentation/v6.1.0/variables/AxisTickStrategies.html
87+
[3D chart]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/Chart3D.html
88+
[3D axis]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/Axis3D.html
89+
[Paletted Fill]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/PalettedFill.html
90+
[Color lookup table]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/LUT.html
91+
[Color HSV factory]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/functions/ColorHSV.html
92+
[Color shading styles (3D)]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/variables/ColorShadingStyles.html
93+
[Surface Grid Series]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/SurfaceGridSeries3D.html
94+
[Heatmap Grid Series]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/HeatmapGridSeriesIntensityValues.html
95+
[Legend Box]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/classes/Chart.html#addLegendBox
96+
[Axis scroll strategies]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/variables/AxisScrollStrategies.html
97+
[Axis tick strategies]: https://lightningchart.com/js-charts/api-documentation/v7.0.1/variables/AxisTickStrategies.html
9898

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"webpack-stream": "^7.0.0"
1818
},
1919
"dependencies": {
20-
"@lightningchart/lcjs": "^6.1.1",
20+
"@lightningchart/lcjs": "^6.1.2",
2121
"@lightningchart/xydata": "^1.4.0"
2222
},
2323
"lightningChart": {

src/index.js

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ const { lightningChart, LUT, ColorHSV, PalettedFill, emptyLine, AxisScrollStrate
88
const historyMs = 27 * 1000
99
// Sampling rate as samples per second.
1010
const sampleRateHz = 35
11-
const sampleIntervalMs = 1000 / sampleRateHz
11+
// Minimum time step that can be displayed by the heatmap. In this example, set to half of average interval between samples. In normal applications you can set this to some comfortably small value.
12+
// Smaller value means more precision but more RAM and GPU memory usage.
13+
const heatmapMinTimeStepMs = (0.5 * 1000) / sampleRateHz
1214

1315
// Create empty dashboard and charts.
1416
// NOTE: Using `Dashboard` is no longer recommended for new applications. Find latest recommendations here: https://lightningchart.com/js-charts/docs/basic-topics/grouping-charts/
@@ -56,20 +58,18 @@ fetch(new URL(document.head.baseURI).origin + new URL(document.head.baseURI).pat
5658
},
5759
]
5860

59-
channelList = channelList.map((channel) => {
61+
channelList = channelList.map((channel, iii) => {
6062
const rows = channel.data[0].length
6163
const chart2D = dashboard
6264
.createChartXY({
6365
columnIndex: channel.columnIndex,
6466
rowIndex: 0,
6567
})
6668
.setTitle(`${channel.name} | 2D audio spectrogram`)
67-
chart2D
68-
.getDefaultAxisX()
69-
.setTickStrategy(AxisTickStrategies.Time)
69+
chart2D.axisX
7070
.setScrollStrategy(AxisScrollStrategies.progressive)
7171
.setDefaultInterval((state) => ({ end: state.dataMax, start: (state.dataMax ?? 0) - historyMs, stopAxisAfter: false }))
72-
chart2D.getDefaultAxisY().setTitle('Frequency').setUnits('Hz')
72+
chart2D.axisY.setTitle('Frequency').setUnits('Hz')
7373

7474
const chart3D = dashboard
7575
.createChart3D({
@@ -78,13 +78,10 @@ fetch(new URL(document.head.baseURI).origin + new URL(document.head.baseURI).pat
7878
})
7979
.setTitle(`${channel.name} | 3D audio spectrogram`)
8080

81-
chart3D
82-
.getDefaultAxisX()
83-
.setTickStrategy(AxisTickStrategies.Time)
81+
chart3D.axisX
8482
.setScrollStrategy(AxisScrollStrategies.progressive)
8583
.setDefaultInterval((state) => ({ end: state.dataMax, start: (state.dataMax ?? 0) - historyMs, stopAxisAfter: false }))
86-
chart3D
87-
.getDefaultAxisY()
84+
chart3D.axisY
8885
.setTitle('Intensity')
8986
.setUnits('dB')
9087
.setTickStrategy(AxisTickStrategies.Numeric, (ticks) =>
@@ -97,46 +94,67 @@ fetch(new URL(document.head.baseURI).origin + new URL(document.head.baseURI).pat
9794
scrollDimension: 'columns',
9895
resolution: rows,
9996
})
100-
.setStep({ x: sampleIntervalMs, y: rowStep })
97+
.setStep({ x: heatmapMinTimeStepMs, y: rowStep })
10198
.setFillStyle(new PalettedFill({ lut }))
10299
.setWireframeStyle(emptyLine)
103100
.setDataCleaning({ maxDataPointCount: 10000 })
104101

105102
const surfaceSeries3D = chart3D
106103
.addSurfaceScrollingGridSeries({
107104
scrollDimension: 'columns',
108-
columns: Math.ceil(historyMs / sampleIntervalMs),
105+
columns: Math.ceil(historyMs / heatmapMinTimeStepMs),
109106
rows,
110107
})
111-
.setStep({ x: sampleIntervalMs, z: rowStep })
108+
.setStep({ x: heatmapMinTimeStepMs, z: rowStep })
112109
.setFillStyle(new PalettedFill({ lut, lookUpProperty: 'y' }))
113110
.setWireframeStyle(emptyLine)
114111

115112
return { ...channel, chart2D, chart3D, heatmapSeries2D, surfaceSeries3D }
116113
})
117114

118-
// Setup infinite streaming from static data set.
119-
let tStart = window.performance.now()
120-
let pushedDataCount = 0
121-
const streamData = () => {
122-
const tNow = window.performance.now()
123-
// NOTE: This code is for example purposes (streaming stable data rate without destroying browser when switching tabs etc.)
124-
// In real use cases, data should be pushed in when it comes.
125-
const shouldBeDataPointsCount = Math.floor((sampleRateHz * (tNow - tStart)) / 1000)
126-
const newDataPointsCount = Math.min(shouldBeDataPointsCount - pushedDataCount, 100) // Add max 100 samples per frame into a series. This prevents massive performance spikes when switching tabs for long times
127-
if (newDataPointsCount > 0) {
128-
channelList.forEach((channel, i) => {
129-
const newDataPoints = []
130-
for (let iDp = 0; iDp < newDataPointsCount; iDp++) {
131-
const iData = (pushedDataCount + iDp) % channel.data.length
132-
const sample = channel.data[iData]
133-
newDataPoints.push(sample)
134-
}
135-
channel.heatmapSeries2D.addIntensityValues(newDataPoints)
136-
channel.surfaceSeries3D.addValues({ yValues: newDataPoints })
115+
let tFirstSample
116+
const handleIncomingData = (channel, timestamp, sample) => {
117+
if (!tFirstSample) {
118+
tFirstSample = timestamp
119+
channelList.forEach((ch) => {
120+
ch.chart2D.axisX.setTickStrategy(AxisTickStrategies.DateTime, (strategy) =>
121+
strategy.setDateOrigin(new Date(tFirstSample)),
122+
)
123+
ch.chart3D.axisX.setTickStrategy(AxisTickStrategies.DateTime, (strategy) =>
124+
strategy.setDateOrigin(new Date(tFirstSample)),
125+
)
137126
})
138-
pushedDataCount += newDataPointsCount
139127
}
128+
// Calculate sample index from timestamp to place sample in correct location in heatmap.
129+
const iSample = Math.round((timestamp - tFirstSample) / heatmapMinTimeStepMs)
130+
channel.heatmapSeries2D.invalidateIntensityValues({
131+
iSample,
132+
values: [sample],
133+
})
134+
channel.surfaceSeries3D.invalidateValues({
135+
iSample,
136+
yValues: [sample],
137+
})
138+
}
139+
140+
// Setup infinite streaming from static data set.
141+
let iData = 0
142+
let tPrev = Date.now()
143+
let dModulus = 0
144+
const streamData = () => {
145+
const tNow = Date.now()
146+
let addDataPointCount = ((tNow - tPrev) * sampleRateHz) / 1000 + dModulus
147+
dModulus = addDataPointCount % 1
148+
addDataPointCount = Math.floor(addDataPointCount)
149+
channelList.forEach((channel) => {
150+
for (let i = 0; i < addDataPointCount; i += 1) {
151+
const timestamp = tPrev + ((i + 1) / addDataPointCount) * (tNow - tPrev)
152+
const sample = channel.data[(iData + i) % channel.data.length]
153+
handleIncomingData(channel, timestamp, sample)
154+
}
155+
})
156+
iData += addDataPointCount
157+
tPrev = tNow
140158
requestAnimationFrame(streamData)
141159
}
142160
streamData()
26 KB
Loading

surfaceScrollingGrid-darkGold.png

27.4 KB
Loading

surfaceScrollingGrid-light.png

40.5 KB
Loading
43.4 KB
Loading
29.4 KB
Loading

0 commit comments

Comments
 (0)