()
| 134 | // Streaming loop: append small batches frequently. |
| 135 | let intervalId: number | null = null; |
| 136 | const startStreaming = (): void => { |
| 137 | if (intervalId !== null) return; |
| 138 | intervalId = window.setInterval(() => { |
| 139 | const batch: DataPoint[] = new Array(streamCfg.pointsPerTick); |
| 140 | for (let i = 0; i < streamCfg.pointsPerTick; i++) { |
| 141 | nextX += 0.02; |
| 142 | const y = |
| 143 | Math.sin(nextX) * 0.8 + |
| 144 | Math.sin(nextX * 0.23 + 1.2) * 0.25 + |
| 145 | Math.sin(nextX * 2.1) * 0.08 + |
| 146 | (Math.random() - 0.5) * 0.04; |
| 147 | batch[i] = [nextX, y] as const; |
| 148 | } |
| 149 | |
| 150 | chart.appendData(0, batch); |
| 151 | rawData.push(...batch); |
| 152 | |
| 153 | // Keep the example bounded: periodically re-seed the chart with a sliding window. |
| 154 | // This keeps memory stable while still exercising streaming + autoScroll behavior. |
| 155 | if (rawData.length > streamCfg.maxPoints) { |
| 156 | rawData = rawData.slice(rawData.length - streamCfg.maxPoints); |
| 157 | applyOptions(); |
| 158 | } |
| 159 | }, streamCfg.tickMs); |
| 160 | }; |
| 161 | |
| 162 | const stopStreaming = (): void => { |
| 163 | if (intervalId === null) return; |
no test coverage detected