@trdrs/quickcharts 2.0.0 → 2.0.1

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/drawings.js CHANGED
@@ -85,7 +85,7 @@ import {
85
85
  visibilityPreset,
86
86
  visibleAt,
87
87
  withAlpha
88
- } from "./chunk-6S6TO2N6.js";
88
+ } from "./chunk-YR7NT5ZW.js";
89
89
  import {
90
90
  DRAWING_CONTEXT_VERSION,
91
91
  DRAWING_DOCUMENT_VERSION,
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.0",
2
+ "version": "2.0.1",
3
3
  "styles": [
4
4
  {
5
5
  "id": "candles",
package/dist/index.js CHANGED
@@ -82,7 +82,7 @@ import {
82
82
  viewportOf,
83
83
  visibilityPreset,
84
84
  withAlpha
85
- } from "./chunk-6S6TO2N6.js";
85
+ } from "./chunk-YR7NT5ZW.js";
86
86
  import {
87
87
  ResourceAbortError,
88
88
  memorySaveLoadAdapter
@@ -8132,6 +8132,10 @@ var PLACE_DRAG_PX = 6;
8132
8132
  var MOVE_EPSILON_PX = 2;
8133
8133
  var HANDLE_GRAB_PX = 11;
8134
8134
  var GRIP_GRAB_PX = 9;
8135
+ var TOUCH_REACH_PX = 14;
8136
+ var TOUCH_GRAB_PX = 22;
8137
+ var TOUCH_PLACE_DRAG_PX = 12;
8138
+ var TOUCH_MOVE_PX = 6;
8135
8139
  var STROKE_STEP_PX = 3;
8136
8140
  var isTransientArmed = (tool) => tool === "measure" || tool === "zoom" || tool === "eraser";
8137
8141
  function bindGestures(ctx) {
@@ -8163,11 +8167,38 @@ function bindGestures(ctx) {
8163
8167
  if (mode === "off") return raw;
8164
8168
  return magnetSnap(chart, series2, p, mode) ?? raw;
8165
8169
  };
8170
+ let touching = false;
8171
+ const hitAt = (p) => {
8172
+ const under = manager.hitTest(p);
8173
+ if (under || !touching) return under;
8174
+ for (const radius of [TOUCH_REACH_PX / 2, TOUCH_REACH_PX]) {
8175
+ for (let k = 0; k < 8; k++) {
8176
+ const angle = k * Math.PI / 4;
8177
+ const near2 = manager.hitTest({ x: p.x + radius * Math.cos(angle), y: p.y + radius * Math.sin(angle) });
8178
+ if (near2) return near2;
8179
+ }
8180
+ }
8181
+ return null;
8182
+ };
8183
+ const showPoint = (anchor) => {
8184
+ if (!touching || !anchor) return;
8185
+ try {
8186
+ chart.setCrosshairPosition(anchor.price, anchor.time, series2);
8187
+ } catch {
8188
+ }
8189
+ };
8190
+ const hidePoint = () => {
8191
+ if (!touching) return;
8192
+ try {
8193
+ chart.clearCrosshairPosition();
8194
+ } catch {
8195
+ }
8196
+ };
8166
8197
  const anchorHit = (drawing2, p) => {
8167
8198
  const vp = viewport();
8168
8199
  if (!vp) return null;
8169
8200
  let best = null;
8170
- let bestD = HANDLE_GRAB_PX;
8201
+ let bestD = touching ? TOUCH_GRAB_PX : HANDLE_GRAB_PX;
8171
8202
  for (const cp of drawing2.getControlPoints(vp)) {
8172
8203
  const d = Math.hypot(cp.x - p.x, cp.y - p.y);
8173
8204
  if (d <= bestD) {
@@ -8239,6 +8270,7 @@ function bindGestures(ctx) {
8239
8270
  };
8240
8271
  const onDown = (e) => {
8241
8272
  if (e.button !== 0) return;
8273
+ touching = e.pointerType === "touch";
8242
8274
  if (ctx.textEditOpen()) return;
8243
8275
  wearCursor(ctx.cursorCss());
8244
8276
  container.focus({ preventScroll: true });
@@ -8247,7 +8279,7 @@ function bindGestures(ctx) {
8247
8279
  if (!ctx.draft && ctx.transient.size && tool !== "measure" && tool !== "zoom") ctx.clearTransients();
8248
8280
  if (tool === "eraser") {
8249
8281
  if (ctx.locked()) return;
8250
- const hit = manager.hitTest(p);
8282
+ const hit = hitAt(p);
8251
8283
  if (hit && !editRefused("erase", hit.options, false)) {
8252
8284
  manager.remove(hit.id);
8253
8285
  ctx.persist();
@@ -8284,7 +8316,8 @@ function bindGestures(ctx) {
8284
8316
  }
8285
8317
  const vp = viewport();
8286
8318
  if (vp) {
8287
- const grip = sel.resizeHandles(vp).findIndex((g) => Math.hypot(g.x - p.x, g.y - p.y) <= GRIP_GRAB_PX);
8319
+ const gripReach = touching ? TOUCH_GRAB_PX : GRIP_GRAB_PX;
8320
+ const grip = sel.resizeHandles(vp).findIndex((g) => Math.hypot(g.x - p.x, g.y - p.y) <= gripReach);
8288
8321
  if (grip !== -1) {
8289
8322
  startDrag("resize", sel, grip, p);
8290
8323
  return;
@@ -8302,7 +8335,7 @@ function bindGestures(ctx) {
8302
8335
  return;
8303
8336
  }
8304
8337
  }
8305
- const hit = manager.hitTest(p);
8338
+ const hit = hitAt(p);
8306
8339
  if (hit) {
8307
8340
  if ((e.ctrlKey || e.metaKey) && !editRefused("cloneDrag", hit.options, false) && ctx.copies(hit.type)) {
8308
8341
  const copy = drawingTools.restore({ ...hit.toJSON(), id: ctx.nextId() });
@@ -8322,7 +8355,10 @@ function bindGestures(ctx) {
8322
8355
  manager.deselect();
8323
8356
  return;
8324
8357
  }
8325
- if (ctx.draft) return;
8358
+ if (ctx.draft) {
8359
+ if (touching) followDraft(ctx.draft, p, e.shiftKey);
8360
+ return;
8361
+ }
8326
8362
  if (ctx.locked()) return;
8327
8363
  const def = drawingTools.get(tool);
8328
8364
  if (!def) return;
@@ -8355,6 +8391,7 @@ function bindGestures(ctx) {
8355
8391
  }
8356
8392
  manager.add(drawing2);
8357
8393
  ctx.draft = { drawing: drawing2, required, placed: 1, downX: p.x, downY: p.y, pendingDrag: true, hasText: !!def.hasText, mode, lastX: p.x, lastY: p.y };
8394
+ showPoint(anchor);
8358
8395
  if (mode === "fixed" && required === 1) completePlacement(ctx.draft, p);
8359
8396
  };
8360
8397
  const constrainedEnd = (draft, p, shift) => {
@@ -8363,12 +8400,22 @@ function bindGestures(ctx) {
8363
8400
  const first = vp && draft.drawing.anchors[0] ? draft.drawing.anchorToPixel(draft.drawing.anchors[0], vp) : null;
8364
8401
  return first ? constrain45(first, p) : p;
8365
8402
  };
8403
+ const followDraft = (draft, p, shift) => {
8404
+ const live = constrainedEnd(draft, p, shift);
8405
+ const anchor = isTransientArmed(ctx.armed()) ? anchorAt(live) : snappedAnchorAt(live, shift);
8406
+ if (anchor) draft.drawing.updateAnchor(draft.drawing.anchors.length - 1, anchor);
8407
+ showPoint(anchor);
8408
+ };
8366
8409
  const onMove = (e) => {
8367
8410
  const p = localXY(e);
8368
8411
  const drag = ctx.drag;
8369
8412
  if (drag) {
8370
8413
  let { x, y } = p;
8371
- if (!drag.moved && Math.abs(x - drag.grabX) + Math.abs(y - drag.grabY) > MOVE_EPSILON_PX) drag.moved = true;
8414
+ if (!drag.moved) {
8415
+ const travel = Math.abs(x - drag.grabX) + Math.abs(y - drag.grabY);
8416
+ if (touching && travel <= TOUCH_MOVE_PX) return;
8417
+ if (travel > MOVE_EPSILON_PX) drag.moved = true;
8418
+ }
8372
8419
  const vp = viewport();
8373
8420
  if (!vp) return;
8374
8421
  if (drag.mode === "resize" && drag.anchorIndex !== null) {
@@ -8382,6 +8429,7 @@ function bindGestures(ctx) {
8382
8429
  }
8383
8430
  const anchor = snappedAnchorAt({ x, y }, e.shiftKey);
8384
8431
  if (anchor) drag.drawing.updateAnchor(drag.anchorIndex, anchor);
8432
+ showPoint(anchor);
8385
8433
  return;
8386
8434
  }
8387
8435
  const dx = x - drag.grabX;
@@ -8404,18 +8452,16 @@ function bindGestures(ctx) {
8404
8452
  const draft = ctx.draft;
8405
8453
  if (draft) {
8406
8454
  if (draft.mode === "freehand") {
8407
- const anchor2 = anchorAt(p);
8408
- if (!anchor2) return;
8455
+ const anchor = anchorAt(p);
8456
+ if (!anchor) return;
8409
8457
  if (Math.hypot(p.x - draft.lastX, p.y - draft.lastY) >= STROKE_STEP_PX) {
8410
- draft.drawing.appendAnchor(anchor2);
8458
+ draft.drawing.appendAnchor(anchor);
8411
8459
  draft.lastX = p.x;
8412
8460
  draft.lastY = p.y;
8413
8461
  }
8414
8462
  return;
8415
8463
  }
8416
- const live = constrainedEnd(draft, p, e.shiftKey);
8417
- const anchor = isTransientArmed(ctx.armed()) ? anchorAt(live) : snappedAnchorAt(live, e.shiftKey);
8418
- if (anchor) draft.drawing.updateAnchor(draft.drawing.anchors.length - 1, anchor);
8464
+ followDraft(draft, p, e.shiftKey);
8419
8465
  return;
8420
8466
  }
8421
8467
  wearCursor(ctx.cursorCss());
@@ -8425,33 +8471,38 @@ function bindGestures(ctx) {
8425
8471
  ctx.setHovered(manager.hitTest(localXY(e))?.id ?? null);
8426
8472
  };
8427
8473
  const onLeave = () => ctx.setHovered(null);
8474
+ const placeSlop = () => touching ? TOUCH_PLACE_DRAG_PX : PLACE_DRAG_PX;
8475
+ const endDrag = (drag) => {
8476
+ ctx.drag = null;
8477
+ freezePan(!!ctx.armed());
8478
+ if (drag.cloned && !drag.moved) manager.remove(drag.drawing.id);
8479
+ if (!drag.moved && !drag.cloned && drag.mode === "move" && drag.drawing.type === "table") {
8480
+ const vp = viewport();
8481
+ const table = drag.drawing;
8482
+ const cell2 = vp && table.cellAt ? table.cellAt({ x: drag.grabX, y: drag.grabY }, vp) : null;
8483
+ if (cell2) {
8484
+ ctx.openCellEdit(drag.drawing, cell2);
8485
+ return;
8486
+ }
8487
+ }
8488
+ if (drag.moved || drag.cloned) {
8489
+ ctx.persist();
8490
+ ctx.changed();
8491
+ }
8492
+ };
8428
8493
  const onUp = (e) => {
8429
8494
  const p = localXY(e);
8495
+ hidePoint();
8430
8496
  const drag = ctx.drag;
8431
8497
  if (drag) {
8432
- ctx.drag = null;
8433
- freezePan(!!ctx.armed());
8434
- if (drag.cloned && !drag.moved) manager.remove(drag.drawing.id);
8435
- if (!drag.moved && !drag.cloned && drag.mode === "move" && drag.drawing.type === "table") {
8436
- const vp = viewport();
8437
- const table = drag.drawing;
8438
- const cell2 = vp && table.cellAt ? table.cellAt({ x: drag.grabX, y: drag.grabY }, vp) : null;
8439
- if (cell2) {
8440
- ctx.openCellEdit(drag.drawing, cell2);
8441
- return;
8442
- }
8443
- }
8444
- if (drag.moved || drag.cloned) {
8445
- ctx.persist();
8446
- ctx.changed();
8447
- }
8498
+ endDrag(drag);
8448
8499
  return;
8449
8500
  }
8450
8501
  const draft = ctx.draft;
8451
8502
  if (!draft) return;
8452
8503
  const tool = ctx.armed();
8453
8504
  if (tool === "measure" || tool === "zoom") {
8454
- const moved2 = Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) > 4;
8505
+ const moved2 = Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) > (touching ? TOUCH_PLACE_DRAG_PX : 4);
8455
8506
  if (!moved2 && draft.pendingDrag) {
8456
8507
  draft.pendingDrag = false;
8457
8508
  return;
@@ -8471,7 +8522,7 @@ function bindGestures(ctx) {
8471
8522
  return;
8472
8523
  }
8473
8524
  if (draft.mode === "multipoint") {
8474
- if (draft.pendingDrag && Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) <= PLACE_DRAG_PX) {
8525
+ if (draft.pendingDrag && Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) <= placeSlop()) {
8475
8526
  draft.pendingDrag = false;
8476
8527
  return;
8477
8528
  }
@@ -8487,7 +8538,7 @@ function bindGestures(ctx) {
8487
8538
  const snapped = snappedAnchorAt(constrainedEnd(draft, p, e.shiftKey), e.shiftKey);
8488
8539
  const lastIndex = draft.drawing.anchors.length - 1;
8489
8540
  if (snapped) draft.drawing.updateAnchor(lastIndex, snapped);
8490
- const moved = Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) > PLACE_DRAG_PX;
8541
+ const moved = Math.abs(p.x - draft.downX) + Math.abs(p.y - draft.downY) > placeSlop();
8491
8542
  if (draft.pendingDrag && !moved) {
8492
8543
  draft.pendingDrag = false;
8493
8544
  return;
@@ -8501,6 +8552,14 @@ function bindGestures(ctx) {
8501
8552
  draft.drawing.appendAnchor({ ...next });
8502
8553
  }
8503
8554
  };
8555
+ const onCancel = () => {
8556
+ hidePoint();
8557
+ if (ctx.drag) endDrag(ctx.drag);
8558
+ else if (ctx.draft) ctx.draft.pendingDrag = false;
8559
+ };
8560
+ const onTouchStart = (e) => {
8561
+ if (ctx.drag || ctx.draft) e.preventDefault();
8562
+ };
8504
8563
  const onDblClick = (e) => {
8505
8564
  if (ctx.locked()) return;
8506
8565
  const draft = ctx.draft;
@@ -8525,18 +8584,22 @@ function bindGestures(ctx) {
8525
8584
  ctx.openTextEdit(hit, p.x, p.y, false);
8526
8585
  };
8527
8586
  container.addEventListener("pointerdown", onDown);
8587
+ container.addEventListener("touchstart", onTouchStart, { passive: false });
8528
8588
  container.addEventListener("pointermove", onHover);
8529
8589
  container.addEventListener("pointerleave", onLeave);
8530
8590
  container.addEventListener("dblclick", onDblClick);
8531
8591
  window.addEventListener("pointermove", onMove);
8532
8592
  window.addEventListener("pointerup", onUp);
8593
+ window.addEventListener("pointercancel", onCancel);
8533
8594
  return () => {
8534
8595
  container.removeEventListener("pointerdown", onDown);
8596
+ container.removeEventListener("touchstart", onTouchStart);
8535
8597
  container.removeEventListener("pointermove", onHover);
8536
8598
  container.removeEventListener("pointerleave", onLeave);
8537
8599
  container.removeEventListener("dblclick", onDblClick);
8538
8600
  window.removeEventListener("pointermove", onMove);
8539
8601
  window.removeEventListener("pointerup", onUp);
8602
+ window.removeEventListener("pointercancel", onCancel);
8540
8603
  };
8541
8604
  }
8542
8605