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.
package/dist/index.js CHANGED
@@ -1046,7 +1046,7 @@ function createChart(element, options = {}) {
1046
1046
  if (Math.abs(priceDiff) < 1e-9 && Math.abs(volumeDiff) < 1e-6) {
1047
1047
  smoothedTickerPrice = tickerPriceTarget;
1048
1048
  smoothedTickerVolume = tickerVolumeTarget;
1049
- draw({ updateAutoScale: false });
1049
+ scheduleDraw({ updateAutoScale: false });
1050
1050
  return;
1051
1051
  }
1052
1052
  const tickerOpts = mergedOptions.tickerLine ?? DEFAULT_OPTIONS.tickerLine;
@@ -1055,7 +1055,7 @@ function createChart(element, options = {}) {
1055
1055
  const lerp = 1 - Math.exp(-speed * dt);
1056
1056
  smoothedTickerPrice += priceDiff * lerp;
1057
1057
  smoothedTickerVolume += volumeDiff * lerp;
1058
- draw({ updateAutoScale: false });
1058
+ scheduleDraw({ updateAutoScale: false });
1059
1059
  smoothingRafId = requestAnimationFrame(tickerSmoothingLoop);
1060
1060
  };
1061
1061
  const pushSmoothedTicker = (targetPrice, targetVolume) => {
@@ -1120,7 +1120,7 @@ function createChart(element, options = {}) {
1120
1120
  image.onload = () => {
1121
1121
  watermarkImage = image;
1122
1122
  watermarkImageReady = true;
1123
- draw();
1123
+ scheduleDraw();
1124
1124
  };
1125
1125
  image.onerror = () => {
1126
1126
  watermarkImage = null;
@@ -1883,7 +1883,21 @@ function createChart(element, options = {}) {
1883
1883
  }
1884
1884
  }
1885
1885
  crosshairPoint = point;
1886
- draw();
1886
+ scheduleDraw();
1887
+ };
1888
+ let drawRafId = null;
1889
+ let pendingDrawUpdateAutoScale = false;
1890
+ const scheduleDraw = (options2 = {}) => {
1891
+ pendingDrawUpdateAutoScale = pendingDrawUpdateAutoScale || (options2.updateAutoScale ?? true);
1892
+ if (drawRafId !== null) {
1893
+ return;
1894
+ }
1895
+ drawRafId = requestAnimationFrame(() => {
1896
+ drawRafId = null;
1897
+ const updateAutoScale = pendingDrawUpdateAutoScale;
1898
+ pendingDrawUpdateAutoScale = false;
1899
+ draw({ updateAutoScale });
1900
+ });
1887
1901
  };
1888
1902
  const draw = (options2 = {}) => {
1889
1903
  const shouldUpdateAutoScale = options2.updateAutoScale ?? true;
@@ -3612,7 +3626,7 @@ function createChart(element, options = {}) {
3612
3626
  clampXViewport();
3613
3627
  updateFollowLatest(false);
3614
3628
  emitViewportChange();
3615
- draw();
3629
+ scheduleDraw();
3616
3630
  };
3617
3631
  const zoomXToLatest = (factor) => {
3618
3632
  if (!drawState || data.length === 0) {
@@ -3627,7 +3641,7 @@ function createChart(element, options = {}) {
3627
3641
  xCenter = nextStart + nextSpan / 2;
3628
3642
  clampXViewport();
3629
3643
  emitViewportChange();
3630
- draw();
3644
+ scheduleDraw();
3631
3645
  };
3632
3646
  const zoomXFromAxis = (factor) => {
3633
3647
  if (!drawState) {
@@ -3658,7 +3672,7 @@ function createChart(element, options = {}) {
3658
3672
  yMinOverride = clamped.min;
3659
3673
  yMaxOverride = clamped.max;
3660
3674
  emitViewportChange();
3661
- draw();
3675
+ scheduleDraw();
3662
3676
  };
3663
3677
  const pan = (deltaX, deltaY, allowX, allowY) => {
3664
3678
  if (!drawState || data.length === 0) {
@@ -3684,7 +3698,7 @@ function createChart(element, options = {}) {
3684
3698
  if (allowX || allowY) {
3685
3699
  emitViewportChange();
3686
3700
  }
3687
- draw();
3701
+ scheduleDraw();
3688
3702
  };
3689
3703
  const resetYViewport = () => {
3690
3704
  yMinOverride = null;
@@ -3724,7 +3738,7 @@ function createChart(element, options = {}) {
3724
3738
  clampXViewport();
3725
3739
  updateFollowLatest(false);
3726
3740
  emitViewportChange();
3727
- draw();
3741
+ scheduleDraw();
3728
3742
  };
3729
3743
  const panY = (priceDelta) => {
3730
3744
  if (!drawState || !Number.isFinite(priceDelta) || priceDelta === 0) {
@@ -3736,20 +3750,20 @@ function createChart(element, options = {}) {
3736
3750
  yMinOverride = clamped.min;
3737
3751
  yMaxOverride = clamped.max;
3738
3752
  emitViewportChange();
3739
- draw();
3753
+ scheduleDraw();
3740
3754
  };
3741
3755
  const fitContent = () => {
3742
3756
  fitXViewport();
3743
3757
  updateFollowLatest(true);
3744
3758
  emitViewportChange();
3745
- draw();
3759
+ scheduleDraw();
3746
3760
  };
3747
3761
  const resetViewport = () => {
3748
3762
  fitXViewport();
3749
3763
  resetYViewport();
3750
3764
  updateFollowLatest(true);
3751
3765
  emitViewportChange();
3752
- draw();
3766
+ scheduleDraw();
3753
3767
  };
3754
3768
  const isFollowingLatest = () => followLatest;
3755
3769
  const setFollowingLatest = (follow) => {
@@ -3757,7 +3771,7 @@ function createChart(element, options = {}) {
3757
3771
  xCenter = data.length - xSpan / 2 + rightEdgePaddingBars;
3758
3772
  clampXViewport();
3759
3773
  updateFollowLatest(true);
3760
- draw();
3774
+ scheduleDraw();
3761
3775
  } else {
3762
3776
  updateFollowLatest(follow);
3763
3777
  }
@@ -3816,7 +3830,7 @@ function createChart(element, options = {}) {
3816
3830
  }
3817
3831
  if (changed) {
3818
3832
  clampXViewport();
3819
- draw();
3833
+ scheduleDraw();
3820
3834
  emitViewportChange();
3821
3835
  }
3822
3836
  };
@@ -4193,7 +4207,7 @@ function createChart(element, options = {}) {
4193
4207
  })
4194
4208
  );
4195
4209
  emitDrawingsChange();
4196
- draw();
4210
+ scheduleDraw();
4197
4211
  return true;
4198
4212
  }
4199
4213
  if (activeDrawingTool === "vertical-line") {
@@ -4208,7 +4222,7 @@ function createChart(element, options = {}) {
4208
4222
  })
4209
4223
  );
4210
4224
  emitDrawingsChange();
4211
- draw();
4225
+ scheduleDraw();
4212
4226
  return true;
4213
4227
  }
4214
4228
  if (activeDrawingTool === "trendline") {
@@ -4223,7 +4237,7 @@ function createChart(element, options = {}) {
4223
4237
  draftDrawing = null;
4224
4238
  activeDrawingTool = null;
4225
4239
  emitDrawingsChange();
4226
- draw();
4240
+ scheduleDraw();
4227
4241
  return true;
4228
4242
  }
4229
4243
  const defaults = getDrawingToolDefaults("trendline");
@@ -4234,7 +4248,7 @@ function createChart(element, options = {}) {
4234
4248
  style: defaults.style ?? "solid",
4235
4249
  width: defaults.width ?? 2
4236
4250
  });
4237
- draw();
4251
+ scheduleDraw();
4238
4252
  return true;
4239
4253
  }
4240
4254
  if (activeDrawingTool === "ray") {
@@ -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("ray");
@@ -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 === "fib-retracement") {
@@ -4273,7 +4287,7 @@ function createChart(element, options = {}) {
4273
4287
  draftDrawing = null;
4274
4288
  activeDrawingTool = null;
4275
4289
  emitDrawingsChange();
4276
- draw();
4290
+ scheduleDraw();
4277
4291
  return true;
4278
4292
  }
4279
4293
  const defaults = getDrawingToolDefaults("fib-retracement");
@@ -4285,7 +4299,7 @@ function createChart(element, options = {}) {
4285
4299
  style: defaults.style ?? "solid",
4286
4300
  width: defaults.width ?? 1
4287
4301
  });
4288
- draw();
4302
+ scheduleDraw();
4289
4303
  return true;
4290
4304
  }
4291
4305
  if (activeDrawingTool === "fib-extension") {
@@ -4295,7 +4309,7 @@ function createChart(element, options = {}) {
4295
4309
  ...serializeDrawing(draftDrawing),
4296
4310
  points: [...draftDrawing.points.slice(0, -1), point, point]
4297
4311
  });
4298
- draw();
4312
+ scheduleDraw();
4299
4313
  return true;
4300
4314
  }
4301
4315
  const completed = normalizeDrawingState({
@@ -4306,7 +4320,7 @@ function createChart(element, options = {}) {
4306
4320
  draftDrawing = null;
4307
4321
  activeDrawingTool = null;
4308
4322
  emitDrawingsChange();
4309
- draw();
4323
+ scheduleDraw();
4310
4324
  return true;
4311
4325
  }
4312
4326
  const defaults = getDrawingToolDefaults("fib-extension");
@@ -4318,7 +4332,7 @@ function createChart(element, options = {}) {
4318
4332
  style: defaults.style ?? "solid",
4319
4333
  width: defaults.width ?? 1
4320
4334
  });
4321
- draw();
4335
+ scheduleDraw();
4322
4336
  return true;
4323
4337
  }
4324
4338
  if (activeDrawingTool === "text" || activeDrawingTool === "note") {
@@ -4335,7 +4349,7 @@ function createChart(element, options = {}) {
4335
4349
  drawings.push(created);
4336
4350
  selectedDrawingId = created.id;
4337
4351
  emitDrawingsChange();
4338
- draw();
4352
+ scheduleDraw();
4339
4353
  drawingEditTextHandler?.({ drawing: serializeDrawing(created), target: "line", x, y });
4340
4354
  return true;
4341
4355
  }
@@ -4355,7 +4369,7 @@ function createChart(element, options = {}) {
4355
4369
  })
4356
4370
  );
4357
4371
  emitDrawingsChange();
4358
- draw();
4372
+ scheduleDraw();
4359
4373
  return true;
4360
4374
  }
4361
4375
  if (activeDrawingTool === "long-position" || activeDrawingTool === "short-position") {
@@ -4391,7 +4405,7 @@ function createChart(element, options = {}) {
4391
4405
  })
4392
4406
  );
4393
4407
  emitDrawingsChange();
4394
- draw();
4408
+ scheduleDraw();
4395
4409
  return true;
4396
4410
  }
