@@ -12,7 +12,7 @@ const xydata = require('@lightningchart/xydata')
1212const { createProgressiveFunctionGenerator } = xydata
1313
1414// Extract required parts from LightningChartJS.
15- const { lightningChart, SolidFill, SolidLine, AxisScrollStrategies, AxisTickStrategies, ColorRGBA, emptyFill, Themes } = lcjs
15+ const { lightningChart, SolidFill, SolidLine, AxisScrollStrategies, AxisTickStrategies, ColorRGBA, emptyFill, DataSetXY , Themes } = lcjs
1616
1717const DATA_FREQUENCY_HZ = 1000
1818const CHANNELS_AMOUNT = 10
@@ -28,7 +28,7 @@ const chart = lightningChart({
2828 . setTitle ( `Multi-channel real-time monitoring (${ CHANNELS_AMOUNT } chs, ${ DATA_FREQUENCY_HZ } Hz)` )
2929const axisX = chart
3030 . getDefaultAxisX ( )
31- . setScrollStrategy ( AxisScrollStrategies . progressive )
31+ . setScrollStrategy ( AxisScrollStrategies . scrolling )
3232 . setDefaultInterval ( ( state ) => ( { end : state . dataMax , start : ( state . dataMax ?? 0 ) - xIntervalMax , stopAxisAfter : false } ) )
3333 . setTitle ( 'Data points per channel' )
3434const axisY = chart
@@ -38,17 +38,21 @@ const axisY = chart
3838 . setScrollStrategy ( AxisScrollStrategies . expansion )
3939 . setInterval ( { start : - channelIntervalY / 2 , end : CHANNELS_AMOUNT * channelIntervalY , stopAxisAfter : false } )
4040
41+ const dataSet = new DataSetXY ( {
42+ schema : {
43+ x : { pattern : 'progressive' } ,
44+ ...Object . fromEntries ( Array . from ( { length : CHANNELS_AMOUNT } , ( _ , i ) => [ `y${ i } ` , { pattern : null } ] ) ) ,
45+ } ,
46+ } ) . setMaxSampleCount ( xIntervalMax )
47+
4148const series = new Array ( CHANNELS_AMOUNT ) . fill ( 0 ) . map ( ( _ , iChannel ) => {
4249 // Create line series optimized for regular progressive X data.
4350 const nSeries = chart
44- . addPointLineAreaSeries ( {
45- dataPattern : 'ProgressiveX' ,
46- } )
51+ . addLineSeries ( )
4752 . setName ( `Channel ${ iChannel + 1 } ` )
48- . setAreaFillStyle ( emptyFill )
4953 // Use -1 thickness for best performance, especially on low end devices like mobile / laptops.
5054 . setStrokeStyle ( ( style ) => style . setThickness ( - 1 ) )
51- . setMaxSampleCount ( xIntervalMax )
55+ . setDataSet ( dataSet , { x : 'x' , y : `y ${ iChannel } ` } )
5256
5357 // Add custom tick for each channel.
5458 chart
@@ -66,16 +70,6 @@ const series = new Array(CHANNELS_AMOUNT).fill(0).map((_, iChannel) => {
6670 return nSeries
6771} )
6872
69- // Add LegendBox.
70- chart
71- . addLegendBox ( )
72- . add ( chart )
73- // Dispose example UI elements automatically if they take too much space. This is to avoid bad UI on mobile / etc. devices.
74- . setAutoDispose ( {
75- type : 'max-width' ,
76- maxWidth : 0.3 ,
77- } )
78-
7973// Define unique signals that will be used for channels.
8074const signals = [
8175 { length : 100 * 2 * Math . PI , func : ( x ) => Math . sin ( x / 100 ) } ,
@@ -123,21 +117,22 @@ Promise.all(
123117 // In real use cases, data should be pushed in when it comes.
124118 const shouldBeDataPointsCount = Math . floor ( ( DATA_FREQUENCY_HZ * ( tNow - tStart ) ) / 1000 )
125119 const newDataPointsCount = Math . min ( shouldBeDataPointsCount - pushedDataCount , 1000 ) // Add max 1000 data points per frame into a series. This prevents massive performance spikes when switching tabs for long times
126- const seriesNewDataPoints = [ ]
127- for ( let iChannel = 0 ; iChannel < series . length ; iChannel ++ ) {
128- const dataSet = dataSets [ iChannel % dataSets . length ]
129- const newDataPoints = [ ]
130- for ( let iDp = 0 ; iDp < newDataPointsCount ; iDp ++ ) {
131- const x = ( pushedDataCount + iDp ) * xStep
120+ const newData = {
121+ x : [ ] ,
122+ ...Object . fromEntries ( Array . from ( { length : CHANNELS_AMOUNT } , ( _ , i ) => [ `y${ i } ` , [ ] ] ) ) ,
123+ }
124+ for ( let iDp = 0 ; iDp < newDataPointsCount ; iDp ++ ) {
125+ const x = ( pushedDataCount + iDp ) * xStep
126+ newData . x . push ( x )
127+ for ( let iChannel = 0 ; iChannel < series . length ; iChannel ++ ) {
128+ const dataSet = dataSets [ iChannel % dataSets . length ]
132129 const iData = ( pushedDataCount + iDp ) % dataSet . length
133130 const ySignal = dataSet [ iData ]
134131 const y = ( CHANNELS_AMOUNT - 1 - iChannel ) * channelIntervalY + ySignal
135- const point = { x, y }
136- newDataPoints . push ( point )
132+ newData [ `y${ iChannel } ` ] . push ( y )
137133 }
138- seriesNewDataPoints [ iChannel ] = newDataPoints
139134 }
140- series . forEach ( ( series , iChannel ) => series . appendJSON ( seriesNewDataPoints [ iChannel ] ) )
135+ dataSet . appendSamples ( newData )
141136 pushedDataCount += newDataPointsCount
142137 requestAnimationFrame ( streamData )
143138 }
0 commit comments