hyperprop-charting-library 0.1.106 → 0.1.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1072,7 +1072,7 @@ function createChart(element, options = {}) {
1072
1072
  if (Math.abs(priceDiff) < 1e-9 && Math.abs(volumeDiff) < 1e-6) {
1073
1073
  smoothedTickerPrice = tickerPriceTarget;
1074
1074
  smoothedTickerVolume = tickerVolumeTarget;
1075
- draw({ updateAutoScale: false });
1075
+ scheduleDraw({ updateAutoScale: false });
1076
1076
  return;
1077
1077
  }
1078
1078
  const tickerOpts = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -1081,7 +1081,7 @@ function createChart(element, options = {}) {
1081
1081
  const lerp = 1 - Math.exp(-speed * dt);
1082
1082
  smoothedTickerPrice += priceDiff * lerp;
1083
1083
  smoothedTickerVolume += volumeDiff * lerp;
1084
- draw({ updateAutoScale: false });
1084
+ scheduleDraw({ updateAutoScale: false });
1085
1085
  smoothingRafId = requestAnimationFrame(tickerSmoothingLoop);
1086
1086
  };
1087
1087
  const pushSmoothedTicker = (targetPrice, targetVolume) => {
@@ -1146,7 +1146,7 @@ function createChart(element, options = {}) {
1146
1146
  image.onload = () => {
1147
1147
  watermarkImage = image;
1148
1148
  watermarkImageReady = true;
1149
- draw();
1149
+ scheduleDraw();
1150
1150
  };
1151
1151
  image.onerror = () => {
1152
1152
  watermarkImage = null;
@@ -1909,7 +1909,21 @@ function createChart(element, options = {}) {
1909
1909
  }
1910
1910
  }
1911
1911
  crosshairPoint = point;
1912
- draw();
1912
+ scheduleDraw();
1913
+ };
1914
+ let drawRafId = null;
1915
+ let pendingDrawUpdateAutoScale = false;
1916
+ const scheduleDraw = (options2 = {}) => {
1917
+ pendingDrawUpdateAutoScale = pendingDrawUpdateAutoScale || (options2.updateAutoScale ?? true);
1918
+ if (drawRafId !== null) {
1919
+ return;
1920
+ }
1921
+ drawRafId = requestAnimationFrame(() => {
1922
+ drawRafId = null;
1923
+ const updateAutoScale = pendingDrawUpdateAutoScale;
1924
+ pendingDrawUpdateAutoScale = false;
1925
+ draw({ updateAutoScale });
1926
+ });
1913
1927
  };
1914
1928
  const draw = (options2 = {}) => {
1915
1929
  const shouldUpdateAutoScale = options2.updateAutoScale ?? true;
@@ -3638,7 +3652,7 @@ function createChart(element, options = {}) {
3638
3652
  clampXViewport();
3639
3653
  updateFollowLatest(false);
3640
3654
  emitViewportChange();
3641
- draw();
3655
+ scheduleDraw();
3642
3656
  };
3643
3657
  const zoomXToLatest = (factor) => {
3644
3658
  if (!drawState || data.length === 0) {
@@ -3653,7 +3667,7 @@ function createChart(element, options = {}) {
3653
3667
  xCenter = nextStart + nextSpan / 2;
3654
3668
  clampXViewport();
3655
3669
  emitViewportChange();
3656
- draw();
3670
+ scheduleDraw();
3657
3671
  };
3658
3672
  const zoomXFromAxis = (factor) => {
3659
3673
  if (!drawState) {
@@ -3684,7 +3698,7 @@ function createChart(element, options = {}) {
3684
3698
  yMinOverride = clamped.min;
3685
3699
  yMaxOverride = clamped.max;
3686
3700
  emitViewportChange();
3687
- draw();
3701
+ scheduleDraw();
3688
3702
  };
3689
3703
  const pan = (deltaX, deltaY, allowX, allowY) => {
3690
3704
  if (!drawState || data.length === 0) {
@@ -3710,7 +3724,7 @@ function createChart(element, options = {}) {
3710
3724
  if (allowX || allowY) {
3711
3725
  emitViewportChange();
3712
3726
  }
3713
- draw();
3727
+ scheduleDraw();
3714
3728
  };
3715
3729
  const resetYViewport = () => {
3716
3730
  yMinOverride = null;
@@ -3750,7 +3764,7 @@ function createChart(element, options = {}) {
3750
3764
  clampXViewport();
3751
3765
  updateFollowLatest(false);
3752
3766
  emitViewportChange();
3753
- draw();
3767
+ scheduleDraw();
3754
3768
  };
3755
3769
  const panY = (priceDelta) => {
3756
3770
  if (!drawState || !Number.isFinite(priceDelta) || priceDelta === 0) {
@@ -3762,20 +3776,20 @@ function createChart(element, options = {}) {
3762
3776
  yMinOverride = clamped.min;
3763
3777
  yMaxOverride = clamped.max;
3764
3778
  emitViewportChange();
3765
- draw();
3779
+ scheduleDraw();
3766
3780
  };
3767
3781
  const fitContent = () => {
3768
3782
  fitXViewport();
3769
3783
  updateFollowLatest(true);
3770
3784
  emitViewportChange();
3771
- draw();
3785
+ scheduleDraw();
3772
3786
  };
3773
3787
  const resetViewport = () => {
3774
3788
  fitXViewport();
3775
3789
  resetYViewport();
3776
3790
  updateFollowLatest(true);
3777
3791
  emitViewportChange();
3778
- draw();
3792
+ scheduleDraw();
3779
3793
  };
3780
3794
  const isFollowingLatest = () => followLatest;
3781
3795
  const setFollowingLatest = (follow) => {
@@ -3783,7 +3797,7 @@ function createChart(element, options = {}) {
3783
3797
  xCenter = data.length - xSpan / 2 + rightEdgePaddingBars;
3784
3798
  clampXViewport();
3785
3799
  updateFollowLatest(true);
3786
- draw();
3800
+ scheduleDraw();
3787
3801
  } else {
3788
3802
  updateFollowLatest(follow);
3789
3803
  }
@@ -3842,7 +3856,7 @@ function createChart(element, options = {}) {
3842
3856
  }
3843
3857
  if (changed) {
3844
3858
  clampXViewport();
3845
- draw();
3859
+ scheduleDraw();
3846
3860
  emitViewportChange();
3847
3861
  }
3848
3862
  };
@@ -4219,7 +4233,7 @@ function createChart(element, options = {}) {
4219
4233
  })
4220
4234
  );
4221
4235
  emitDrawingsChange();
4222
- draw();
4236
+ scheduleDraw();
4223
4237
  return true;
4224
4238
  }
4225
4239
  if (activeDrawingTool === "vertical-line") {
@@ -4234,7 +4248,7 @@ function createChart(element, options = {}) {
4234
4248
  })
4235
4249
  );
4236
4250
  emitDrawingsChange();
4237
- draw();
4251
+ scheduleDraw();
4238
4252
  return true;
4239
4253
  }
4240
4254
  if (activeDrawingTool === "trendline") {
@@ -4249,7 +4263,7 @@ function createChart(element, options = {}) {
4249
4263
  draftDrawing = null;
4250
4264
  activeDrawingTool = null;
4251
4265
  emitDrawingsChange();
4252
- draw();
4266
+ scheduleDraw();
4253
4267
  return true;
4254
4268
  }
4255
4269
  const defaults = getDrawingToolDefaults("trendline");
@@ -4260,7 +4274,7 @@ function createChart(element, options = {}) {
4260
4274
  style: defaults.style ?? "solid",
4261
4275
  width: defaults.width ?? 2
4262
4276
  });
4263
- draw();
4277
+ scheduleDraw();
4264
4278
  return true;
4265
4279
  }
4266
4280
  if (activeDrawingTool === "ray") {
@@ -4275,7 +4289,7 @@ function createChart(element, options = {}) {
4275
4289
  draftDrawing = null;
4276
4290
  activeDrawingTool = null;
4277
4291
  emitDrawingsChange();
4278
- draw();
4292
+ scheduleDraw();
4279
4293
  return true;
4280
4294
  }
4281
4295
  const defaults = getDrawingToolDefaults("ray");
@@ -4286,7 +4300,7 @@ function createChart(element, options = {}) {
4286
4300
  style: defaults.style ?? "solid",
4287
4301
  width: defaults.width ?? 2
4288
4302
  });
4289
- draw();
4303
+ scheduleDraw();
4290
4304
  return true;
4291
4305
  }
4292
4306
  if (activeDrawingTool === "fib-retracement") {
@@ -4299,7 +4313,7 @@ function createChart(element, options = {}) {
4299
4313
  draftDrawing = null;
4300
4314
  activeDrawingTool = null;
4301
4315
  emitDrawingsChange();
4302
- draw();
4316
+ scheduleDraw();
4303
4317
  return true;
4304
4318
  }
4305
4319
  const defaults = getDrawingToolDefaults("fib-retracement");
@@ -4311,7 +4325,7 @@ function createChart(element, options = {}) {
4311
4325
  style: defaults.style ?? "solid",
4312
4326
  width: defaults.width ?? 1
4313
4327
  });
4314
- draw();
4328
+ scheduleDraw();
4315
4329
  return true;
4316
4330
  }
4317
4331
  if (activeDrawingTool === "fib-extension") {
@@ -4321,7 +4335,7 @@ function createChart(element, options = {}) {
4321
4335
  ...serializeDrawing(draftDrawing),
4322
4336
  points: [...draftDrawing.points.slice(0, -1), point, point]
4323
4337
  });
4324
- draw();
4338
+ scheduleDraw();
4325
4339
  return true;
4326
4340
  }
4327
4341
  const completed = normalizeDrawingState({
@@ -4332,7 +4346,7 @@ function createChart(element, options = {}) {
4332
4346
  draftDrawing = null;
4333
4347
  activeDrawingTool = null;
4334
4348
  emitDrawingsChange();
4335
- draw();
4349
+ scheduleDraw();
4336
4350
  return true;
4337
4351
  }
4338
4352
  const defaults = getDrawingToolDefaults("fib-extension");
@@ -4344,7 +4358,7 @@ function createChart(element, options = {}) {
4344
4358
  style: defaults.style ?? "solid",
4345
4359
  width: defaults.width ?? 1
4346
4360
  });
4347
- draw();
4361
+ scheduleDraw();
4348
4362
  return true;
4349
4363
  }
4350
4364
  if (activeDrawingTool === "text" || activeDrawingTool === "note") {
@@ -4361,7 +4375,7 @@ function createChart(element, options = {}) {
4361
4375
  drawings.push(created);
4362
4376
  selectedDrawingId = created.id;
4363
4377
  emitDrawingsChange();
4364
- draw();
4378
+ scheduleDraw();
4365
4379
  drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
4366
4380
  return true;
4367
4381
  }
@@ -4381,7 +4395,7 @@ function createChart(element, options = {}) {
4381
4395
  })
4382
4396
  );
4383
4397
  emitDrawingsChange();
4384
- draw();
4398
+ scheduleDraw();
4385
4399
  return true;
4386
4400
  }
4387
4401
  if (activeDrawingTool === "long-position" || activeDrawingTool === "short-position") {
@@ -4417,7 +4431,7 @@ function createChart(element, options = {}) {
4417
4431
  })
4418
4432
  );