4397
4411
  return false;
@@ -4408,7 +4422,7 @@ function createChart(element, options = {}) {
4408
4422
  return;
4409
4423
  }
4410
4424
  selectedDrawingId = id;
4411
- draw();
4425
+ scheduleDraw();
4412
4426
  };
4413
4427
  const updateDrawingDrag = (x, y) => {
4414
4428
  if (!drawingDragState) {
@@ -4467,7 +4481,7 @@ function createChart(element, options = {}) {
4467
4481
  };
4468
4482
  });
4469
4483
  emitDrawingsChange();
4470
- draw();
4484
+ scheduleDraw();
4471
4485
  return true;
4472
4486
  };
4473
4487
  let isDragging = false;
@@ -4532,7 +4546,7 @@ function createChart(element, options = {}) {
4532
4546
  clampXViewport();
4533
4547
  updateFollowLatest(false);
4534
4548
  emitViewportChange();
4535
- draw();
4549
+ scheduleDraw();
4536
4550
  };
4537
4551
  const onPointerDown = (event) => {
4538
4552
  if (event.pointerType === "touch" || event.pointerType === "pen") {
@@ -4639,7 +4653,7 @@ function createChart(element, options = {}) {
4639
4653
  isDragging = true;
4640
4654
  dragMode = region;
4641
4655
  activePointerId = event.pointerId;
4642
- const crosshairDrag = (event.pointerType === "touch" || event.pointerType === "pen") && region === "plot";
4656
+ const crosshairDrag = false;
4643
4657
  pointerDownInfo = {
4644
4658
  pointerId: event.pointerId,
4645
4659
  pointerType: event.pointerType,
@@ -4716,7 +4730,7 @@ function createChart(element, options = {}) {
4716
4730
  points: [...draftDrawing.points.slice(0, -1), nextPoint]
4717
4731
  };
4718
4732
  canvas.style.cursor = "crosshair";
4719
- draw();
4733
+ scheduleDraw();
4720
4734
  return;
4721
4735
  }
4722
4736
  }
@@ -4744,7 +4758,7 @@ function createChart(element, options = {}) {
4744
4758
  dragging: true,
4745
4759
  ...currentLine ? { line: currentLine } : {}
4746
4760
  });
4747
- draw();
4761
+ scheduleDraw();
4748
4762
  }
