11const lcjs = require ( '@lightningchart/lcjs' )
2- const { lightningChart, Themes, AxisScrollStrategies, LUT , regularColorSteps, PalettedFill, emptyLine, synchronizeAxisIntervals, AxisTickStrategies, htmlTextRenderer, } = lcjs
2+ const {
3+ lightningChart,
4+ Themes,
5+ AxisScrollStrategies,
6+ LUT ,
7+ regularColorSteps,
8+ PalettedFill,
9+ emptyLine,
10+ synchronizeAxisIntervals,
11+ AxisTickStrategies,
12+ htmlTextRenderer,
13+ } = lcjs
314
415// General configuration for this data set
516const config = {
6- framesPerSecond : 20 ,
7- frameIntervalMs : ( 0.5 * 1000 ) / 20 ,
8- freqStartMHz : 920 ,
9- freqEndMHz : 935 ,
10- resolution : 1612 ,
11- freqStepMHz : ( 935 - 920 ) / ( 1612 - 1 ) ,
12- visibleFrameCount : 150 ,
17+ framesPerSecond : 20 ,
18+ frameIntervalMs : ( 0.5 * 1000 ) / 20 ,
19+ freqStartMHz : 920 ,
20+ freqEndMHz : 935 ,
21+ resolution : 1612 ,
22+ freqStepMHz : ( 935 - 920 ) / ( 1612 - 1 ) ,
23+ visibleFrameCount : 150 ,
1324}
1425
1526// Initialize LightningChart JS
@@ -19,9 +30,9 @@ const lc = lightningChart({
1930
2031const exampleContainer = document . getElementById ( 'chart' ) || document . body
2132if ( exampleContainer === document . body ) {
22- exampleContainer . style . width = '100vw'
23- exampleContainer . style . height = '100vh'
24- exampleContainer . style . margin = '0px'
33+ exampleContainer . style . width = '100vw'
34+ exampleContainer . style . height = '100vh'
35+ exampleContainer . style . margin = '0px'
2536}
2637exampleContainer . style . display = 'flex'
2738exampleContainer . style . flexDirection = 'column'
@@ -30,157 +41,156 @@ exampleContainer.style.flexDirection = 'column'
3041const containerChart1 = document . createElement ( 'div' )
3142exampleContainer . append ( containerChart1 )
3243const chart1 = lc
33- . ChartXY ( {
34- container : containerChart1 ,
35- defaultAxisX : { type : 'linear-highPrecision' } ,
36- defaultAxisY : { type : 'linear-highPrecision' } ,
37- textRenderer : htmlTextRenderer ,
38- theme : Themes [ new URLSearchParams ( window . location . search ) . get ( 'theme' ) || 'darkGold' ] || undefined ,
39- } )
40- . setTitle ( 'Scrolling Heatmap - No Aggregation' )
41- . setTitleMargin ( { top : 10 , bottom : 10 } )
44+ . ChartXY ( {
45+ container : containerChart1 ,
46+ defaultAxisX : { type : 'linear-highPrecision' } ,
47+ defaultAxisY : { type : 'linear-highPrecision' } ,
48+ textRenderer : htmlTextRenderer ,
49+ theme : Themes [ new URLSearchParams ( window . location . search ) . get ( 'theme' ) || 'darkGold' ] || undefined ,
50+ } )
51+ . setTitle ( 'Scrolling Heatmap - No Aggregation' )
52+ . setTitleMargin ( { top : 10 , bottom : 10 } )
4253containerChart1 . style . flex = '1'
4354
4455// Setup progressive scrolling Axis
4556chart1 . axisY
46- . setScrollStrategy ( AxisScrollStrategies . scrolling )
47- . setTitle ( 'History (Frames)' )
48- . setDefaultInterval ( ( state ) => ( {
49- start : state . dataMax ?? 0 ,
50- end : ( state . dataMax ?? 0 ) - config . visibleFrameCount ,
51- stopAxisAfter : false ,
52- } ) )
53- . setPointerEvents ( false )
54- . setTickStrategy ( AxisTickStrategies . Empty )
55- . setAnimationsEnabled ( false )
57+ . setScrollStrategy ( AxisScrollStrategies . scrolling )
58+ . setTitle ( 'History (Frames)' )
59+ . setDefaultInterval ( ( state ) => ( {
60+ start : state . dataMax ?? 0 ,
61+ end : ( state . dataMax ?? 0 ) - config . visibleFrameCount ,
62+ stopAxisAfter : false ,
63+ } ) )
64+ . setPointerEvents ( false )
65+ . setTickStrategy ( AxisTickStrategies . Empty )
66+ . setAnimationsEnabled ( false )
5667
5768chart1 . axisX
58- . setTitle ( 'Frequency' )
59- . setUnits ( 'MHz' )
60- . setInterval ( { start : config . freqStartMHz , end : config . freqEndMHz } )
61- . setPointerEvents ( false )
62- . setMarginAfterTicks ( 10 )
69+ . setTitle ( 'Frequency' )
70+ . setUnits ( 'MHz' )
71+ . setInterval ( { start : config . freqStartMHz , end : config . freqEndMHz } )
72+ . setPointerEvents ( false )
73+ . setMarginAfterTicks ( 10 )
6374
6475const theme = chart1 . getTheme ( )
6576
6677// Create Scrolling Heatmap Grid Series
6778const heatmapSeries1 = chart1
68- . addHeatmapScrollingGridSeries ( {
69- scrollDimension : 'rows' ,
70- resolution : config . resolution
71- } )
72- . setName ( " Power" )
73- . setStart ( { x : config . freqStartMHz , y : 0 } )
74- . setStep ( { x : config . freqStepMHz , y : 1 } )
75- . setWireframeStyle ( emptyLine )
76- // Configure automatic data cleaning.
77- . setDataCleaning ( {
78- // Out of view data can be lazily removed as long as total columns count remains over 1000.
79- minDataPointCount : 1000 ,
80- } )
79+ . addHeatmapScrollingGridSeries ( {
80+ scrollDimension : 'rows' ,
81+ resolution : config . resolution ,
82+ } )
83+ . setName ( ' Power' )
84+ . setStart ( { x : config . freqStartMHz , y : 0 } )
85+ . setStep ( { x : config . freqStepMHz , y : 1 } )
86+ . setWireframeStyle ( emptyLine )
87+ // Configure automatic data cleaning.
88+ . setDataCleaning ( {
89+ // Out of view data can be lazily removed as long as total columns count remains over 1000.
90+ minDataPointCount : 1000 ,
91+ } )
8192
8293// Create chart with aggregation mode set to "max"
8394const containerChart2 = document . createElement ( 'div' )
8495exampleContainer . append ( containerChart2 )
8596const chart2 = lc
86- . ChartXY ( {
87- container : containerChart2 ,
88- defaultAxisX : { type : 'linear-highPrecision' } ,
89- defaultAxisY : { type : 'linear-highPrecision' } ,
90- textRenderer : htmlTextRenderer ,
91- theme : Themes [ new URLSearchParams ( window . location . search ) . get ( 'theme' ) || 'darkGold' ] || undefined , ,
92- } )
93- . setTitle ( 'Scrolling Heatmap - Aggregation (Max)' )
94- . setTitleMargin ( { top : 10 , bottom : 10 } )
97+ . ChartXY ( {
98+ container : containerChart2 ,
99+ defaultAxisX : { type : 'linear-highPrecision' } ,
100+ defaultAxisY : { type : 'linear-highPrecision' } ,
101+ textRenderer : htmlTextRenderer ,
102+ theme : Themes [ new URLSearchParams ( window . location . search ) . get ( 'theme' ) || 'darkGold' ] || undefined , ,
103+ } )
104+ . setTitle ( 'Scrolling Heatmap - Aggregation (Max)' )
105+ . setTitleMargin ( { top : 10 , bottom : 10 } )
95106containerChart2 . style . flex = '1'
96107
97108// Setup progressive scrolling Axis
98109chart2 . axisY
99- . setScrollStrategy ( AxisScrollStrategies . scrolling )
100- . setTitle ( 'History (Frames)' )
101- . setDefaultInterval ( ( state ) => ( {
102- start : state . dataMax ?? 0 ,
103- end : ( state . dataMax ?? 0 ) - config . visibleFrameCount ,
104- stopAxisAfter : false ,
105- } ) )
106- . setPointerEvents ( false )
107- . setTickStrategy ( AxisTickStrategies . Empty )
108- . setAnimationsEnabled ( false )
109-
110+ . setScrollStrategy ( AxisScrollStrategies . scrolling )
111+ . setTitle ( 'History (Frames)' )
112+ . setDefaultInterval ( ( state ) => ( {
113+ start : state . dataMax ?? 0 ,
114+ end : ( state . dataMax ?? 0 ) - config . visibleFrameCount ,
115+ stopAxisAfter : false ,
116+ } ) )
117+ . setPointerEvents ( false )
118+ . setTickStrategy ( AxisTickStrategies . Empty )
119+ . setAnimationsEnabled ( false )
120+
110121chart2 . axisX
111- . setTitle ( 'Frequency' )
112- . setUnits ( 'MHz' )
113- . setInterval ( { start : config . freqStartMHz , end : config . freqEndMHz } )
114- . setPointerEvents ( false )
115- . setMarginAfterTicks ( 10 )
122+ . setTitle ( 'Frequency' )
123+ . setUnits ( 'MHz' )
124+ . setInterval ( { start : config . freqStartMHz , end : config . freqEndMHz } )
125+ . setPointerEvents ( false )
126+ . setMarginAfterTicks ( 10 )
116127
117128const heatmapSeries2 = chart2
118- . addHeatmapScrollingGridSeries ( {
119- scrollDimension : 'rows' ,
120- resolution : config . resolution ,
121- } )
122- . setName ( " Power" )
123- . setStart ( { x : config . freqStartMHz , y : 0 } )
124- . setStep ( { x : config . freqStepMHz , y : 1 } )
125- . setWireframeStyle ( emptyLine )
126- . setAggregation ( 'max' )
127- . setIntensityInterpolation ( 'disabled' )
128- // Configure automatic data cleaning.
129- . setDataCleaning ( {
130- // Out of view data can be lazily removed as long as total columns count remains over 1000.
131- minDataPointCount : 1000 ,
132- } )
129+ . addHeatmapScrollingGridSeries ( {
130+ scrollDimension : 'rows' ,
131+ resolution : config . resolution ,
132+ } )
133+ . setName ( ' Power' )
134+ . setStart ( { x : config . freqStartMHz , y : 0 } )
135+ . setStep ( { x : config . freqStepMHz , y : 1 } )
136+ . setWireframeStyle ( emptyLine )
137+ . setAggregation ( 'max' )
138+ . setIntensityInterpolation ( 'disabled' )
139+ // Configure automatic data cleaning.
140+ . setDataCleaning ( {
141+ // Out of view data can be lazily removed as long as total columns count remains over 1000.
142+ minDataPointCount : 1000 ,
143+ } )
133144
134145// Synchronize the intervals of the x- and y-axes
135146synchronizeAxisIntervals ( chart1 . axisX , chart2 . axisX )
136147synchronizeAxisIntervals ( chart1 . axisY , chart2 . axisY )
137148
138149const streamData = ( ) => {
139- fetch ( document . head . baseURI + 'examples/assets/1708/spectrum_920_935.json' )
140- . then ( ( r ) => r . json ( ) )
141- . then ( ( data ) => {
142- // Find min and max values of data for LUT
143- let min = data [ 0 ] [ 0 ]
144- let max = data [ 0 ] [ 0 ]
145-
146- for ( const frame of data ) {
147- for ( const v of frame ) {
148- if ( v < min ) min = v
149- if ( v > max ) max = v
150- }
151- }
152-
153- const A = Math . floor ( min )
154- const B = Math . ceil ( max )
155-
156- const lut = new LUT ( {
157- steps : regularColorSteps ( A , B , theme . examples . coldHotColorPalette ) ,
158- units : 'dBm' ,
159- interpolate : true ,
160- } )
161- const paletteFill = new PalettedFill ( { lut, lookUpProperty : 'value' } )
162- heatmapSeries1 . setFillStyle ( paletteFill )
163- heatmapSeries2 . setFillStyle ( paletteFill )
164-
165- let frameIndex = 0
166-
167- const interval = setInterval ( ( ) => {
168- if ( frameIndex >= data . length ) {
169- // Loop the data set
170- frameIndex = 0
171- }
172-
173- const sample = data [ frameIndex ]
174- heatmapSeries1 . addIntensityValues ( [ sample ] )
175- heatmapSeries2 . addIntensityValues ( [ sample ] )
176-
177- frameIndex ++
178- } , config . frameIntervalMs )
179- } )
180- . catch ( ( err ) => {
181- console . log ( err )
182- } )
150+ fetch ( document . head . baseURI + 'examples/assets/1708/spectrum_920_935.json' )
151+ . then ( ( r ) => r . json ( ) )
152+ . then ( ( data ) => {
153+ // Find min and max values of data for LUT
154+ let min = data [ 0 ] [ 0 ]
155+ let max = data [ 0 ] [ 0 ]
156+
157+ for ( const frame of data ) {
158+ for ( const v of frame ) {
159+ if ( v < min ) min = v
160+ if ( v > max ) max = v
161+ }
162+ }
163+
164+ const A = Math . floor ( min )
165+ const B = Math . ceil ( max )
166+
167+ const lut = new LUT ( {
168+ steps : regularColorSteps ( A , B , theme . examples . coldHotColorPalette ) ,
169+ units : 'dBm' ,
170+ interpolate : true ,
171+ } )
172+ const paletteFill = new PalettedFill ( { lut, lookUpProperty : 'value' } )
173+ heatmapSeries1 . setFillStyle ( paletteFill )
174+ heatmapSeries2 . setFillStyle ( paletteFill )
175+
176+ let frameIndex = 0
177+
178+ const interval = setInterval ( ( ) => {
179+ if ( frameIndex >= data . length ) {
180+ // Loop the data set
181+ frameIndex = 0
182+ }
183+
184+ const sample = data [ frameIndex ]
185+ heatmapSeries1 . addIntensityValues ( [ sample ] )
186+ heatmapSeries2 . addIntensityValues ( [ sample ] )
187+
188+ frameIndex ++
189+ } , config . frameIntervalMs )
190+ } )
191+ . catch ( ( err ) => {
192+ console . log ( err )
193+ } )
183194}
184195
185196streamData ( )
186-
0 commit comments