4419
4433
  emitDrawingsChange();
4420
- draw();
4434
+ scheduleDraw();
4421
4435
  return true;
4422
4436
  }
4423
4437
  return false;
@@ -4434,7 +4448,7 @@ function createChart(element, options = {}) {
4434
4448
  return;
4435
4449
  }
4436
4450
  selectedDrawingId = id;
4437
- draw();
4451
+ scheduleDraw();
4438
4452
  };
4439
4453
  const updateDrawingDrag = (x, y) => {
4440
4454
  if (!drawingDragState) {
@@ -4493,7 +4507,7 @@ function createChart(element, options = {}) {
4493
4507
  };
4494
4508
  });
4495
4509
  emitDrawingsChange();
4496
- draw();
4510
+ scheduleDraw();
4497
4511
  return true;
4498
4512
  };
4499
4513
  let isDragging = false;
@@ -4558,7 +4572,7 @@ function createChart(element, options = {}) {
4558
4572
  clampXViewport();
4559
4573
  updateFollowLatest(false);
4560
4574
  emitViewportChange();
4561
- draw();
4575
+ scheduleDraw();
4562
4576
  };
4563
4577
  const onPointerDown = (event) => {
4564
4578
  if (event.pointerType === "touch" || event.pointerType === "pen") {
@@ -4665,7 +4679,7 @@ function createChart(element, options = {}) {
4665
4679
  isDragging = true;
4666
4680
  dragMode = region;
4667
4681
  activePointerId = event.pointerId;
4668
- const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
4682
+ const crosshairDrag = false;
4669
4683
  pointerDownInfo = {
4670
4684
  pointerId: event.pointerId,
4671
4685
  pointerType: event.pointerType,
@@ -4742,7 +4756,7 @@ function createChart(element, options = {}) {
4742
4756
  points: [...draftDrawing.points.slice(0, -1), nextPoint]
4743
4757
  };
4744
4758
  canvas.style.cursor = "crosshair";
4745
- draw();
4759
+ scheduleDraw();
4746
4760
  return;
4747
4761
  }
4748
4762
  }
@@ -4770,7 +4784,7 @@ function createChart(element, options = {}) {
4770
4784
  dragging: true,
4771
4785
  ...currentLine ? { line: currentLine } : {}
4772
4786
  });
4773
- draw();
4787
+ scheduleDraw();
4774
4788
  }
