hyperprop-charting-library 0.1.60 → 0.1.62

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.
@@ -964,6 +964,8 @@ function createChart(element, options = {}) {
964
964
  let drawingSelectHandler = null;
965
965
  let drawingHoverHandler = null;
966
966
  let lastHoveredDrawingId = null;
967
+ const drawingToolDefaults = /* @__PURE__ */ new Map();
968
+ const getDrawingToolDefaults = (tool) => drawingToolDefaults.get(tool) ?? {};
967
969
  const emitDrawingsChange = () => {
968
970
  drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
969
971
  };
@@ -2021,16 +2023,17 @@ function createChart(element, options = {}) {
2021
2023
  return chartBottom - (price - yMin) / yRange * chartHeight;
2022
2024
  };
2023
2025
  const xFromDrawingPoint = (point) => chartLeft + (point.index + 0.5 - xStart) / xSpan * chartWidth;
2024
- const FIB_LEVELS = [
2025
- { ratio: 0, color: "#787b86" },
2026
- { ratio: 0.236, color: "#f23645", band: "rgba(242,54,69,0.10)" },
2027
- { ratio: 0.382, color: "#ff9800", band: "rgba(255,152,0,0.10)" },
2028
- { ratio: 0.5, color: "#4caf50", band: "rgba(76,175,80,0.10)" },
2029
- { ratio: 0.618, color: "#089981", band: "rgba(8,153,129,0.10)" },
2030
- { ratio: 0.786, color: "#00bcd4", band: "rgba(0,188,212,0.10)" },
2031
- { ratio: 1, color: "#787b86", band: "rgba(120,123,134,0.10)" },
2032
- { ratio: 1.618, color: "#2962ff", band: "rgba(41,98,255,0.08)" }
2033
- ];
2026
+ const FIB_RATIOS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
2027
+ const hexToRgba = (hex, alpha) => {
2028
+ const cleaned = hex.replace("#", "");
2029
+ if (cleaned.length !== 6) {
2030
+ return `rgba(0,0,0,${alpha})`;
2031
+ }
2032
+ const r = parseInt(cleaned.slice(0, 2), 16);
2033
+ const g = parseInt(cleaned.slice(2, 4), 16);
2034
+ const b = parseInt(cleaned.slice(4, 6), 16);
2035
+ return `rgba(${r},${g},${b},${alpha})`;
2036
+ };
2034
2037
  const drawDrawingHandle = (x, y, color) => {
2035
2038
  ctx.save();
2036
2039
  ctx.setLineDash([]);
@@ -2117,28 +2120,27 @@ function createChart(element, options = {}) {
2117
2120
  const secondY = yFromPrice(second.price);
2118
2121
  const lineLeft = chartLeft;
2119
2122
  const lineRight = chartRight;
2120
- const levelLines = FIB_LEVELS.map((level) => {
2121
- const price = first.price + (second.price - first.price) * (1 - level.ratio);
2122
- return { ...level, price, y: yFromPrice(price) };
2123
+ const levelLines = FIB_RATIOS.map((ratio) => {
2124
+ const price = first.price + (second.price - first.price) * (1 - ratio);
2125
+ return { ratio, price, y: yFromPrice(price) };
2123
2126
  });
2127
+ const bandColor = hexToRgba(drawing.color, 0.1);
2124
2128
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2125
2129
  const top = levelLines[index];
2126
2130
  const bottom = levelLines[index + 1];
2127
- const fillColor = bottom.band ?? top.band;
2128
- if (!fillColor) continue;
2129
2131
  const bandTop = Math.min(top.y, bottom.y);
2130
2132
  const bandBottom = Math.max(top.y, bottom.y);
2131
2133
  ctx.save();
2132
- ctx.fillStyle = fillColor;
2134
+ ctx.fillStyle = bandColor;
2133
2135
  ctx.globalAlpha = draft ? 0.5 : 1;
2134
2136
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2135
2137
  ctx.restore();
2136
2138
  }
2137
2139
  ctx.save();
2138
2140
  ctx.lineWidth = drawing.width;
2141
+ ctx.strokeStyle = drawing.color;
2139
2142
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2140
2143
  for (const level of levelLines) {
2141
- ctx.strokeStyle = level.color;
2142
2144
  ctx.beginPath();
2143
2145
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2144
2146
  ctx.lineTo(crisp(lineRight), crisp(level.y));
@@ -2146,7 +2148,7 @@ function createChart(element, options = {}) {
2146
2148
  }
2147
2149
  ctx.restore();
2148
2150
  ctx.save();
2149
- ctx.strokeStyle = "rgba(148,163,184,0.7)";
2151
+ ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
2150
2152
  ctx.setLineDash([4, 4]);
2151
2153
  ctx.lineWidth = 1;
2152
2154
  ctx.beginPath();
@@ -2166,7 +2168,7 @@ function createChart(element, options = {}) {
2166
2168
  const bgY = level.y - 9;
2167
2169
  ctx.fillStyle = mergedOptions.backgroundColor;
2168
2170
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2169
- ctx.fillStyle = level.color;
2171
+ ctx.fillStyle = drawing.color;
2170
2172
  ctx.textAlign = "left";
2171
2173
  ctx.textBaseline = "middle";
2172
2174
  ctx.fillText(labelText, bgX + padding, bgY + 8);
@@ -3346,13 +3348,14 @@ function createChart(element, options = {}) {
3346
3348
  return false;
3347
3349
  }
3348
3350
  if (activeDrawingTool === "horizontal-line") {
3351
+ const defaults = getDrawingToolDefaults("horizontal-line");
3349
3352
  drawings.push(
3350
3353
  normalizeDrawingState({
3351
3354
  type: "horizontal-line",
3352
3355
  points: [point],
3353
- color: "#38bdf8",
3354
- style: "dotted",
3355
- width: 1
3356
+ color: defaults.color ?? "#38bdf8",
3357
+ style: defaults.style ?? "solid",
3358
+ width: defaults.width ?? 1
3356
3359
  })
3357
3360
  );
3358
3361
  emitDrawingsChange();
@@ -3372,12 +3375,13 @@ function createChart(element, options = {}) {
3372
3375
  draw();
3373
3376
  return true;
3374
3377
  }
3378
+ const defaults = getDrawingToolDefaults("trendline");
3375
3379
  draftDrawing = normalizeDrawingState({
3376
3380
  type: "trendline",
3377
3381
  points: [point, point],
3378
- color: "#2563eb",
3379
- style: "solid",
3380
- width: 2
3382
+ color: defaults.color ?? "#2563eb",
3383
+ style: defaults.style ?? "solid",
3384
+ width: defaults.width ?? 2
3381
3385
  });
3382
3386
  draw();
3383
3387
  return true;
@@ -3395,18 +3399,26 @@ function createChart(element, options = {}) {
3395
3399
  draw();
3396
3400
  return true;
3397
3401
  }
3402
+ const defaults = getDrawingToolDefaults("fib-retracement");
3398
3403
  draftDrawing = normalizeDrawingState({
3399
3404
  type: "fib-retracement",
3400
3405
  points: [point, point],
3401
- color: "#2563eb",
3402
- style: "solid",
3403
- width: 1
3406
+ color: defaults.color ?? "#2563eb",
3407
+ style: defaults.style ?? "solid",
3408
+ width: defaults.width ?? 1
3404
3409
  });
3405
3410
  draw();
3406
3411
  return true;
3407
3412
  }
3408
3413
  return false;
3409
3414
  };
3415
+ const setDrawingDefaults = (tool, defaults) => {
3416
+ if (defaults === null) {
3417
+ drawingToolDefaults.delete(tool);
3418
+ return;
3419
+ }
3420
+ drawingToolDefaults.set(tool, { ...defaults });
3421
+ };
3410
3422
  const updateDrawingDrag = (x, y) => {
3411
3423
  if (!drawingDragState) {
3412
3424
  return false;
@@ -4255,6 +4267,7 @@ function createChart(element, options = {}) {
4255
4267
  onDrawingsChange,
4256
4268
  onDrawingSelect,
4257
4269
  onDrawingHover,
4270
+ setDrawingDefaults,
4258
4271
  setDoubleClickEnabled,
4259
4272
  setDoubleClickAction,
4260
4273
  registerIndicator,
@@ -73,6 +73,7 @@ interface DrawingHoverEvent {
73
73
  x: number;
74
74
  y: number;
75
75
  }
76
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
76
77
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
77
78
  id?: string;
78
79
  type: string;
@@ -405,6 +406,7 @@ interface ChartInstance {
405
406
  onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
406
407
  onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
407
408
  onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
409
+ setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
408
410
  setDoubleClickEnabled: (enabled: boolean) => void;
409
411
  setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
410
412
  registerIndicator: (plugin: IndicatorPlugin<any>) => void;
@@ -440,4 +442,4 @@ interface ViewportState {
440
442
  }
441
443
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
442
444
 
443
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
445
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
@@ -940,6 +940,8 @@ function createChart(element, options = {}) {
940
940
  let drawingSelectHandler = null;
941
941
  let drawingHoverHandler = null;
942
942
  let lastHoveredDrawingId = null;
943
+ const drawingToolDefaults = /* @__PURE__ */ new Map();
944
+ const getDrawingToolDefaults = (tool) => drawingToolDefaults.get(tool) ?? {};
943
945
  const emitDrawingsChange = () => {
944
946
  drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
945
947
  };
@@ -1997,16 +1999,17 @@ function createChart(element, options = {}) {
1997
1999
  return chartBottom - (price - yMin) / yRange * chartHeight;
1998
2000
  };
1999
2001
  const xFromDrawingPoint = (point) => chartLeft + (point.index + 0.5 - xStart) / xSpan * chartWidth;
2000
- const FIB_LEVELS = [
2001
- { ratio: 0, color: "#787b86" },
2002
- { ratio: 0.236, color: "#f23645", band: "rgba(242,54,69,0.10)" },
2003
- { ratio: 0.382, color: "#ff9800", band: "rgba(255,152,0,0.10)" },
2004
- { ratio: 0.5, color: "#4caf50", band: "rgba(76,175,80,0.10)" },
2005
- { ratio: 0.618, color: "#089981", band: "rgba(8,153,129,0.10)" },
2006
- { ratio: 0.786, color: "#00bcd4", band: "rgba(0,188,212,0.10)" },
2007
- { ratio: 1, color: "#787b86", band: "rgba(120,123,134,0.10)" },
2008
- { ratio: 1.618, color: "#2962ff", band: "rgba(41,98,255,0.08)" }
2009
- ];
2002
+ const FIB_RATIOS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
2003
+ const hexToRgba = (hex, alpha) => {
2004
+ const cleaned = hex.replace("#", "");
2005
+ if (cleaned.length !== 6) {
2006
+ return `rgba(0,0,0,${alpha})`;
2007
+ }
2008
+ const r = parseInt(cleaned.slice(0, 2), 16);
2009
+ const g = parseInt(cleaned.slice(2, 4), 16);
2010
+ const b = parseInt(cleaned.slice(4, 6), 16);
2011
+ return `rgba(${r},${g},${b},${alpha})`;
2012
+ };
2010
2013
  const drawDrawingHandle = (x, y, color) => {
2011
2014
  ctx.save();
2012
2015
  ctx.setLineDash([]);
@@ -2093,28 +2096,27 @@ function createChart(element, options = {}) {
2093
2096
  const secondY = yFromPrice(second.price);
2094
2097
  const lineLeft = chartLeft;
2095
2098
  const lineRight = chartRight;
2096
- const levelLines = FIB_LEVELS.map((level) => {
2097
- const price = first.price + (second.price - first.price) * (1 - level.ratio);
2098
- return { ...level, price, y: yFromPrice(price) };
2099
+ const levelLines = FIB_RATIOS.map((ratio) => {
2100
+ const price = first.price + (second.price - first.price) * (1 - ratio);
2101
+ return { ratio, price, y: yFromPrice(price) };
2099
2102
  });
2103
+ const bandColor = hexToRgba(drawing.color, 0.1);
2100
2104
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2101
2105
  const top = levelLines[index];
2102
2106
  const bottom = levelLines[index + 1];
2103
- const fillColor = bottom.band ?? top.band;
2104
- if (!fillColor) continue;
2105
2107
  const bandTop = Math.min(top.y, bottom.y);
2106
2108
  const bandBottom = Math.max(top.y, bottom.y);
2107
2109
  ctx.save();
2108
- ctx.fillStyle = fillColor;
2110
+ ctx.fillStyle = bandColor;
2109
2111
  ctx.globalAlpha = draft ? 0.5 : 1;
2110
2112
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2111
2113
  ctx.restore();
2112
2114
  }
2113
2115
  ctx.save();
2114
2116
  ctx.lineWidth = drawing.width;
2117
+ ctx.strokeStyle = drawing.color;
2115
2118
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2116
2119
  for (const level of levelLines) {
2117
- ctx.strokeStyle = level.color;
2118
2120
  ctx.beginPath();
2119
2121
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2120
2122
  ctx.lineTo(crisp(lineRight), crisp(level.y));
@@ -2122,7 +2124,7 @@ function createChart(element, options = {}) {
2122
2124
  }
2123
2125
  ctx.restore();
2124
2126
  ctx.save();
2125
- ctx.strokeStyle = "rgba(148,163,184,0.7)";
2127
+ ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
2126
2128
  ctx.setLineDash([4, 4]);
2127
2129
  ctx.lineWidth = 1;
2128
2130
  ctx.beginPath();
@@ -2142,7 +2144,7 @@ function createChart(element, options = {}) {
2142
2144
  const bgY = level.y - 9;
2143
2145
  ctx.fillStyle = mergedOptions.backgroundColor;
2144
2146
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2145
- ctx.fillStyle = level.color;
2147
+ ctx.fillStyle = drawing.color;
2146
2148
  ctx.textAlign = "left";
2147
2149
  ctx.textBaseline = "middle";
2148
2150
  ctx.fillText(labelText, bgX + padding, bgY + 8);
@@ -3322,13 +3324,14 @@ function createChart(element, options = {}) {
3322
3324
  return false;
3323
3325
  }
3324
3326
  if (activeDrawingTool === "horizontal-line") {
3327
+ const defaults = getDrawingToolDefaults("horizontal-line");
3325
3328
  drawings.push(
3326
3329
  normalizeDrawingState({
3327
3330
  type: "horizontal-line",
3328
3331
  points: [point],
3329
- color: "#38bdf8",
3330
- style: "dotted",
3331
- width: 1
3332
+ color: defaults.color ?? "#38bdf8",
3333
+ style: defaults.style ?? "solid",
3334
+ width: defaults.width ?? 1
3332
3335
  })
3333
3336
  );
3334
3337
  emitDrawingsChange();
@@ -3348,12 +3351,13 @@ function createChart(element, options = {}) {
3348
3351
  draw();
3349
3352
  return true;
3350
3353
  }
3354
+ const defaults = getDrawingToolDefaults("trendline");
3351
3355
  draftDrawing = normalizeDrawingState({
3352
3356
  type: "trendline",
3353
3357
  points: [point, point],
3354
- color: "#2563eb",
3355
- style: "solid",
3356
- width: 2
3358
+ color: defaults.color ?? "#2563eb",
3359
+ style: defaults.style ?? "solid",
3360
+ width: defaults.width ?? 2
3357
3361
  });
3358
3362
  draw();
3359
3363
  return true;
@@ -3371,18 +3375,26 @@ function createChart(element, options = {}) {
3371
3375
  draw();
3372
3376
  return true;
3373
3377
  }
3378
+ const defaults = getDrawingToolDefaults("fib-retracement");
3374
3379
  draftDrawing = normalizeDrawingState({
3375
3380
  type: "fib-retracement",
3376
3381
  points: [point, point],
3377
- color: "#2563eb",
3378
- style: "solid",
3379
- width: 1
3382
+ color: defaults.color ?? "#2563eb",
3383
+ style: defaults.style ?? "solid",
3384
+ width: defaults.width ?? 1
3380
3385
  });
3381
3386
  draw();
3382
3387
  return true;
3383
3388
  }
3384
3389
  return false;
3385
3390
  };
3391
+ const setDrawingDefaults = (tool, defaults) => {
3392
+ if (defaults === null) {
3393
+ drawingToolDefaults.delete(tool);
3394
+ return;
3395
+ }
3396
+ drawingToolDefaults.set(tool, { ...defaults });
3397
+ };
3386
3398
  const updateDrawingDrag = (x, y) => {
3387
3399
  if (!drawingDragState) {
3388
3400
  return false;
@@ -4231,6 +4243,7 @@ function createChart(element, options = {}) {
4231
4243
  onDrawingsChange,
4232
4244
  onDrawingSelect,
4233
4245
  onDrawingHover,
4246
+ setDrawingDefaults,
4234
4247
  setDoubleClickEnabled,
4235
4248
  setDoubleClickAction,
4236
4249
  registerIndicator,
package/dist/index.cjs CHANGED
@@ -964,6 +964,8 @@ function createChart(element, options = {}) {
964
964
  let drawingSelectHandler = null;
965
965
  let drawingHoverHandler = null;
966
966
  let lastHoveredDrawingId = null;
967
+ const drawingToolDefaults = /* @__PURE__ */ new Map();
968
+ const getDrawingToolDefaults = (tool) => drawingToolDefaults.get(tool) ?? {};
967
969
  const emitDrawingsChange = () => {
968
970
  drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
969
971
  };
@@ -2021,16 +2023,17 @@ function createChart(element, options = {}) {
2021
2023
  return chartBottom - (price - yMin) / yRange * chartHeight;
2022
2024
  };
2023
2025
  const xFromDrawingPoint = (point) => chartLeft + (point.index + 0.5 - xStart) / xSpan * chartWidth;
2024
- const FIB_LEVELS = [
2025
- { ratio: 0, color: "#787b86" },
2026
- { ratio: 0.236, color: "#f23645", band: "rgba(242,54,69,0.10)" },
2027
- { ratio: 0.382, color: "#ff9800", band: "rgba(255,152,0,0.10)" },
2028
- { ratio: 0.5, color: "#4caf50", band: "rgba(76,175,80,0.10)" },
2029
- { ratio: 0.618, color: "#089981", band: "rgba(8,153,129,0.10)" },
2030
- { ratio: 0.786, color: "#00bcd4", band: "rgba(0,188,212,0.10)" },
2031
- { ratio: 1, color: "#787b86", band: "rgba(120,123,134,0.10)" },
2032
- { ratio: 1.618, color: "#2962ff", band: "rgba(41,98,255,0.08)" }
2033
- ];
2026
+ const FIB_RATIOS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
2027
+ const hexToRgba = (hex, alpha) => {
2028
+ const cleaned = hex.replace("#", "");
2029
+ if (cleaned.length !== 6) {
2030
+ return `rgba(0,0,0,${alpha})`;
2031
+ }
2032
+ const r = parseInt(cleaned.slice(0, 2), 16);
2033
+ const g = parseInt(cleaned.slice(2, 4), 16);
2034
+ const b = parseInt(cleaned.slice(4, 6), 16);
2035
+ return `rgba(${r},${g},${b},${alpha})`;
2036
+ };
2034
2037
  const drawDrawingHandle = (x, y, color) => {
2035
2038
  ctx.save();
2036
2039
  ctx.setLineDash([]);
@@ -2117,28 +2120,27 @@ function createChart(element, options = {}) {
2117
2120
  const secondY = yFromPrice(second.price);
2118
2121
  const lineLeft = chartLeft;
2119
2122
  const lineRight = chartRight;
2120
- const levelLines = FIB_LEVELS.map((level) => {
2121
- const price = first.price + (second.price - first.price) * (1 - level.ratio);
2122
- return { ...level, price, y: yFromPrice(price) };
2123
+ const levelLines = FIB_RATIOS.map((ratio) => {
2124
+ const price = first.price + (second.price - first.price) * (1 - ratio);
2125
+ return { ratio, price, y: yFromPrice(price) };
2123
2126
  });
2127
+ const bandColor = hexToRgba(drawing.color, 0.1);
2124
2128
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2125
2129
  const top = levelLines[index];
2126
2130
  const bottom = levelLines[index + 1];
2127
- const fillColor = bottom.band ?? top.band;
2128
- if (!fillColor) continue;
2129
2131
  const bandTop = Math.min(top.y, bottom.y);
2130
2132
  const bandBottom = Math.max(top.y, bottom.y);
2131
2133
  ctx.save();
2132
- ctx.fillStyle = fillColor;
2134
+ ctx.fillStyle = bandColor;
2133
2135
  ctx.globalAlpha = draft ? 0.5 : 1;
2134
2136
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2135
2137
  ctx.restore();
2136
2138
  }
2137
2139
  ctx.save();
2138
2140
  ctx.lineWidth = drawing.width;
2141
+ ctx.strokeStyle = drawing.color;
2139
2142
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2140
2143
  for (const level of levelLines) {
2141
- ctx.strokeStyle = level.color;
2142
2144
  ctx.beginPath();
2143
2145
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2144
2146
  ctx.lineTo(crisp(lineRight), crisp(level.y));
@@ -2146,7 +2148,7 @@ function createChart(element, options = {}) {
2146
2148
  }
2147
2149
  ctx.restore();
2148
2150
  ctx.save();
2149
- ctx.strokeStyle = "rgba(148,163,184,0.7)";
2151
+ ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
2150
2152
  ctx.setLineDash([4, 4]);
2151
2153
  ctx.lineWidth = 1;
2152
2154
  ctx.beginPath();
@@ -2166,7 +2168,7 @@ function createChart(element, options = {}) {
2166
2168
  const bgY = level.y - 9;
2167
2169
  ctx.fillStyle = mergedOptions.backgroundColor;
2168
2170
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2169
- ctx.fillStyle = level.color;
2171
+ ctx.fillStyle = drawing.color;
2170
2172
  ctx.textAlign = "left";
2171
2173
  ctx.textBaseline = "middle";
2172
2174
  ctx.fillText(labelText, bgX + padding, bgY + 8);
@@ -3346,13 +3348,14 @@ function createChart(element, options = {}) {
3346
3348
  return false;
3347
3349
  }
3348
3350
  if (activeDrawingTool === "horizontal-line") {
3351
+ const defaults = getDrawingToolDefaults("horizontal-line");
3349
3352
  drawings.push(
3350
3353
  normalizeDrawingState({
3351
3354
  type: "horizontal-line",
3352
3355
  points: [point],
3353
- color: "#38bdf8",
3354
- style: "dotted",
3355
- width: 1
3356
+ color: defaults.color ?? "#38bdf8",
3357
+ style: defaults.style ?? "solid",
3358
+ width: defaults.width ?? 1
3356
3359
  })
3357
3360
  );
3358
3361
  emitDrawingsChange();
@@ -3372,12 +3375,13 @@ function createChart(element, options = {}) {
3372
3375
  draw();
3373
3376
  return true;
3374
3377
  }
3378
+ const defaults = getDrawingToolDefaults("trendline");
3375
3379
  draftDrawing = normalizeDrawingState({
3376
3380
  type: "trendline",
3377
3381
  points: [point, point],
3378
- color: "#2563eb",
3379
- style: "solid",
3380
- width: 2
3382
+ color: defaults.color ?? "#2563eb",
3383
+ style: defaults.style ?? "solid",
3384
+ width: defaults.width ?? 2
3381
3385
  });
3382
3386
  draw();
3383
3387
  return true;
@@ -3395,18 +3399,26 @@ function createChart(element, options = {}) {
3395
3399
  draw();
3396
3400
  return true;
3397
3401
  }
3402
+ const defaults = getDrawingToolDefaults("fib-retracement");
3398
3403
  draftDrawing = normalizeDrawingState({
3399
3404
  type: "fib-retracement",
3400
3405
  points: [point, point],
3401
- color: "#2563eb",
3402
- style: "solid",
3403
- width: 1
3406
+ color: defaults.color ?? "#2563eb",
3407
+ style: defaults.style ?? "solid",
3408
+ width: defaults.width ?? 1
3404
3409
  });
3405
3410
  draw();
3406
3411
  return true;
3407
3412
  }
3408
3413
  return false;
3409
3414
  };
3415
+ const setDrawingDefaults = (tool, defaults) => {
3416
+ if (defaults === null) {
3417
+ drawingToolDefaults.delete(tool);
3418
+ return;
3419
+ }
3420
+ drawingToolDefaults.set(tool, { ...defaults });
3421
+ };
3410
3422
  const updateDrawingDrag = (x, y) => {
3411
3423
  if (!drawingDragState) {
3412
3424
  return false;
@@ -4255,6 +4267,7 @@ function createChart(element, options = {}) {
4255
4267
  onDrawingsChange,
4256
4268
  onDrawingSelect,
4257
4269
  onDrawingHover,
4270
+ setDrawingDefaults,
4258
4271
  setDoubleClickEnabled,
4259
4272
  setDoubleClickAction,
4260
4273
  registerIndicator,
package/dist/index.d.cts CHANGED
@@ -73,6 +73,7 @@ interface DrawingHoverEvent {
73
73
  x: number;
74
74
  y: number;
75
75
  }
76
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
76
77
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
77
78
  id?: string;
78
79
  type: string;
@@ -405,6 +406,7 @@ interface ChartInstance {
405
406
  onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
406
407
  onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
407
408
  onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
409
+ setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
408
410
  setDoubleClickEnabled: (enabled: boolean) => void;
409
411
  setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
410
412
  registerIndicator: (plugin: IndicatorPlugin<any>) => void;
@@ -440,4 +442,4 @@ interface ViewportState {
440
442
  }
441
443
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
442
444
 
443
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
445
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
package/dist/index.d.ts CHANGED
@@ -73,6 +73,7 @@ interface DrawingHoverEvent {
73
73
  x: number;
74
74
  y: number;
75
75
  }
76
+ type DrawingDefaults = Partial<Pick<DrawingObjectOptions, "color" | "style" | "width">>;
76
77
  interface IndicatorInstanceOptions<TInputs extends Record<string, unknown> = Record<string, unknown>> {
77
78
  id?: string;
78
79
  type: string;
@@ -405,6 +406,7 @@ interface ChartInstance {
405
406
  onDrawingsChange: (handler: ((drawings: DrawingObjectOptions[]) => void) | null) => void;
406
407
  onDrawingSelect: (handler: ((event: DrawingSelectEvent) => void) | null) => void;
407
408
  onDrawingHover: (handler: ((event: DrawingHoverEvent) => void) | null) => void;
409
+ setDrawingDefaults: (tool: DrawingToolType, defaults: DrawingDefaults | null) => void;
408
410
  setDoubleClickEnabled: (enabled: boolean) => void;
409
411
  setDoubleClickAction: (action: "reset" | "placeLimitOrder") => void;
410
412
  registerIndicator: (plugin: IndicatorPlugin<any>) => void;
@@ -440,4 +442,4 @@ interface ViewportState {
440
442
  }
441
443
  declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
442
444
 
443
- export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
445
+ export { type AxisOptions, type BuiltInIndicatorInfo, type ChartClickEvent, type ChartInstance, type ChartOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingToolType, type GridOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type LabelsOptions, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, type PriceLineOptions, type TickerLineOptions, type ViewportState, type WatermarkOptions, createChart };
package/dist/index.js CHANGED
@@ -940,6 +940,8 @@ function createChart(element, options = {}) {
940
940
  let drawingSelectHandler = null;
941
941
  let drawingHoverHandler = null;
942
942
  let lastHoveredDrawingId = null;
943
+ const drawingToolDefaults = /* @__PURE__ */ new Map();
944
+ const getDrawingToolDefaults = (tool) => drawingToolDefaults.get(tool) ?? {};
943
945
  const emitDrawingsChange = () => {
944
946
  drawingsChangeHandler?.(drawings.map((drawing) => serializeDrawing(drawing)));
945
947
  };
@@ -1997,16 +1999,17 @@ function createChart(element, options = {}) {
1997
1999
  return chartBottom - (price - yMin) / yRange * chartHeight;
1998
2000
  };
1999
2001
  const xFromDrawingPoint = (point) => chartLeft + (point.index + 0.5 - xStart) / xSpan * chartWidth;
2000
- const FIB_LEVELS = [
2001
- { ratio: 0, color: "#787b86" },
2002
- { ratio: 0.236, color: "#f23645", band: "rgba(242,54,69,0.10)" },
2003
- { ratio: 0.382, color: "#ff9800", band: "rgba(255,152,0,0.10)" },
2004
- { ratio: 0.5, color: "#4caf50", band: "rgba(76,175,80,0.10)" },
2005
- { ratio: 0.618, color: "#089981", band: "rgba(8,153,129,0.10)" },
2006
- { ratio: 0.786, color: "#00bcd4", band: "rgba(0,188,212,0.10)" },
2007
- { ratio: 1, color: "#787b86", band: "rgba(120,123,134,0.10)" },
2008
- { ratio: 1.618, color: "#2962ff", band: "rgba(41,98,255,0.08)" }
2009
- ];
2002
+ const FIB_RATIOS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
2003
+ const hexToRgba = (hex, alpha) => {
2004
+ const cleaned = hex.replace("#", "");
2005
+ if (cleaned.length !== 6) {
2006
+ return `rgba(0,0,0,${alpha})`;
2007
+ }
2008
+ const r = parseInt(cleaned.slice(0, 2), 16);
2009
+ const g = parseInt(cleaned.slice(2, 4), 16);
2010
+ const b = parseInt(cleaned.slice(4, 6), 16);
2011
+ return `rgba(${r},${g},${b},${alpha})`;
2012
+ };
2010
2013
  const drawDrawingHandle = (x, y, color) => {
2011
2014
  ctx.save();
2012
2015
  ctx.setLineDash([]);
@@ -2093,28 +2096,27 @@ function createChart(element, options = {}) {
2093
2096
  const secondY = yFromPrice(second.price);
2094
2097
  const lineLeft = chartLeft;
2095
2098
  const lineRight = chartRight;
2096
- const levelLines = FIB_LEVELS.map((level) => {
2097
- const price = first.price + (second.price - first.price) * (1 - level.ratio);
2098
- return { ...level, price, y: yFromPrice(price) };
2099
+ const levelLines = FIB_RATIOS.map((ratio) => {
2100
+ const price = first.price + (second.price - first.price) * (1 - ratio);
2101
+ return { ratio, price, y: yFromPrice(price) };
2099
2102
  });
2103
+ const bandColor = hexToRgba(drawing.color, 0.1);
2100
2104
  for (let index = 0; index < levelLines.length - 1; index += 1) {
2101
2105
  const top = levelLines[index];
2102
2106
  const bottom = levelLines[index + 1];
2103
- const fillColor = bottom.band ?? top.band;
2104
- if (!fillColor) continue;
2105
2107
  const bandTop = Math.min(top.y, bottom.y);
2106
2108
  const bandBottom = Math.max(top.y, bottom.y);
2107
2109
  ctx.save();
2108
- ctx.fillStyle = fillColor;
2110
+ ctx.fillStyle = bandColor;
2109
2111
  ctx.globalAlpha = draft ? 0.5 : 1;
2110
2112
  ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
2111
2113
  ctx.restore();
2112
2114
  }
2113
2115
  ctx.save();
2114
2116
  ctx.lineWidth = drawing.width;
2117
+ ctx.strokeStyle = drawing.color;
2115
2118
  applyDashPattern(drawing.style, dashPatterns.dotted, dashPatterns.dashed);
2116
2119
  for (const level of levelLines) {
2117
- ctx.strokeStyle = level.color;
2118
2120
  ctx.beginPath();
2119
2121
  ctx.moveTo(crisp(lineLeft), crisp(level.y));
2120
2122
  ctx.lineTo(crisp(lineRight), crisp(level.y));
@@ -2122,7 +2124,7 @@ function createChart(element, options = {}) {
2122
2124
  }
2123
2125
  ctx.restore();
2124
2126
  ctx.save();
2125
- ctx.strokeStyle = "rgba(148,163,184,0.7)";
2127
+ ctx.strokeStyle = hexToRgba(drawing.color, 0.5);
2126
2128
  ctx.setLineDash([4, 4]);
2127
2129
  ctx.lineWidth = 1;
2128
2130
  ctx.beginPath();
@@ -2142,7 +2144,7 @@ function createChart(element, options = {}) {
2142
2144
  const bgY = level.y - 9;
2143
2145
  ctx.fillStyle = mergedOptions.backgroundColor;
2144
2146
  fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
2145
- ctx.fillStyle = level.color;
2147
+ ctx.fillStyle = drawing.color;
2146
2148
  ctx.textAlign = "left";
2147
2149
  ctx.textBaseline = "middle";
2148
2150
  ctx.fillText(labelText, bgX + padding, bgY + 8);
@@ -3322,13 +3324,14 @@ function createChart(element, options = {}) {
3322
3324
  return false;
3323
3325
  }
3324
3326
  if (activeDrawingTool === "horizontal-line") {
3327
+ const defaults = getDrawingToolDefaults("horizontal-line");
3325
3328
  drawings.push(
3326
3329
  normalizeDrawingState({
3327
3330
  type: "horizontal-line",
3328
3331
  points: [point],
3329
- color: "#38bdf8",
3330
- style: "dotted",
3331
- width: 1
3332
+ color: defaults.color ?? "#38bdf8",
3333
+ style: defaults.style ?? "solid",
3334
+ width: defaults.width ?? 1
3332
3335
  })
3333
3336
  );
3334
3337
  emitDrawingsChange();
@@ -3348,12 +3351,13 @@ function createChart(element, options = {}) {
3348
3351
  draw();
3349
3352
  return true;
3350
3353
  }
3354
+ const defaults = getDrawingToolDefaults("trendline");
3351
3355
  draftDrawing = normalizeDrawingState({
3352
3356
  type: "trendline",
3353
3357
  points: [point, point],
3354
- color: "#2563eb",
3355
- style: "solid",
3356
- width: 2
3358
+ color: defaults.color ?? "#2563eb",
3359
+ style: defaults.style ?? "solid",
3360
+ width: defaults.width ?? 2
3357
3361
  });
3358
3362
  draw();
3359
3363
  return true;
@@ -3371,18 +3375,26 @@ function createChart(element, options = {}) {
3371
3375
  draw();
3372
3376
  return true;
3373
3377
  }
3378
+ const defaults = getDrawingToolDefaults("fib-retracement");
3374
3379
  draftDrawing = normalizeDrawingState({
3375
3380
  type: "fib-retracement",
3376
3381
  points: [point, point],
3377
- color: "#2563eb",
3378
- style: "solid",
3379
- width: 1
3382
+ color: defaults.color ?? "#2563eb",
3383
+ style: defaults.style ?? "solid",
3384
+ width: defaults.width ?? 1
3380
3385
  });
3381
3386
  draw();
3382
3387
  return true;
3383
3388
  }
3384
3389
  return false;
3385
3390
  };
3391
+ const setDrawingDefaults = (tool, defaults) => {
3392
+ if (defaults === null) {
3393
+ drawingToolDefaults.delete(tool);
3394
+ return;
3395
+ }
3396
+ drawingToolDefaults.set(tool, { ...defaults });
3397
+ };
3386
3398
  const updateDrawingDrag = (x, y) => {
3387
3399
  if (!drawingDragState) {
3388
3400
  return false;
@@ -4231,6 +4243,7 @@ function createChart(element, options = {}) {
4231
4243
  onDrawingsChange,
4232
4244
  onDrawingSelect,
4233
4245
  onDrawingHover,
4246
+ setDrawingDefaults,
4234
4247
  setDoubleClickEnabled,
4235
4248
  setDoubleClickAction,
4236
4249
  registerIndicator,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyperprop-charting-library",
3
- "version": "0.1.60",
3
+ "version": "0.1.62",
4
4
  "description": "Lightweight TypeScript charting core",
5
5
  "type": "module",
6
6
  "main": "./dist/hyperprop-charting-library.cjs",