hyperprop-charting-library 0.1.91 → 0.1.93

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.
@@ -2527,28 +2527,29 @@ function createChart(element, options = {}) {
2527
2527
  const formatAmount = (value) => value.toFixed(2);
2528
2528
  const targetAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * target.price * effectivePointValue)}` : "";
2529
2529
  const stopAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * stop.price * effectivePointValue)}` : "";
2530
- const drawPositionPill = (text, centerX, centerY, bg) => {
2530
+ const drawPositionPill = (text, leftX2, centerY, bg) => {
2531
2531
  const lines = Array.isArray(text) ? text : [text];
2532
2532
  const prevFont = ctx.font;
2533
- ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2534
- const padding = 6;
2535
- const lineH = 14;
2533
+ ctx.font = `500 10px ${mergedOptions.fontFamily}`;
2534
+ const padding = 5;
2535
+ const lineH = 12;
2536
2536
  const textW = Math.max(...lines.map((line) => ctx.measureText(line).width));
2537
2537
  const pillW = textW + padding * 2;
2538
- const pillH = lines.length === 1 ? 18 : lines.length * lineH + 6;
2539
- const pillX = centerX - pillW / 2;
2538
+ const pillH = lines.length === 1 ? 15 : lines.length * lineH + 5;
2539
+ const pillX = leftX2;
2540
2540
  const pillY = centerY - pillH / 2;
2541
2541
  ctx.fillStyle = bg;
2542
- fillRoundedRect(pillX, pillY, pillW, pillH, 4);
2542
+ fillRoundedRect(pillX, pillY, pillW, pillH, 3);
2543
2543
  ctx.fillStyle = labelTextColor;
2544
- ctx.textAlign = "center";
2544
+ ctx.textAlign = "left";
2545
2545
  ctx.textBaseline = "middle";
2546
2546
  const startY = pillY + pillH / 2 - (lines.length - 1) * lineH / 2;
2547
- lines.forEach((line, lineIndex) => ctx.fillText(line, centerX, startY + lineIndex * lineH));
2547
+ lines.forEach((line, lineIndex) => ctx.fillText(line, pillX + padding, startY + lineIndex * lineH));
2548
2548
  ctx.font = prevFont;
2549
2549
  };
2550
- drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, cx, targetY, profitLine);
2551
- drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, cx, stopY, lossLine);
2550
+ const labelLeftX = boxX0 + 10;
2551
+ drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, labelLeftX, targetY, profitLine);
2552
+ drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, labelLeftX, stopY, lossLine);
2552
2553
  let centerLines;
2553
2554
  let centerBg;