4775
4789
  canvas.style.cursor = "ns-resize";
4776
4790
  setCrosshairPoint(null);
@@ -5032,7 +5046,7 @@ function createChart(element, options = {}) {
5032
5046
  }
5033
5047
  if (region === "y-axis") {
5034
5048
  resetYViewport();
5035
- draw();
5049
+ scheduleDraw();
5036
5050
  return;
5037
5051
  }
5038
5052
  resetViewport();
@@ -5054,7 +5068,7 @@ function createChart(element, options = {}) {
5054
5068
  const changed = active !== magnetModifierActive || shift !== shiftKeyActive;
5055
5069
  magnetModifierActive = active;
5056
5070
  shiftKeyActive = shift;
5057
- if (changed && draftDrawing) draw();
5071
+ if (changed && draftDrawing) scheduleDraw();
5058
5072
  };
5059
5073
  const onWindowBlurMagnet = () => {
5060
5074
  magnetModifierActive = false;
@@ -5090,7 +5104,7 @@ function createChart(element, options = {}) {
5090
5104
  const lastPoint = data[data.length - 1];
5091
5105
  pushSmoothedTicker(lastPoint.c, lastPoint.v);
5092
5106
  }
5093
- draw();
5107
+ scheduleDraw();
5094
5108
  };