4749
4763
  canvas.style.cursor = "ns-resize";
4750
4764
  setCrosshairPoint(null);
@@ -5006,7 +5020,7 @@ function createChart(element, options = {}) {
5006
5020
  }
5007
5021
  if (region === "y-axis") {
5008
5022
  resetYViewport();
5009
- draw();
5023
+ scheduleDraw();
5010
5024
  return;
5011
5025
  }
5012
5026
  resetViewport();
@@ -5028,7 +5042,7 @@ function createChart(element, options = {}) {
5028
5042
  const changed = active !== magnetModifierActive || shift !== shiftKeyActive;
5029
5043
  magnetModifierActive = active;
5030
5044
  shiftKeyActive = shift;
5031
- if (changed && draftDrawing) draw();
5045
+ if (changed && draftDrawing) scheduleDraw();
5032
5046
  };
5033
5047
  const onWindowBlurMagnet = () => {
5034
5048
  magnetModifierActive = false;
@@ -5064,7 +5078,7 @@ function createChart(element, options = {}) {
5064
5078
  const lastPoint = data[data.length - 1];
5065
5079
  pushSmoothedTicker(lastPoint.c, lastPoint.v);
5066
5080
  }
5067
- draw();
5081
+ scheduleDraw();
5068
5082
  };