2554
2555
  if (positionHit) {
@@ -2561,7 +2562,7 @@ function createChart(element, options = {}) {
2561
2562
  centerLines = [line1, `Risk/reward ratio: ${rr.toFixed(2)}`];
2562
2563
  centerBg = hexToRgba(drawing.color, 0.92);
2563
2564
  }
2564
- drawPositionPill(centerLines, cx, entryY, centerBg);
2565
+ drawPositionPill(centerLines, labelLeftX, entryY, centerBg);
2565
2566
  if (drawing.label) {
2566
2567
  drawDrawingLabel(drawing.label, cx, Math.min(targetY, stopY) - 4, drawing.color);
2567
2568
  }
@@ -4855,6 +4856,22 @@ function createChart(element, options = {}) {
4855
4856
  canvas.addEventListener("wheel", onWheel, { passive: false });
4856
4857
  canvas.addEventListener("dblclick", onDoubleClick);
4857
4858
  canvas.addEventListener("contextmenu", onContextMenu);
4859
+ const onModifierKeyChange = (event) => {
4860
+ const active = event.metaKey || event.ctrlKey;
4861
+ if (active !== magnetModifierActive) {
4862
+ magnetModifierActive = active;
4863
+ if (draftDrawing) draw();
4864
+ }
4865
+ };
4866
+ const onWindowBlurMagnet = () => {
4867
+ magnetModifierActive = false;
4868
+ };
4869
+ const hasWindow = typeof window !== "undefined";
4870
+ if (hasWindow) {
4871
+ window.addEventListener("keydown", onModifierKeyChange);
4872
+ window.addEventListener("keyup", onModifierKeyChange);
4873
+ window.addEventListener("blur", onWindowBlurMagnet);
4874
+ }
4858
4875
  const updateOptions = (nextOptions) => {
4859
4876
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
4860
4877
  const previousWidth = width;
@@ -5171,6 +5188,11 @@ function createChart(element, options = {}) {
5171
5188
  canvas.removeEventListener("wheel", onWheel);
5172
5189
  canvas.removeEventListener("dblclick", onDoubleClick);
5173
5190
  canvas.removeEventListener("contextmenu", onContextMenu);
5191
+ if (hasWindow) {
5192
+ window.removeEventListener("keydown", onModifierKeyChange);
5193
+ window.removeEventListener("keyup", onModifierKeyChange);
5194
+ window.removeEventListener("blur", onWindowBlurMagnet);
5195
+ }
5174
5196
  element.innerHTML = "";
5175
5197
  };
5176
5198
  draw();
@@ -2501,28 +2501,29 @@ function createChart(element, options = {}) {
2501
2501
  const formatAmount = (value) => value.toFixed(2);
2502
2502
  const targetAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * target.price * effectivePointValue)}` : "";
2503
2503
  const stopAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * stop.price * effectivePointValue)}` : "";
2504
- const drawPositionPill = (text, centerX, centerY, bg) => {
2504
+ const drawPositionPill = (text, leftX2, centerY, bg) => {
2505
2505
  const lines = Array.isArray(text) ? text : [text];
2506
2506
  const prevFont = ctx.font;
2507
- ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2508
- const padding = 6;
2509
- const lineH = 14;
2507
+ ctx.font = `500 10px ${mergedOptions.fontFamily}`;
2508
+ const padding = 5;
2509
+ const lineH = 12;
2510
2510
  const textW = Math.max(...lines.map((line) => ctx.measureText(line).width));
2511
2511
  const pillW = textW + padding * 2;
2512
- const pillH = lines.length === 1 ? 18 : lines.length * lineH + 6;
2513
- const pillX = centerX - pillW / 2;
2512
+ const pillH = lines.length === 1 ? 15 : lines.length * lineH + 5;
2513
+ const pillX = leftX2;
2514
2514
  const pillY = centerY - pillH / 2;
2515
2515
  ctx.fillStyle = bg;
2516
- fillRoundedRect(pillX, pillY, pillW, pillH, 4);
2516
+ fillRoundedRect(pillX, pillY, pillW, pillH, 3);
2517
2517
  ctx.fillStyle = labelTextColor;
2518
- ctx.textAlign = "center";
2518
+ ctx.textAlign = "left";
2519
2519
  ctx.textBaseline = "middle";
2520
2520
  const startY = pillY + pillH / 2 - (lines.length - 1) * lineH / 2;
2521
- lines.forEach((line, lineIndex) => ctx.fillText(line, centerX, startY + lineIndex * lineH));
2521
+ lines.forEach((line, lineIndex) => ctx.fillText(line, pillX + padding, startY + lineIndex * lineH));
2522
2522
  ctx.font = prevFont;
2523
2523
  };
2524
- drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, cx, targetY, profitLine);
2525
- drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, cx, stopY, lossLine);
2524
+ const labelLeftX = boxX0 + 10;
2525
+ drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, labelLeftX, targetY, profitLine);
2526
+ drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, labelLeftX, stopY, lossLine);
2526
2527
  let centerLines;
2527
2528
  let centerBg;
