@@ -93,36 +93,6 @@ export function toDate(time: number) {
93
93
return new Date ( time * 1000 )
94
94
}
95
95
96
- function smoothSeries ( series : PointValue [ ] , windowSize : number ) : PointValue [ ] {
97
- let result : PointValue [ ] = [ ]
98
- windowSize = ~ ~ windowSize
99
- if ( series . length < windowSize ) {
100
- windowSize = series . length
101
- }
102
- let extraWindow = windowSize / 2
103
- extraWindow = ~ ~ extraWindow
104
-
105
-
106
- let count = 0
107
- let total = 0
108
-
109
- for ( let i = 0 ; i < series . length + extraWindow ; i ++ ) {
110
- let j = i - extraWindow
111
- if ( i < series . length ) {
112
- total += series [ i ] . value
113
- count ++
114
- }
115
- if ( j - extraWindow - 1 >= 0 ) {
116
- total -= series [ j - extraWindow - 1 ] . value
117
- count --
118
- }
119
- if ( j >= 0 ) {
120
- result . push ( { step : series [ j ] . step , value : series [ j ] . value , smoothed : total / count , lastStep : series [ j ] . lastStep } )
121
- }
122
- }
123
- return result
124
- }
125
-
126
96
export function fillPlotPreferences ( series : Indicator [ ] , currentPlotIdx : number [ ] = [ ] ) {
127
97
if ( currentPlotIdx . length != 0 ) {
128
98
if ( currentPlotIdx . length == series . length ) {
@@ -213,57 +183,6 @@ export function smoothAndTrimAllCharts(series: Indicator[], baseSeries: Indicato
213
183
}
214
184
}
215
185
216
- function trimSteps ( series : Indicator [ ] , min : number , max : number , smoothWindow : number [ ] , trimSmoothEnds : boolean = true ) {
217
- series . forEach ( ( s , i ) => {
218
- let localSmoothWindow = smoothWindow [ i ] / 2 // remove half from each end
219
- localSmoothWindow = Math . floor ( localSmoothWindow )
220
- if ( localSmoothWindow < 0 ) {
221
- localSmoothWindow = 0
222
- }
223
- if ( s . series . length <= 1 ) {
224
- localSmoothWindow = 0
225
- } else if ( smoothWindow [ i ] >= s . series . length ) {
226
- localSmoothWindow = Math . floor ( s . series . length / 2 )
227
- }
228
-
229
-
230
- let localMin = min
231
- let localMax = max
232
-
233
- if ( localMin == - 1 ) {
234
- localMin = s . series [ 0 ] . step
235
- }
236
- if ( trimSmoothEnds ) {
237
- localMin = Math . max ( localMin , s . series [ localSmoothWindow ] . step )
238
- }
239
-
240
- if ( localMax == - 1 ) {
241
- localMax = s . series [ s . series . length - 1 ] . step
242
- }
243
- if ( trimSmoothEnds ) {
244
- localMax = Math . min ( localMax , s . series [ s . series . length - 1 - localSmoothWindow +
245
- ( s . series . length % 2 == 0 && localSmoothWindow != 0 ? 1 : 0 ) ] . step ) // get the mid value for even length series
246
- }
247
-
248
- localMin = Math . floor ( localMin - 1 )
249
- localMax = Math . ceil ( localMax + 1 )
250
-
251
- let minIndex = s . series . length - 1
252
- let maxIndex = 0
253
-
254
- for ( let i = 0 ; i < s . series . length ; i ++ ) {
255
- let p = s . series [ i ]
256
- if ( p . step >= localMin && p . step <= localMax ) {
257
- minIndex = Math . min ( i , minIndex )
258
- maxIndex = Math . max ( i , maxIndex )
259
- }
260
- }
261
-
262
- s . lowTrimIndex = minIndex
263
- s . highTrimIndex = maxIndex
264
- } )
265
- }
266
-
267
186
/**
268
187
* Calculates the smooth window size for each series in the current and base series.
269
188
* The smooth window size is determined based on the minimum range of steps in the series and the provided smooth value.
@@ -274,7 +193,7 @@ function trimSteps(series: Indicator[], min: number, max: number, smoothWindow:
274
193
* @returns {[number[][], number] } - Returns an array of smooth window sizes for each series. and the smooth window size in steps.
275
194
* (ret[0] = smooth window for current series, ret[1] = smooth window for base series
276
195
*/
277
- export function getSmoothWindow ( currentSeries : Indicator [ ] , baseSeries : Indicator [ ] , smoothValue : number ) : [ number [ ] [ ] , number ] {
196
+ function getSmoothWindow ( currentSeries : Indicator [ ] , baseSeries : Indicator [ ] , smoothValue : number ) : [ number [ ] [ ] , number ] {
278
197
let maxRange : number = Number . MIN_SAFE_INTEGER
279
198
for ( let s of currentSeries ) {
280
199
if ( s . series . length > 1 && ! s . is_summary ) {
@@ -286,7 +205,7 @@ export function getSmoothWindow(currentSeries: Indicator[], baseSeries: Indicato
286
205
maxRange = Math . max ( maxRange , s . series [ s . series . length - 1 ] . step - s . series [ 0 ] . step )
287
206
}
288
207
}
289
- if ( maxRange == Number . MIN_SAFE_INTEGER ) {
208
+ if ( maxRange == Number . MIN_SAFE_INTEGER ) { // all single points. -> can't smooth
290
209
let stepRange = [ [ ] , [ ] ]
291
210
for ( let s of currentSeries ) {
292
211
stepRange [ 0 ] . push ( 1 )
@@ -297,35 +216,108 @@ export function getSmoothWindow(currentSeries: Indicator[], baseSeries: Indicato
297
216
return [ stepRange , 0 ]
298
217
}
299
218
300
- let smoothRange = mapRange ( smoothValue , 1 , 100 , 1 , maxRange )
219
+ let smoothRange = mapRange ( smoothValue , 1 , 100 , 1 , 2 * maxRange )
301
220
302
221
let stepRange = [ [ ] , [ ] ]
222
+
303
223
for ( let s of currentSeries ) {
304
- if ( smoothValue == 100 ) { // hardcode to max range in case not range due to step inconsistencies
305
- stepRange [ 0 ] . push ( s . series . length )
306
- } else if ( s . series . length >= 2 && ! s . is_summary ) {
224
+ if ( s . series . length >= 2 && ! s . is_summary ) {
307
225
let stepGap = s . series [ 1 ] . step - s . series [ 0 ] . step
308
- let numSteps = Math . max ( 1 , Math . floor ( smoothRange / stepGap ) )
226
+ let numSteps = Math . max ( 1 , Math . ceil ( smoothRange / stepGap ) )
309
227
stepRange [ 0 ] . push ( numSteps )
310
- } else {
228
+ } else { // can't smooth - just a single point
311
229
stepRange [ 0 ] . push ( 1 )
312
230
}
313
231
}
232
+
314
233
for ( let s of baseSeries ) {
315
- if ( smoothValue == 100 ) {
316
- stepRange [ 1 ] . push ( s . series . length )
317
- } else if ( s . series . length >= 2 && ! s . is_summary ) {
234
+ if ( s . series . length >= 2 && ! s . is_summary ) {
318
235
let stepGap = s . series [ 1 ] . step - s . series [ 0 ] . step
319
- let numSteps = Math . max ( 1 , Math . floor ( smoothRange / stepGap ) )
236
+ let numSteps = Math . max ( 1 , Math . ceil ( smoothRange / stepGap ) )
320
237
stepRange [ 1 ] . push ( numSteps )
321
- } else {
238
+ } else { // can't smooth - just a single point
322
239
stepRange [ 1 ] . push ( 1 )
323
240
}
324
241
}
325
242
326
243
return [ stepRange , smoothRange ]
327
244
}
328
245
246
+ function smoothSeries ( series : PointValue [ ] , windowSize : number ) : PointValue [ ] {
247
+ let result : PointValue [ ] = [ ]
248
+ windowSize = ~ ~ windowSize
249
+ let extraWindow = windowSize / 2
250
+ extraWindow = ~ ~ extraWindow
251
+
252
+
253
+ let count = 0
254
+ let total = 0
255
+
256
+ for ( let i = 0 ; i < series . length + extraWindow ; i ++ ) {
257
+ let j = i - extraWindow
258
+ if ( i < series . length ) {
259
+ total += series [ i ] . value
260
+ count ++
261
+ }
262
+ if ( j - extraWindow - 1 >= 0 ) {
263
+ total -= series [ j - extraWindow - 1 ] . value
264
+ count --
265
+ }
266
+ if ( j >= 0 ) {
267
+ result . push ( { step : series [ j ] . step , value : series [ j ] . value , smoothed : total / count , lastStep : series [ j ] . lastStep } )
268
+ }
269
+ }
270
+ return result
271
+ }
272
+
273
+
274
+ function trimSteps ( series : Indicator [ ] , min : number , max : number , smoothWindow : number [ ] , trimSmoothEnds : boolean = true ) {
275
+ series . forEach ( ( s , i ) => {
276
+ let localSmoothWindow = Math . floor ( smoothWindow [ i ] / 2 ) // remove half from each end
277
+
278
+ if ( s . series . length <= 1 ) {
279
+ localSmoothWindow = 0
280
+ } else if ( smoothWindow [ i ] >= s . series . length ) {
281
+ localSmoothWindow = Math . floor ( s . series . length / 2 )
282
+ }
283
+
284
+ let localMin = min
285
+ let localMax = max
286
+
287
+ if ( localMin == - 1 ) {
288
+ localMin = s . series [ 0 ] . step
289
+ }
290
+ if ( trimSmoothEnds ) {
291
+ localMin = Math . max ( localMin , s . series [ localSmoothWindow ] . step )
292
+ }
293
+
294
+ if ( localMax == - 1 ) {
295
+ localMax = s . series [ s . series . length - 1 ] . step
296
+ }
297
+ if ( trimSmoothEnds ) {
298
+ localMax = Math . min ( localMax , s . series [ s . series . length - 1 - localSmoothWindow +
299
+ ( s . series . length % 2 == 0 && localSmoothWindow != 0 ? 1 : 0 ) ] . step ) // get the mid value for even length series
300
+ }
301
+
302
+ localMin = Math . floor ( localMin ) - 0.5
303
+ localMax = Math . ceil ( localMax ) + 0.5
304
+
305
+ let minIndex = s . series . length - 1
306
+ let maxIndex = 0
307
+
308
+ for ( let i = 0 ; i < s . series . length ; i ++ ) {
309
+ let p = s . series [ i ]
310
+ if ( p . step >= localMin && p . step <= localMax ) {
311
+ minIndex = Math . min ( i , minIndex )
312
+ maxIndex = Math . max ( i , maxIndex )
313
+ }
314
+ }
315
+
316
+ s . lowTrimIndex = minIndex
317
+ s . highTrimIndex = maxIndex
318
+ } )
319
+ }
320
+
329
321
// Default smoothing function from backend
330
322
function meanAngle ( smoothed : PointValue [ ] , aspectRatio : number ) {
331
323
let xRange = smoothed [ smoothed . length - 1 ] . lastStep - smoothed [ 0 ] . lastStep
0 commit comments