5095
5109
  const resize = (nextWidth, nextHeight) => {
5096
5110
  if (nextWidth && nextWidth > 0) {
@@ -5101,7 +5115,7 @@ function createChart(element, options = {}) {
5101
5115
  }
5102
5116
  mergedOptions = { ...mergedOptions, width, height };
5103
5117
  resetRightMarginCache();
5104
- draw();
5118
+ scheduleDraw();
5105
5119
  };
5106
5120
  const setData = (nextData) => {
5107
5121
  const hadData = data.length > 0;
@@ -5119,7 +5133,7 @@ function createChart(element, options = {}) {
5119
5133
  tickerVolumeTarget = null;
5120
5134
  resetRightMarginCache();
5121
5135
  resetYViewport();
5122
- draw();
5136
+ scheduleDraw();
5123
5137
  return;
5124
5138
  }
5125
5139
  if (!hadData) {
@@ -5144,7 +5158,7 @@ function createChart(element, options = {}) {
5144
5158
  if (lastPoint) {
5145
5159
  pushSmoothedTicker(lastPoint.c, lastPoint.v);
5146
5160
  }
5147
- draw();
5161
+ scheduleDraw();
5148
5162
  };
5149
5163
  const setPriceLines = (lines) => {
5150
5164
  priceLines = lines.map((line, index) => ({
@@ -5152,18 +5166,18 @@ function createChart(element, options = {}) {
5152
5166
  id: line.id ?? `line-${index + 1}`
5153
5167
  }));
5154
5168
  resetRightMarginCache();
5155
- draw();
5169
+ scheduleDraw();
5156
5170
  };
5157
5171
  const addPriceLine = (line) => {
5158
5172
  const id = line.id ?? `line-${generatedPriceLineId++}`;
5159
5173
  priceLines.push({ ...line, id });
5160
- draw();
5174
+ scheduleDraw();
5161
5175
  return id;
5162
5176
  };
5163
5177
  const removePriceLine = (id) => {
5164
5178
  priceLines = priceLines.filter((line) => line.id !== id);
5165
5179
  resetRightMarginCache();
5166
- draw();
5180
+ scheduleDraw();
5167
5181
  };
5168
5182
  const setOrderLines = (lines) => {
5169
5183
  orderLines = lines.map((line, index) => ({
@@ -5182,24 +5196,24 @@ function createChart(element, options = {}) {
5182
5196
  orderPriceTagWidthById.delete(id);
5183
5197
  }
5184
5198
  }
5185
- draw();
5199
+ scheduleDraw();
5186
5200
  };
5187
5201
  const addOrderLine = (line) => {
5188
5202
  const id = line.id ?? `order-${generatedOrderLineId++}`;
5189
5203
  orderLines.push({ ...line, id });
5190
- draw();
5204
+ scheduleDraw();
5191
5205
  return id;
5192
5206
  };
5193
5207
  const updateOrderLine = (id, patch) => {
5194
5208
  orderLines = orderLines.map((line) => line.id === id ? { ...line, ...patch, id } : line);
5195
- draw();
5209
+ scheduleDraw();
5196
5210
  };
5197
5211
  const removeOrderLine = (id) => {
5198
5212
  orderLines = orderLines.filter((line) => line.id !== id);
5199
5213
  orderWidgetWidthById.delete(id);
5200
5214
  orderPriceTagWidthById.delete(id);
5201
5215
  resetRightMarginCache();
5202
- draw();
5216
+ scheduleDraw();
5203
5217
  };
5204
5218
  const onOrderAction = (handler) => {
5205
5219
  orderActionHandler = handler;
@@ -5224,12 +5238,12 @@ function createChart(element, options = {}) {
5224
5238
  throw new Error("Invalid indicator plugin. Expected { id, draw }.");
5225
5239
  }
5226
5240
  indicatorRegistry.set(plugin.id, plugin);
5227
- draw();
5241
+ scheduleDraw();
5228
5242
  };
5229
5243
  const unregisterIndicator = (type) => {
5230
5244
  indicatorRegistry.delete(type);
5231
5245
  indicators = indicators.filter((indicator) => indicator.type !== type);
5232
- draw();
5246
+ scheduleDraw();
5233
5247
  };
5234
5248
  const listBuiltInIndicators = () => {
5235
5249
  return BUILTIN_INDICATORS.map((indicator) => ({
@@ -5254,7 +5268,7 @@ function createChart(element, options = {}) {
5254
5268
  };
5255
5269
  const setIndicators = (nextIndicators) => {
5256
5270
  indicators = nextIndicators.map((indicator) => normalizeIndicatorState(indicator));
5257
- draw();
5271
+ scheduleDraw();
5258
5272
  };
5259
5273
  const addIndicator = (type, inputs = {}, options2 = {}) => {
5260
5274
  const plugin = indicatorRegistry.get(type);
@@ -5267,7 +5281,7 @@ function createChart(element, options = {}) {
5267
5281
  inputs
5268
5282
  });
5269
5283
  indicators.push(next);
5270
- draw();
5284
+ scheduleDraw();
5271
5285
  return next.id;
5272
5286
  };
5273
5287
  const updateIndicator = (id, patch) => {
@@ -5291,30 +5305,30 @@ function createChart(element, options = {}) {
5291
5305
  }
5292
5306
  };
5293
5307
  });
5294
- draw();
5308
+ scheduleDraw();
5295
5309
  };
5296
5310
  const removeIndicator = (id) => {
5297
5311
  indicators = indicators.filter((indicator) => indicator.id !== id);
5298
- draw();
5312
+ scheduleDraw();
5299
5313
  };
5300
5314
  const setActiveDrawingTool = (tool) => {
5301
5315
  activeDrawingTool = tool;
5302
5316
  draftDrawing = null;
5303
5317
  canvas.style.cursor = tool ? "crosshair" : "default";
5304
- draw();
5318
+ scheduleDraw();
5305
5319
  };
5306
5320
  const getActiveDrawingTool = () => activeDrawingTool;
5307
5321
  const cancelDrawing = () => {
5308
5322
  if (draftDrawing) {
5309
5323
  draftDrawing = null;
5310
- draw();
5324
+ scheduleDraw();
5311
5325
  return true;
5312
5326
  }
5313
5327
  return false;
5314
5328
  };
5315
5329
  const setTradeMarkers = (markers) => {
5316
5330
  tradeMarkers = Array.isArray(markers) ? markers.slice() : [];
5317
- draw();
5331
+ scheduleDraw();
5318
5332
  };
5319
5333
  const setMagnetMode = (mode) => {
5320
5334
  magnetMode = mode;
@@ -5325,13 +5339,13 @@ function createChart(element, options = {}) {
5325
5339
  drawings = nextDrawings.map((drawing) => normalizeDrawingState(drawing));
5326
5340
  draftDrawing = null;
5327
5341
  emitDrawingsChange();
5328
- draw();
5342
+ scheduleDraw();
5329
5343
  };
5330
5344
  const addDrawing = (drawing) => {
5331
5345
  const next = normalizeDrawingState(drawing);
5332
5346
  drawings.push(next);
5333
5347
  emitDrawingsChange();
5334
- draw();
5348
+ scheduleDraw();
5335
5349
  return next.id;
5336
5350
  };
5337
5351
  const updateDrawing = (id, patch) => {
@@ -5344,18 +5358,18 @@ function createChart(element, options = {}) {
5344
5358
  }) : drawing
5345
5359
  );
5346
5360
  emitDrawingsChange();
5347
- draw();
5361
+ scheduleDraw();
5348
5362
  };
5349
5363
  const removeDrawing = (id) => {
5350
5364
  drawings = drawings.filter((drawing) => drawing.id !== id);
5351
5365
  emitDrawingsChange();
5352
- draw();
5366
+ scheduleDraw();
5353
5367
  };
5354
5368
  const clearDrawings = () => {
5355
5369
  drawings = [];
5356
5370
  draftDrawing = null;
5357
5371
  emitDrawingsChange();
5358
- draw();
5372
+ scheduleDraw();
5359
5373
  };
5360
5374
  const onDrawingsChange = (handler) => {
5361
5375
  drawingsChangeHandler = handler;
@@ -5377,6 +5391,11 @@ function createChart(element, options = {}) {
5377
5391
  cancelAnimationFrame(smoothingRafId);
5378
5392
  smoothingRafId = null;
5379
5393
  }
5394
+ if (drawRafId !== null) {
5395
+ cancelAnimationFrame(drawRafId);
5396
+ drawRafId = null;
5397
+ pendingDrawUpdateAutoScale = false;
5398
+ }
5380
5399
  canvas.removeEventListener("pointerdown", onPointerDown);
5381
5400
  canvas.removeEventListener("pointermove", onPointerMove);
5382
5401
  canvas.removeEventListener("pointerup", endPointerDrag);