5069
5083
  const resize = (nextWidth, nextHeight) => {
5070
5084
  if (nextWidth && nextWidth > 0) {
@@ -5075,7 +5089,7 @@ function createChart(element, options = {}) {
5075
5089
  }
5076
5090
  mergedOptions = { ...mergedOptions, width, height };
5077
5091
  resetRightMarginCache();
5078
- draw();
5092
+ scheduleDraw();
5079
5093
  };
5080
5094
  const setData = (nextData) => {
5081
5095
  const hadData = data.length > 0;
@@ -5093,7 +5107,7 @@ function createChart(element, options = {}) {
5093
5107
  tickerVolumeTarget = null;
5094
5108
  resetRightMarginCache();
5095
5109
  resetYViewport();
5096
- draw();
5110
+ scheduleDraw();
5097
5111
  return;
5098
5112
  }
5099
5113
  if (!hadData) {
@@ -5118,7 +5132,7 @@ function createChart(element, options = {}) {
5118
5132
  if (lastPoint) {
5119
5133
  pushSmoothedTicker(lastPoint.c, lastPoint.v);
5120
5134
  }
5121
- draw();
5135
+ scheduleDraw();
5122
5136
  };
5123
5137
  const setPriceLines = (lines) => {
5124
5138
  priceLines = lines.map((line, index) => ({
@@ -5126,18 +5140,18 @@ function createChart(element, options = {}) {
5126
5140
  id: line.id ?? `line-${index + 1}`
5127
5141
  }));
5128
5142
  resetRightMarginCache();
5129
- draw();
5143
+ scheduleDraw();
5130
5144
  };
5131
5145
  const addPriceLine = (line) => {
5132
5146
  const id = line.id ?? `line-${generatedPriceLineId++}`;
5133
5147
  priceLines.push({ ...line, id });
5134
- draw();
5148
+ scheduleDraw();
5135
5149
  return id;
5136
5150
  };
5137
5151
  const removePriceLine = (id) => {
5138
5152
  priceLines = priceLines.filter((line) => line.id !== id);
5139
5153
  resetRightMarginCache();
5140
- draw();
5154
+ scheduleDraw();
5141
5155
  };
5142
5156
  const setOrderLines = (lines) => {
5143
5157
  orderLines = lines.map((line, index) => ({
@@ -5156,24 +5170,24 @@ function createChart(element, options = {}) {
5156
5170
  orderPriceTagWidthById.delete(id);
5157
5171
  }
5158
5172
  }
5159
- draw();
5173
+ scheduleDraw();
5160
5174
  };
5161
5175
  const addOrderLine = (line) => {
5162
5176
  const id = line.id ?? `order-${generatedOrderLineId++}`;
5163
5177
  orderLines.push({ ...line, id });
5164
- draw();
5178
+ scheduleDraw();
5165
5179
  return id;
5166
5180
  };
5167
5181
  const updateOrderLine = (id, patch) => {
5168
5182
  orderLines = orderLines.map((line) => line.id === id ? { ...line, ...patch, id } : line);
5169
- draw();
5183
+ scheduleDraw();
5170
5184
  };
5171
5185
  const removeOrderLine = (id) => {
5172
5186
  orderLines = orderLines.filter((line) => line.id !== id);
5173
5187
  orderWidgetWidthById.delete(id);
5174
5188
  orderPriceTagWidthById.delete(id);
5175
5189
  resetRightMarginCache();
5176
- draw();
5190
+ scheduleDraw();
5177
5191
  };
5178
5192
  const onOrderAction = (handler) => {
5179
5193
  orderActionHandler = handler;
@@ -5198,12 +5212,12 @@ function createChart(element, options = {}) {
5198
5212
  throw new Error("Invalid indicator plugin. Expected { id, draw }.");
5199
5213
  }
5200
5214
  indicatorRegistry.set(plugin.id, plugin);
5201
- draw();
5215
+ scheduleDraw();
5202
5216
  };
5203
5217
  const unregisterIndicator = (type) => {
5204
5218
  indicatorRegistry.delete(type);
5205
5219
  indicators = indicators.filter((indicator) => indicator.type !== type);
5206
- draw();
5220
+ scheduleDraw();
5207
5221
  };
5208
5222
  const listBuiltInIndicators = () => {
5209
5223
  return BUILTIN_INDICATORS.map((indicator) => ({
@@ -5228,7 +5242,7 @@ function createChart(element, options = {}) {
5228
5242
  };
5229
5243
  const setIndicators = (nextIndicators) => {
5230
5244
  indicators = nextIndicators.map((indicator) => normalizeIndicatorState(indicator));
5231
- draw();
5245
+ scheduleDraw();
5232
5246
  };
5233
5247
  const addIndicator = (type, inputs = {}, options2 = {}) => {
5234
5248
  const plugin = indicatorRegistry.get(type);
@@ -5241,7 +5255,7 @@ function createChart(element, options = {}) {
5241
5255
  inputs
5242
5256
  });
5243
5257
  indicators.push(next);
5244
- draw();
5258
+ scheduleDraw();
5245
5259
  return next.id;
5246
5260
  };
5247
5261
  const updateIndicator = (id, patch) => {
@@ -5265,30 +5279,30 @@ function createChart(element, options = {}) {
5265
5279
  }
5266
5280
  };
5267
5281
  });
5268
- draw();
5282
+ scheduleDraw();
5269
5283
  };
5270
5284
  const removeIndicator = (id) => {
5271
5285
  indicators = indicators.filter((indicator) => indicator.id !== id);
5272
- draw();
5286
+ scheduleDraw();
5273
5287
  };
5274
5288
  const setActiveDrawingTool = (tool) => {
5275
5289
  activeDrawingTool = tool;
5276
5290
  draftDrawing = null;
5277
5291
  canvas.style.cursor = tool ? "crosshair" : "default";
5278
- draw();
5292
+ scheduleDraw();
5279
5293
  };
5280
5294
  const getActiveDrawingTool = () => activeDrawingTool;
5281
5295
  const cancelDrawing = () => {
5282
5296
  if (draftDrawing) {
5283
5297
  draftDrawing = null;
5284
- draw();
5298
+ scheduleDraw();
5285
5299
  return true;
5286
5300
  }
5287
5301
  return false;
5288
5302
  };
5289
5303
  const setTradeMarkers = (markers) => {
5290
5304
  tradeMarkers = Array.isArray(markers) ? markers.slice() : [];
5291
- draw();
5305
+ scheduleDraw();
5292
5306
  };
5293
5307
  const setMagnetMode = (mode) => {
5294
5308
  magnetMode = mode;
@@ -5299,13 +5313,13 @@ function createChart(element, options = {}) {
5299
5313
  drawings = nextDrawings.map((drawing) => normalizeDrawingState(drawing));
5300
5314
  draftDrawing = null;
5301
5315
  emitDrawingsChange();
5302
- draw();
5316
+ scheduleDraw();
5303
5317
  };
5304
5318
  const addDrawing = (drawing) => {
5305
5319
  const next = normalizeDrawingState(drawing);
5306
5320
  drawings.push(next);
5307
5321
  emitDrawingsChange();
5308
- draw();
5322
+ scheduleDraw();
5309
5323
  return next.id;
5310
5324
  };
5311
5325
  const updateDrawing = (id, patch) => {
@@ -5318,18 +5332,18 @@ function createChart(element, options = {}) {
5318
5332
  }) : drawing
5319
5333
  );
5320
5334
  emitDrawingsChange();
5321
- draw();
5335
+ scheduleDraw();
5322
5336
  };
5323
5337
  const removeDrawing = (id) => {
5324
5338
  drawings = drawings.filter((drawing) => drawing.id !== id);
5325
5339
  emitDrawingsChange();
5326
- draw();
5340
+ scheduleDraw();
5327
5341
  };
5328
5342
  const clearDrawings = () => {
5329
5343
  drawings = [];
5330
5344
  draftDrawing = null;
5331
5345
  emitDrawingsChange();
5332
- draw();
5346
+ scheduleDraw();
5333
5347
  };
5334
5348
  const onDrawingsChange = (handler) => {
5335
5349
  drawingsChangeHandler = handler;
@@ -5351,6 +5365,11 @@ function createChart(element, options = {}) {
5351
5365
  cancelAnimationFrame(smoothingRafId);
5352
5366
  smoothingRafId = null;
5353
5367
  }
5368
+ if (drawRafId !== null) {
5369
+ cancelAnimationFrame(drawRafId);
5370
+ drawRafId = null;
5371
+ pendingDrawUpdateAutoScale = false;
5372
+ }
5354
5373
  canvas.removeEventListener("pointerdown", onPointerDown);
5355
5374
  canvas.removeEventListener("pointermove", onPointerMove);
5356
5375
  canvas.removeEventListener("pointerup", endPointerDrag);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.106",
3
+ "version": "0.1.108",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",