(tick: Tick)
| 161 | } |
| 162 | |
| 163 | function handleTick(tick: Tick) { |
| 164 | // Advance simulated time (so we can close candles faster than real time). |
| 165 | const now = performance.now(); |
| 166 | const dtRealMs = Math.max(0, now - lastSimPerfNow); |
| 167 | lastSimPerfNow = now; |
| 168 | simulatedTimeMs += dtRealMs * timeScale; |
| 169 | |
| 170 | // Drive the candle aggregator from ticks, but using simulated time. |
| 171 | candleAggregator.processTick({ ...tick, timestamp: Math.floor(simulatedTimeMs) }); |
| 172 | |
| 173 | // Update the current (forming) candle in real-time. |
| 174 | const currentCandle = candleAggregator.getCurrentCandle(); |
| 175 | if (currentCandle) { |
| 176 | const isSameCandle = data.length > 0 && getTimestamp(data[data.length - 1]) === getTimestamp(currentCandle); |
| 177 | |
| 178 | if (isSameCandle) { |
| 179 | // Update existing (forming) candle |
| 180 | data[data.length - 1] = currentCandle; |
| 181 | |
| 182 | // Throttled update for current candle (every ~100ms) |
| 183 | throttledUpdateCurrentCandle(); |
| 184 | } else { |
| 185 | // New candle period started — append the new candle once, then update it as it forms. |
| 186 | data.push(currentCandle); |
| 187 | |
| 188 | // Memory management: trim old candles |
| 189 | const maxCandles = getMaxCandles(currentCandleCount); |
| 190 | if (data.length > maxCandles) { |
| 191 | data = data.slice(data.length - maxCandles); |
| 192 | // Preserve full options when trimming data |
| 193 | const series0 = fullChartOptions.series?.[0]; |
| 194 | if (series0 && series0.type === 'candlestick') { |
| 195 | fullChartOptions = { |
| 196 | ...fullChartOptions, |
| 197 | series: [ |
| 198 | { |
| 199 | ...series0, |
| 200 | data, |
| 201 | }, |
| 202 | ], |
| 203 | }; |
| 204 | chart.setOption(fullChartOptions); |
| 205 | } |
| 206 | } else { |
| 207 | // Efficient append (candlesticks supported) |
| 208 | chart.appendData(0, [currentCandle]); |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | updatePrice(tick.price); |
| 214 | } |
| 215 | |
| 216 | // Throttle current candle updates to avoid overwhelming the GPU |
| 217 | let lastCurrentCandleUpdate = 0; |
nothing calls this directly
no test coverage detected