2528
2529
  if (positionHit) {
@@ -2535,7 +2536,7 @@ function createChart(element, options = {}) {
2535
2536
  centerLines = [line1, `Risk/reward ratio: ${rr.toFixed(2)}`];
2536
2537
  centerBg = hexToRgba(drawing.color, 0.92);
2537
2538
  }
2538
- drawPositionPill(centerLines, cx, entryY, centerBg);
2539
+ drawPositionPill(centerLines, labelLeftX, entryY, centerBg);
2539
2540
  if (drawing.label) {
2540
2541
  drawDrawingLabel(drawing.label, cx, Math.min(targetY, stopY) - 4, drawing.color);
2541
2542
  }
@@ -4829,6 +4830,22 @@ function createChart(element, options = {}) {
4829
4830
  canvas.addEventListener("wheel", onWheel, { passive: false });
4830
4831
  canvas.addEventListener("dblclick", onDoubleClick);
4831
4832
  canvas.addEventListener("contextmenu", onContextMenu);
4833
+ const onModifierKeyChange = (event) => {
4834
+ const active = event.metaKey || event.ctrlKey;
4835
+ if (active !== magnetModifierActive) {
4836
+ magnetModifierActive = active;
4837
+ if (draftDrawing) draw();
4838
+ }
4839
+ };
4840
+ const onWindowBlurMagnet = () => {
4841
+ magnetModifierActive = false;
4842
+ };
4843
+ const hasWindow = typeof window !== "undefined";
4844
+ if (hasWindow) {
4845
+ window.addEventListener("keydown", onModifierKeyChange);
4846
+ window.addEventListener("keyup", onModifierKeyChange);
4847
+ window.addEventListener("blur", onWindowBlurMagnet);
4848
+ }
4832
4849
  const updateOptions = (nextOptions) => {
4833
4850
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
4834
4851
  const previousWidth = width;
@@ -5145,6 +5162,11 @@ function createChart(element, options = {}) {
5145
5162
  canvas.removeEventListener("wheel", onWheel);
5146
5163
  canvas.removeEventListener("dblclick", onDoubleClick);
5147
5164
  canvas.removeEventListener("contextmenu", onContextMenu);
5165
+ if (hasWindow) {
5166
+ window.removeEventListener("keydown", onModifierKeyChange);
5167
+ window.removeEventListener("keyup", onModifierKeyChange);
5168
+ window.removeEventListener("blur", onWindowBlurMagnet);
5169
+ }
5148
5170
  element.innerHTML = "";
5149
5171
  };
5150
5172
  draw();
package/dist/index.cjs CHANGED
@@ -2527,28 +2527,29 @@ function createChart(element, options = {}) {
2527
2527
  const formatAmount = (value) => value.toFixed(2);
2528
2528
  const targetAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * target.price * effectivePointValue)}` : "";
2529
2529
  const stopAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * stop.price * effectivePointValue)}` : "";
2530
- const drawPositionPill = (text, centerX, centerY, bg) => {
2530
+ const drawPositionPill = (text, leftX2, centerY, bg) => {
2531
2531
  const lines = Array.isArray(text) ? text : [text];
2532
2532
  const prevFont = ctx.font;
2533
- ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2534
- const padding = 6;
2535
- const lineH = 14;
2533
+ ctx.font = `500 10px ${mergedOptions.fontFamily}`;
2534
+ const padding = 5;
2535
+ const lineH = 12;
2536
2536
  const textW = Math.max(...lines.map((line) => ctx.measureText(line).width));
2537
2537
  const pillW = textW + padding * 2;
2538
- const pillH = lines.length === 1 ? 18 : lines.length * lineH + 6;
2539
- const pillX = centerX - pillW / 2;
2538
+ const pillH = lines.length === 1 ? 15 : lines.length * lineH + 5;
2539
+ const pillX = leftX2;
2540
2540
  const pillY = centerY - pillH / 2;
2541
2541
  ctx.fillStyle = bg;
2542
- fillRoundedRect(pillX, pillY, pillW, pillH, 4);
2542
+ fillRoundedRect(pillX, pillY, pillW, pillH, 3);
2543
2543
  ctx.fillStyle = labelTextColor;
2544
- ctx.textAlign = "center";
2544
+ ctx.textAlign = "left";
2545
2545
  ctx.textBaseline = "middle";
2546
2546
  const startY = pillY + pillH / 2 - (lines.length - 1) * lineH / 2;
2547
- lines.forEach((line, lineIndex) => ctx.fillText(line, centerX, startY + lineIndex * lineH));
2547
+ lines.forEach((line, lineIndex) => ctx.fillText(line, pillX + padding, startY + lineIndex * lineH));
2548
2548
  ctx.font = prevFont;
2549
2549
  };
2550
- drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, cx, targetY, profitLine);
2551
- drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, cx, stopY, lossLine);
2550
+ const labelLeftX = boxX0 + 10;
2551
+ drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, labelLeftX, targetY, profitLine);
2552
+ drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, labelLeftX, stopY, lossLine);
2552
2553
  let centerLines;
2553
2554
  let centerBg;
2554
2555
  if (positionHit) {
@@ -2561,7 +2562,7 @@ function createChart(element, options = {}) {
2561
2562
  centerLines = [line1, `Risk/reward ratio: ${rr.toFixed(2)}`];
2562
2563
  centerBg = hexToRgba(drawing.color, 0.92);
2563
2564
  }
2564
- drawPositionPill(centerLines, cx, entryY, centerBg);
2565
+ drawPositionPill(centerLines, labelLeftX, entryY, centerBg);
2565
2566
  if (drawing.label) {
2566
2567
  drawDrawingLabel(drawing.label, cx, Math.min(targetY, stopY) - 4, drawing.color);
2567
2568
  }
@@ -4855,6 +4856,22 @@ function createChart(element, options = {}) {
4855
4856
  canvas.addEventListener("wheel", onWheel, { passive: false });
4856
4857
  canvas.addEventListener("dblclick", onDoubleClick);
4857
4858
  canvas.addEventListener("contextmenu", onContextMenu);
4859
+ const onModifierKeyChange = (event) => {
4860
+ const active = event.metaKey || event.ctrlKey;
4861
+ if (active !== magnetModifierActive) {
4862
+ magnetModifierActive = active;
4863
+ if (draftDrawing) draw();
4864
+ }
4865
+ };
4866
+ const onWindowBlurMagnet = () => {
4867
+ magnetModifierActive = false;
4868
+ };
4869
+ const hasWindow = typeof window !== "undefined";
4870
+ if (hasWindow) {
4871
+ window.addEventListener("keydown", onModifierKeyChange);
4872
+ window.addEventListener("keyup", onModifierKeyChange);
4873
+ window.addEventListener("blur", onWindowBlurMagnet);
4874
+ }
4858
4875
  const updateOptions = (nextOptions) => {
4859
4876
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
4860
4877
  const previousWidth = width;
@@ -5171,6 +5188,11 @@ function createChart(element, options = {}) {
5171
5188
  canvas.removeEventListener("wheel", onWheel);
5172
5189
  canvas.removeEventListener("dblclick", onDoubleClick);
5173
5190
  canvas.removeEventListener("contextmenu", onContextMenu);
5191
+ if (hasWindow) {
5192
+ window.removeEventListener("keydown", onModifierKeyChange);
5193
+ window.removeEventListener("keyup", onModifierKeyChange);
5194
+ window.removeEventListener("blur", onWindowBlurMagnet);
5195
+ }
5174
5196
  element.innerHTML = "";
5175
5197
  };
5176
5198
  draw();
package/dist/index.js CHANGED
@@ -2501,28 +2501,29 @@ function createChart(element, options = {}) {
2501
2501
  const formatAmount = (value) => value.toFixed(2);
2502
2502
  const targetAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * target.price * effectivePointValue)}` : "";
2503
2503
  const stopAmountText = hasMoney ? `, Amount: ${formatAmount(qtyRaw * stop.price * effectivePointValue)}` : "";
2504
- const drawPositionPill = (text, centerX, centerY, bg) => {
2504
+ const drawPositionPill = (text, leftX2, centerY, bg) => {
2505
2505
  const lines = Array.isArray(text) ? text : [text];
2506
2506
  const prevFont = ctx.font;
2507
- ctx.font = `500 11px ${mergedOptions.fontFamily}`;
2508
- const padding = 6;
2509
- const lineH = 14;
2507
+ ctx.font = `500 10px ${mergedOptions.fontFamily}`;
2508
+ const padding = 5;
2509
+ const lineH = 12;
2510
2510
  const textW = Math.max(...lines.map((line) => ctx.measureText(line).width));
2511
2511
  const pillW = textW + padding * 2;
2512
- const pillH = lines.length === 1 ? 18 : lines.length * lineH + 6;
2513
- const pillX = centerX - pillW / 2;
2512
+ const pillH = lines.length === 1 ? 15 : lines.length * lineH + 5;
2513
+ const pillX = leftX2;
2514
2514
  const pillY = centerY - pillH / 2;
2515
2515
  ctx.fillStyle = bg;
2516
- fillRoundedRect(pillX, pillY, pillW, pillH, 4);
2516
+ fillRoundedRect(pillX, pillY, pillW, pillH, 3);
2517
2517
  ctx.fillStyle = labelTextColor;
2518
- ctx.textAlign = "center";
2518
+ ctx.textAlign = "left";
2519
2519
  ctx.textBaseline = "middle";
2520
2520
  const startY = pillY + pillH / 2 - (lines.length - 1) * lineH / 2;
2521
- lines.forEach((line, lineIndex) => ctx.fillText(line, centerX, startY + lineIndex * lineH));
2521
+ lines.forEach((line, lineIndex) => ctx.fillText(line, pillX + padding, startY + lineIndex * lineH));
2522
2522
  ctx.font = prevFont;
2523
2523
  };
2524
- drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, cx, targetY, profitLine);
2525
- drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, cx, stopY, lossLine);
2524
+ const labelLeftX = boxX0 + 10;
2525
+ drawPositionPill(`Target: ${formatPrice(targetDist)} (${pctOfDist(targetDist)})${ticksOfDist(targetDist)}${targetAmountText}`, labelLeftX, targetY, profitLine);
2526
+ drawPositionPill(`Stop: ${formatPrice(stopDist)} (${pctOfDist(stopDist)})${ticksOfDist(stopDist)}${stopAmountText}`, labelLeftX, stopY, lossLine);
2526
2527
  let centerLines;
2527
2528
  let centerBg;
2528
2529
  if (positionHit) {
@@ -2535,7 +2536,7 @@ function createChart(element, options = {}) {
2535
2536
  centerLines = [line1, `Risk/reward ratio: ${rr.toFixed(2)}`];
2536
2537
  centerBg = hexToRgba(drawing.color, 0.92);
2537
2538
  }
2538
- drawPositionPill(centerLines, cx, entryY, centerBg);
2539
+ drawPositionPill(centerLines, labelLeftX, entryY, centerBg);
2539
2540
  if (drawing.label) {
2540
2541
  drawDrawingLabel(drawing.label, cx, Math.min(targetY, stopY) - 4, drawing.color);
2541
2542
  }
@@ -4829,6 +4830,22 @@ function createChart(element, options = {}) {
4829
4830
  canvas.addEventListener("wheel", onWheel, { passive: false });
4830
4831
  canvas.addEventListener("dblclick", onDoubleClick);
4831
4832
  canvas.addEventListener("contextmenu", onContextMenu);
4833
+ const onModifierKeyChange = (event) => {
4834
+ const active = event.metaKey || event.ctrlKey;
4835
+ if (active !== magnetModifierActive) {
4836
+ magnetModifierActive = active;
4837
+ if (draftDrawing) draw();
4838
+ }
4839
+ };
4840
+ const onWindowBlurMagnet = () => {
4841
+ magnetModifierActive = false;
4842
+ };
4843
+ const hasWindow = typeof window !== "undefined";
4844
+ if (hasWindow) {
4845
+ window.addEventListener("keydown", onModifierKeyChange);
4846
+ window.addEventListener("keyup", onModifierKeyChange);
4847
+ window.addEventListener("blur", onWindowBlurMagnet);
4848
+ }
4832
4849
  const updateOptions = (nextOptions) => {
4833
4850
  const wasTickerSmoothingEnabled = mergedOptions.tickerLine?.smoothing ?? false;
4834
4851
  const previousWidth = width;
@@ -5145,6 +5162,11 @@ function createChart(element, options = {}) {
5145
5162
  canvas.removeEventListener("wheel", onWheel);
5146
5163
  canvas.removeEventListener("dblclick", onDoubleClick);
5147
5164
  canvas.removeEventListener("contextmenu", onContextMenu);
5165
+ if (hasWindow) {
5166
+ window.removeEventListener("keydown", onModifierKeyChange);
5167
+ window.removeEventListener("keyup", onModifierKeyChange);
5168
+ window.removeEventListener("blur", onWindowBlurMagnet);
5169
+ }
5148
5170
  element.innerHTML = "";
5149
5171
  };
5150
5172
  draw();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.91",
3
+ "version": "0.1.93",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",