hyperprop-charting-library 0.1.152 → 0.1.154
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/hyperprop-charting-library.cjs +137 -33
- package/dist/hyperprop-charting-library.d.ts +40 -1
- package/dist/hyperprop-charting-library.js +134 -33
- package/dist/index.cjs +137 -33
- package/dist/index.d.cts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +134 -33
- package/package.json +1 -1
|
@@ -22,6 +22,9 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
CHART_THEMES: () => CHART_THEMES,
|
|
24
24
|
CHART_THEME_NAMES: () => CHART_THEME_NAMES,
|
|
25
|
+
DRAWING_ICON_STROKE_WIDTH: () => DRAWING_ICON_STROKE_WIDTH,
|
|
26
|
+
DRAWING_ICON_VIEWBOX: () => DRAWING_ICON_VIEWBOX,
|
|
27
|
+
DRAWING_TOOL_ICONS: () => DRAWING_TOOL_ICONS,
|
|
25
28
|
FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
|
|
26
29
|
POSITION_DEFAULT_COLORS: () => POSITION_DEFAULT_COLORS,
|
|
27
30
|
SCRIPT_SOURCE_INPUT_VALUES: () => SCRIPT_SOURCE_INPUT_VALUES,
|
|
@@ -3168,6 +3171,94 @@ var compileScriptIndicator = (definition) => {
|
|
|
3168
3171
|
return plugin;
|
|
3169
3172
|
};
|
|
3170
3173
|
|
|
3174
|
+
// src/icons.ts
|
|
3175
|
+
var DRAWING_ICON_VIEWBOX = 28;
|
|
3176
|
+
var DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
3177
|
+
var dot = (cx, cy) => ({ kind: "circle", cx, cy, r: 2.1 });
|
|
3178
|
+
var path = (d, extra) => ({
|
|
3179
|
+
kind: "path",
|
|
3180
|
+
d,
|
|
3181
|
+
...extra
|
|
3182
|
+
});
|
|
3183
|
+
var DRAWING_TOOL_ICONS = {
|
|
3184
|
+
"cursor-cross": [path("M14 4v6.5M14 17.5V24M4 14h6.5M17.5 14H24")],
|
|
3185
|
+
"cursor-dot": [{ kind: "circle", cx: 14, cy: 14, r: 2.6, fill: true }],
|
|
3186
|
+
"cursor-arrow": [path("M10 4.5v16.4l4.3-4.1 3 6.7 2.9-1.3-3-6.7h5.9L10 4.5Z")],
|
|
3187
|
+
trendline: [dot(7, 21), dot(21, 7), path("M8.6 19.4 19.4 8.6")],
|
|
3188
|
+
"horizontal-line": [dot(14, 14), path("M3.5 14h8.4M16.1 14h8.4")],
|
|
3189
|
+
"vertical-line": [dot(14, 14), path("M14 3.5v8.4M14 16.1v8.4")],
|
|
3190
|
+
ray: [dot(7.5, 20.5), path("M9 19 24 4")],
|
|
3191
|
+
arrow: [dot(6, 22), path("M7.6 20.4 21.4 6.6"), path("M14.6 6.2h7.2v7.2")],
|
|
3192
|
+
"parallel-channel": [dot(6, 17), dot(17, 6), path("M7.5 15.5 15.5 7.5"), path("M11 23.5 23.5 11")],
|
|
3193
|
+
"fib-retracement": [
|
|
3194
|
+
dot(6, 7),
|
|
3195
|
+
path("M9.6 7h14.9"),
|
|
3196
|
+
path("M3.5 14h21"),
|
|
3197
|
+
dot(6, 21),
|
|
3198
|
+
path("M9.6 21h14.9")
|
|
3199
|
+
],
|
|
3200
|
+
"fib-extension": [
|
|
3201
|
+
dot(6.5, 21.5),
|
|
3202
|
+
dot(12.5, 6.5),
|
|
3203
|
+
path("M7.5 19.1l4-9.2"),
|
|
3204
|
+
path("M17 7h7.5M17 14h7.5M17 21h7.5")
|
|
3205
|
+
],
|
|
3206
|
+
// Long/short: three price levels (target, entry, stop) with anchor dots and
|
|
3207
|
+
// a dotted "price path" diagonal running from entry toward the target.
|
|
3208
|
+
"long-position": [
|
|
3209
|
+
dot(5, 6.5),
|
|
3210
|
+
path("M8.6 6.5h15.9"),
|
|
3211
|
+
dot(5, 16),
|
|
3212
|
+
path("M8.6 16h10.3"),
|
|
3213
|
+
dot(21, 16),
|
|
3214
|
+
path("M8.6 22.5h15.9"),
|
|
3215
|
+
dot(5, 22.5),
|
|
3216
|
+
path("M10.5 14 22 7.8", { dash: "2 3.2" })
|
|
3217
|
+
],
|
|
3218
|
+
"short-position": [
|
|
3219
|
+
dot(5, 21.5),
|
|
3220
|
+
path("M8.6 21.5h15.9"),
|
|
3221
|
+
dot(5, 12),
|
|
3222
|
+
path("M8.6 12h10.3"),
|
|
3223
|
+
dot(21, 12),
|
|
3224
|
+
path("M8.6 5.5h15.9"),
|
|
3225
|
+
dot(5, 5.5),
|
|
3226
|
+
path("M10.5 14 22 20.2", { dash: "2 3.2" })
|
|
3227
|
+
],
|
|
3228
|
+
"price-range": [
|
|
3229
|
+
path("M8 5h12M8 23h12"),
|
|
3230
|
+
path("M14 7v14"),
|
|
3231
|
+
path("M11.2 9.8 14 7l2.8 2.8M11.2 18.2 14 21l2.8-2.8")
|
|
3232
|
+
],
|
|
3233
|
+
// Fixed range VP: two vertical range anchors with the profile bars attached
|
|
3234
|
+
// to the left one.
|
|
3235
|
+
"fixed-range-volume-profile": [
|
|
3236
|
+
path("M5 3.5v15.4"),
|
|
3237
|
+
dot(5, 21.5),
|
|
3238
|
+
dot(23, 6.5),
|
|
3239
|
+
path("M23 9.1v15.4"),
|
|
3240
|
+
{ kind: "rect", x: 5, y: 6, width: 7, height: 3.2 },
|
|
3241
|
+
{ kind: "rect", x: 5, y: 11, width: 10.5, height: 3.2 },
|
|
3242
|
+
{ kind: "rect", x: 5, y: 16, width: 4.5, height: 3.2 }
|
|
3243
|
+
],
|
|
3244
|
+
measure: [
|
|
3245
|
+
path("M4.5 18.5 18.5 4.5l5 5L9.5 23.5Z"),
|
|
3246
|
+
path("m8 15 1.8 1.8M11.5 11.5 14 14M15 8l1.8 1.8")
|
|
3247
|
+
],
|
|
3248
|
+
rectangle: [
|
|
3249
|
+
dot(6, 8),
|
|
3250
|
+
dot(22, 8),
|
|
3251
|
+
dot(22, 20),
|
|
3252
|
+
dot(6, 20),
|
|
3253
|
+
path("M8.1 8h11.8M8.1 20h11.8M6 10.1v7.8M22 10.1v7.8")
|
|
3254
|
+
],
|
|
3255
|
+
ellipse: [path("M6.1 14a7.9 6.9 0 1 0 15.8 0 7.9 6.9 0 1 0-15.8 0"), dot(4, 14), dot(24, 14)],
|
|
3256
|
+
brush: [dot(5, 20), path("M6.9 18.4c2.6-6 5-.6 8.4-3.2 3-2.3 5.4-6 8.2-7.9")],
|
|
3257
|
+
text: [path("M7 8.5V6h14v2.5"), path("M14 6v16M11 22h6")],
|
|
3258
|
+
note: [path("M5.5 5h17v11.5l-6 6h-11V5Z"), path("M22.5 16.5h-6v6")],
|
|
3259
|
+
callout: [path("M4.5 6h19v11.5H13L8 22.5v-5H4.5V6Z")]
|
|
3260
|
+
};
|
|
3261
|
+
|
|
3171
3262
|
// src/themes.ts
|
|
3172
3263
|
var CHART_THEMES = {
|
|
3173
3264
|
midnight: {
|
|
@@ -4690,9 +4781,9 @@ function createChart(element, options = {}) {
|
|
|
4690
4781
|
const groupThousands = (value, decimals) => {
|
|
4691
4782
|
const negative = value < 0;
|
|
4692
4783
|
const fixed = Math.abs(value).toFixed(decimals);
|
|
4693
|
-
const
|
|
4694
|
-
const intPart =
|
|
4695
|
-
const decPart =
|
|
4784
|
+
const dot2 = fixed.indexOf(".");
|
|
4785
|
+
const intPart = dot2 === -1 ? fixed : fixed.slice(0, dot2);
|
|
4786
|
+
const decPart = dot2 === -1 ? "" : fixed.slice(dot2);
|
|
4696
4787
|
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4697
4788
|
return `${negative ? "-" : ""}${grouped}${decPart}`;
|
|
4698
4789
|
};
|
|
@@ -6289,6 +6380,8 @@ function createChart(element, options = {}) {
|
|
|
6289
6380
|
const palette = drawing.colors.length > 0 ? drawing.colors : null;
|
|
6290
6381
|
const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
|
|
6291
6382
|
const move = p1.price - p0.price;
|
|
6383
|
+
const lineLeft = Math.min(x0, x1, x2);
|
|
6384
|
+
const lineRight = Math.max(x0, x1, x2);
|
|
6292
6385
|
const levelLines = FIB_EXT_RATIOS.map((ratio) => {
|
|
6293
6386
|
const price = p2.price + move * ratio;
|
|
6294
6387
|
return { ratio, price, y: yFromPrice(price) };
|
|
@@ -6301,7 +6394,7 @@ function createChart(element, options = {}) {
|
|
|
6301
6394
|
ctx.save();
|
|
6302
6395
|
ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
|
|
6303
6396
|
ctx.globalAlpha = draft ? 0.5 : 1;
|
|
6304
|
-
ctx.fillRect(
|
|
6397
|
+
ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
|
|
6305
6398
|
ctx.restore();
|
|
6306
6399
|
}
|
|
6307
6400
|
ctx.save();
|
|
@@ -6310,8 +6403,8 @@ function createChart(element, options = {}) {
|
|
|
6310
6403
|
levelLines.forEach((level, index) => {
|
|
6311
6404
|
ctx.strokeStyle = levelColorAt(index);
|
|
6312
6405
|
ctx.beginPath();
|
|
6313
|
-
ctx.moveTo(crisp(
|
|
6314
|
-
ctx.lineTo(crisp(
|
|
6406
|
+
ctx.moveTo(crisp(lineLeft), crisp(level.y));
|
|
6407
|
+
ctx.lineTo(crisp(lineRight), crisp(level.y));
|
|
6315
6408
|
ctx.stroke();
|
|
6316
6409
|
});
|
|
6317
6410
|
ctx.restore();
|
|
@@ -6321,7 +6414,7 @@ function createChart(element, options = {}) {
|
|
|
6321
6414
|
const labelText = `${level.ratio} (${formatPrice(level.price)})`;
|
|
6322
6415
|
const textWidth = measureTextWidth(labelText);
|
|
6323
6416
|
const padding = 4;
|
|
6324
|
-
const bgX = chartLeft + 4;
|
|
6417
|
+
const bgX = Math.max(chartLeft + 2, lineLeft - textWidth - padding * 2 - 4);
|
|
6325
6418
|
const bgY = level.y - 9;
|
|
6326
6419
|
ctx.fillStyle = mergedOptions.backgroundColor;
|
|
6327
6420
|
fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
|
|
@@ -7270,12 +7363,12 @@ function createChart(element, options = {}) {
|
|
|
7270
7363
|
const upColumns = new Path2D();
|
|
7271
7364
|
const downColumns = new Path2D();
|
|
7272
7365
|
for (const column of seriesColumns) {
|
|
7273
|
-
const
|
|
7366
|
+
const path2 = column.close >= column.open ? upColumns : downColumns;
|
|
7274
7367
|
const x = column.x + 0.5;
|
|
7275
7368
|
const top = crisp(yFromPrice(column.high));
|
|
7276
7369
|
const bottom = crisp(yFromPrice(column.low));
|
|
7277
|
-
|
|
7278
|
-
|
|
7370
|
+
path2.moveTo(x, top);
|
|
7371
|
+
path2.lineTo(x, bottom === top ? bottom + 1 : bottom);
|
|
7279
7372
|
}
|
|
7280
7373
|
ctx.lineWidth = 1;
|
|
7281
7374
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7418,16 +7511,16 @@ function createChart(element, options = {}) {
|
|
|
7418
7511
|
const displayLow = isLastCandle && actualDirection === "down" ? Math.min(point.l, displayClose) : point.l;
|
|
7419
7512
|
const roundedCenterX = Math.round(chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth);
|
|
7420
7513
|
const direction = isLastCandle ? actualDirection : getCandleDirectionByIndex(index);
|
|
7421
|
-
const
|
|
7514
|
+
const path2 = direction === "up" ? upBars : downBars;
|
|
7422
7515
|
const centerX = roundedCenterX + 0.5;
|
|
7423
|
-
|
|
7424
|
-
|
|
7516
|
+
path2.moveTo(centerX, crisp(yFromPrice(displayHigh)));
|
|
7517
|
+
path2.lineTo(centerX, crisp(yFromPrice(displayLow)));
|
|
7425
7518
|
const openY = crisp(yFromPrice(point.o));
|
|
7426
7519
|
const closeY = crisp(yFromPrice(displayClose));
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7520
|
+
path2.moveTo(centerX - tickLength, openY);
|
|
7521
|
+
path2.lineTo(centerX, openY);
|
|
7522
|
+
path2.moveTo(centerX, closeY);
|
|
7523
|
+
path2.lineTo(centerX + tickLength, closeY);
|
|
7431
7524
|
}
|
|
7432
7525
|
ctx.lineWidth = Math.max(1, candleWickWidth);
|
|
7433
7526
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7495,7 +7588,7 @@ function createChart(element, options = {}) {
|
|
|
7495
7588
|
for (const plan of comparePlans) {
|
|
7496
7589
|
const color = plan.state.options.color ?? "#f59e0b";
|
|
7497
7590
|
const lineWidth = Math.max(1, plan.state.options.lineWidth ?? 1.5);
|
|
7498
|
-
const
|
|
7591
|
+
const path2 = new Path2D();
|
|
7499
7592
|
let started = false;
|
|
7500
7593
|
let firstX = 0;
|
|
7501
7594
|
let lastX = 0;
|
|
@@ -7503,11 +7596,11 @@ function createChart(element, options = {}) {
|
|
|
7503
7596
|
let lastPrice = Number.NaN;
|
|
7504
7597
|
const emit = (x, y) => {
|
|
7505
7598
|
if (!started) {
|
|
7506
|
-
|
|
7599
|
+
path2.moveTo(x, y);
|
|
7507
7600
|
firstX = x;
|
|
7508
7601
|
started = true;
|
|
7509
7602
|
} else {
|
|
7510
|
-
|
|
7603
|
+
path2.lineTo(x, y);
|
|
7511
7604
|
}
|
|
7512
7605
|
lastX = x;
|
|
7513
7606
|
lastY = y;
|
|
@@ -7565,7 +7658,7 @@ function createChart(element, options = {}) {
|
|
|
7565
7658
|
}
|
|
7566
7659
|
if (!started) continue;
|
|
7567
7660
|
if (plan.state.options.style === "area") {
|
|
7568
|
-
const fillPath = new Path2D(
|
|
7661
|
+
const fillPath = new Path2D(path2);
|
|
7569
7662
|
fillPath.lineTo(lastX, chartBottom);
|
|
7570
7663
|
fillPath.lineTo(firstX, chartBottom);
|
|
7571
7664
|
fillPath.closePath();
|
|
@@ -7579,7 +7672,7 @@ function createChart(element, options = {}) {
|
|
|
7579
7672
|
ctx.strokeStyle = color;
|
|
7580
7673
|
ctx.lineWidth = lineWidth;
|
|
7581
7674
|
ctx.lineJoin = "round";
|
|
7582
|
-
ctx.stroke(
|
|
7675
|
+
ctx.stroke(path2);
|
|
7583
7676
|
ctx.restore();
|
|
7584
7677
|
if (Number.isFinite(lastPrice)) {
|
|
7585
7678
|
const label = plan.state.options.label ?? plan.state.options.id;
|
|
@@ -9387,12 +9480,16 @@ function createChart(element, options = {}) {
|
|
|
9387
9480
|
if (Math.hypot(x - x2, y - y2) <= 9 * hitTolerance) {
|
|
9388
9481
|
return { drawing, target: "handle", pointIndex: 1 };
|
|
9389
9482
|
}
|
|
9390
|
-
const
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
const
|
|
9394
|
-
|
|
9395
|
-
|
|
9483
|
+
const fibLeft = Math.min(x1, x2) - 5 * hitTolerance;
|
|
9484
|
+
const fibRight = Math.max(x1, x2) + 5 * hitTolerance;
|
|
9485
|
+
if (x >= fibLeft && x <= fibRight) {
|
|
9486
|
+
const fibRatios = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
|
|
9487
|
+
for (const ratio of fibRatios) {
|
|
9488
|
+
const price = first.price + (second.price - first.price) * (1 - ratio);
|
|
9489
|
+
const lineY = canvasYFromDrawingPrice(price);
|
|
9490
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9491
|
+
return { drawing, target: "line" };
|
|
9492
|
+
}
|
|
9396
9493
|
}
|
|
9397
9494
|
}
|
|
9398
9495
|
} else if (drawing.type === "fib-extension") {
|
|
@@ -9417,11 +9514,15 @@ function createChart(element, options = {}) {
|
|
|
9417
9514
|
return { drawing, target: "handle", pointIndex: 2 };
|
|
9418
9515
|
}
|
|
9419
9516
|
const move = p1.price - p0.price;
|
|
9420
|
-
const
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9517
|
+
const extLeft = Math.min(x0, x1, x2) - 5 * hitTolerance;
|
|
9518
|
+
const extRight = Math.max(x0, x1, x2) + 5 * hitTolerance;
|
|
9519
|
+
if (x >= extLeft && x <= extRight) {
|
|
9520
|
+
const fibExtRatios = [0, 0.382, 0.5, 0.618, 1, 1.272, 1.618, 2.618];
|
|
9521
|
+
for (const ratio of fibExtRatios) {
|
|
9522
|
+
const lineY = canvasYFromDrawingPrice(p2.price + move * ratio);
|
|
9523
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9524
|
+
return { drawing, target: "line" };
|
|
9525
|
+
}
|
|
9425
9526
|
}
|
|
9426
9527
|
}
|
|
9427
9528
|
if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
|
|
@@ -12376,6 +12477,9 @@ function createChart(element, options = {}) {
|
|
|
12376
12477
|
0 && (module.exports = {
|
|
12377
12478
|
CHART_THEMES,
|
|
12378
12479
|
CHART_THEME_NAMES,
|
|
12480
|
+
DRAWING_ICON_STROKE_WIDTH,
|
|
12481
|
+
DRAWING_ICON_VIEWBOX,
|
|
12482
|
+
DRAWING_TOOL_ICONS,
|
|
12379
12483
|
FIB_DEFAULT_PALETTE,
|
|
12380
12484
|
POSITION_DEFAULT_COLORS,
|
|
12381
12485
|
SCRIPT_SOURCE_INPUT_VALUES,
|
|
@@ -1441,6 +1441,45 @@ declare const validateScriptSource: (source: string) => string | null;
|
|
|
1441
1441
|
*/
|
|
1442
1442
|
declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
|
|
1443
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* Hyperprop drawing-tool icon pack — framework-agnostic geometry.
|
|
1446
|
+
*
|
|
1447
|
+
* Original artwork drawn in the visual language traders know from desktop
|
|
1448
|
+
* charting platforms: a 28x28 grid, thin round-capped outlines, and hollow
|
|
1449
|
+
* "anchor" dots on anything line-based (a dot marks a draggable point of the
|
|
1450
|
+
* tool). The data here is plain shape descriptions so every consumer renders
|
|
1451
|
+
* the identical set: the web terminal maps it to DOM `<svg>` elements and the
|
|
1452
|
+
* mobile app to react-native-svg components.
|
|
1453
|
+
*
|
|
1454
|
+
* Design rules when adding icons:
|
|
1455
|
+
* - viewBox 0 0 28 28, strokeWidth 1.6, round caps/joins, no fill (except
|
|
1456
|
+
* shapes marked `fill: true`).
|
|
1457
|
+
* - Anchor dots are hollow circles r=2.1; lines stop ~1.5px short of them.
|
|
1458
|
+
* - Keep 3.5px padding to the edges so glyphs optically match.
|
|
1459
|
+
*/
|
|
1460
|
+
type DrawingIconShape = {
|
|
1461
|
+
kind: "path";
|
|
1462
|
+
d: string;
|
|
1463
|
+
dash?: string;
|
|
1464
|
+
fill?: boolean;
|
|
1465
|
+
} | {
|
|
1466
|
+
kind: "circle";
|
|
1467
|
+
cx: number;
|
|
1468
|
+
cy: number;
|
|
1469
|
+
r: number;
|
|
1470
|
+
fill?: boolean;
|
|
1471
|
+
} | {
|
|
1472
|
+
kind: "rect";
|
|
1473
|
+
x: number;
|
|
1474
|
+
y: number;
|
|
1475
|
+
width: number;
|
|
1476
|
+
height: number;
|
|
1477
|
+
};
|
|
1478
|
+
type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout";
|
|
1479
|
+
declare const DRAWING_ICON_VIEWBOX = 28;
|
|
1480
|
+
declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
1481
|
+
declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
|
|
1482
|
+
|
|
1444
1483
|
/**
|
|
1445
1484
|
* Built-in palettes.
|
|
1446
1485
|
*
|
|
@@ -1465,4 +1504,4 @@ declare const SESSION_PRESETS: Record<SessionPresetName, SessionSpec>;
|
|
|
1465
1504
|
|
|
1466
1505
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
1467
1506
|
|
|
1468
|
-
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
|
1507
|
+
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, DRAWING_ICON_STROKE_WIDTH, DRAWING_ICON_VIEWBOX, DRAWING_TOOL_ICONS, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingIconName, type DrawingIconShape, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
|
@@ -3132,6 +3132,94 @@ var compileScriptIndicator = (definition) => {
|
|
|
3132
3132
|
return plugin;
|
|
3133
3133
|
};
|
|
3134
3134
|
|
|
3135
|
+
// src/icons.ts
|
|
3136
|
+
var DRAWING_ICON_VIEWBOX = 28;
|
|
3137
|
+
var DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
3138
|
+
var dot = (cx, cy) => ({ kind: "circle", cx, cy, r: 2.1 });
|
|
3139
|
+
var path = (d, extra) => ({
|
|
3140
|
+
kind: "path",
|
|
3141
|
+
d,
|
|
3142
|
+
...extra
|
|
3143
|
+
});
|
|
3144
|
+
var DRAWING_TOOL_ICONS = {
|
|
3145
|
+
"cursor-cross": [path("M14 4v6.5M14 17.5V24M4 14h6.5M17.5 14H24")],
|
|
3146
|
+
"cursor-dot": [{ kind: "circle", cx: 14, cy: 14, r: 2.6, fill: true }],
|
|
3147
|
+
"cursor-arrow": [path("M10 4.5v16.4l4.3-4.1 3 6.7 2.9-1.3-3-6.7h5.9L10 4.5Z")],
|
|
3148
|
+
trendline: [dot(7, 21), dot(21, 7), path("M8.6 19.4 19.4 8.6")],
|
|
3149
|
+
"horizontal-line": [dot(14, 14), path("M3.5 14h8.4M16.1 14h8.4")],
|
|
3150
|
+
"vertical-line": [dot(14, 14), path("M14 3.5v8.4M14 16.1v8.4")],
|
|
3151
|
+
ray: [dot(7.5, 20.5), path("M9 19 24 4")],
|
|
3152
|
+
arrow: [dot(6, 22), path("M7.6 20.4 21.4 6.6"), path("M14.6 6.2h7.2v7.2")],
|
|
3153
|
+
"parallel-channel": [dot(6, 17), dot(17, 6), path("M7.5 15.5 15.5 7.5"), path("M11 23.5 23.5 11")],
|
|
3154
|
+
"fib-retracement": [
|
|
3155
|
+
dot(6, 7),
|
|
3156
|
+
path("M9.6 7h14.9"),
|
|
3157
|
+
path("M3.5 14h21"),
|
|
3158
|
+
dot(6, 21),
|
|
3159
|
+
path("M9.6 21h14.9")
|
|
3160
|
+
],
|
|
3161
|
+
"fib-extension": [
|
|
3162
|
+
dot(6.5, 21.5),
|
|
3163
|
+
dot(12.5, 6.5),
|
|
3164
|
+
path("M7.5 19.1l4-9.2"),
|
|
3165
|
+
path("M17 7h7.5M17 14h7.5M17 21h7.5")
|
|
3166
|
+
],
|
|
3167
|
+
// Long/short: three price levels (target, entry, stop) with anchor dots and
|
|
3168
|
+
// a dotted "price path" diagonal running from entry toward the target.
|
|
3169
|
+
"long-position": [
|
|
3170
|
+
dot(5, 6.5),
|
|
3171
|
+
path("M8.6 6.5h15.9"),
|
|
3172
|
+
dot(5, 16),
|
|
3173
|
+
path("M8.6 16h10.3"),
|
|
3174
|
+
dot(21, 16),
|
|
3175
|
+
path("M8.6 22.5h15.9"),
|
|
3176
|
+
dot(5, 22.5),
|
|
3177
|
+
path("M10.5 14 22 7.8", { dash: "2 3.2" })
|
|
3178
|
+
],
|
|
3179
|
+
"short-position": [
|
|
3180
|
+
dot(5, 21.5),
|
|
3181
|
+
path("M8.6 21.5h15.9"),
|
|
3182
|
+
dot(5, 12),
|
|
3183
|
+
path("M8.6 12h10.3"),
|
|
3184
|
+
dot(21, 12),
|
|
3185
|
+
path("M8.6 5.5h15.9"),
|
|
3186
|
+
dot(5, 5.5),
|
|
3187
|
+
path("M10.5 14 22 20.2", { dash: "2 3.2" })
|
|
3188
|
+
],
|
|
3189
|
+
"price-range": [
|
|
3190
|
+
path("M8 5h12M8 23h12"),
|
|
3191
|
+
path("M14 7v14"),
|
|
3192
|
+
path("M11.2 9.8 14 7l2.8 2.8M11.2 18.2 14 21l2.8-2.8")
|
|
3193
|
+
],
|
|
3194
|
+
// Fixed range VP: two vertical range anchors with the profile bars attached
|
|
3195
|
+
// to the left one.
|
|
3196
|
+
"fixed-range-volume-profile": [
|
|
3197
|
+
path("M5 3.5v15.4"),
|
|
3198
|
+
dot(5, 21.5),
|
|
3199
|
+
dot(23, 6.5),
|
|
3200
|
+
path("M23 9.1v15.4"),
|
|
3201
|
+
{ kind: "rect", x: 5, y: 6, width: 7, height: 3.2 },
|
|
3202
|
+
{ kind: "rect", x: 5, y: 11, width: 10.5, height: 3.2 },
|
|
3203
|
+
{ kind: "rect", x: 5, y: 16, width: 4.5, height: 3.2 }
|
|
3204
|
+
],
|
|
3205
|
+
measure: [
|
|
3206
|
+
path("M4.5 18.5 18.5 4.5l5 5L9.5 23.5Z"),
|
|
3207
|
+
path("m8 15 1.8 1.8M11.5 11.5 14 14M15 8l1.8 1.8")
|
|
3208
|
+
],
|
|
3209
|
+
rectangle: [
|
|
3210
|
+
dot(6, 8),
|
|
3211
|
+
dot(22, 8),
|
|
3212
|
+
dot(22, 20),
|
|
3213
|
+
dot(6, 20),
|
|
3214
|
+
path("M8.1 8h11.8M8.1 20h11.8M6 10.1v7.8M22 10.1v7.8")
|
|
3215
|
+
],
|
|
3216
|
+
ellipse: [path("M6.1 14a7.9 6.9 0 1 0 15.8 0 7.9 6.9 0 1 0-15.8 0"), dot(4, 14), dot(24, 14)],
|
|
3217
|
+
brush: [dot(5, 20), path("M6.9 18.4c2.6-6 5-.6 8.4-3.2 3-2.3 5.4-6 8.2-7.9")],
|
|
3218
|
+
text: [path("M7 8.5V6h14v2.5"), path("M14 6v16M11 22h6")],
|
|
3219
|
+
note: [path("M5.5 5h17v11.5l-6 6h-11V5Z"), path("M22.5 16.5h-6v6")],
|
|
3220
|
+
callout: [path("M4.5 6h19v11.5H13L8 22.5v-5H4.5V6Z")]
|
|
3221
|
+
};
|
|
3222
|
+
|
|
3135
3223
|
// src/themes.ts
|
|
3136
3224
|
var CHART_THEMES = {
|
|
3137
3225
|
midnight: {
|
|
@@ -4654,9 +4742,9 @@ function createChart(element, options = {}) {
|
|
|
4654
4742
|
const groupThousands = (value, decimals) => {
|
|
4655
4743
|
const negative = value < 0;
|
|
4656
4744
|
const fixed = Math.abs(value).toFixed(decimals);
|
|
4657
|
-
const
|
|
4658
|
-
const intPart =
|
|
4659
|
-
const decPart =
|
|
4745
|
+
const dot2 = fixed.indexOf(".");
|
|
4746
|
+
const intPart = dot2 === -1 ? fixed : fixed.slice(0, dot2);
|
|
4747
|
+
const decPart = dot2 === -1 ? "" : fixed.slice(dot2);
|
|
4660
4748
|
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4661
4749
|
return `${negative ? "-" : ""}${grouped}${decPart}`;
|
|
4662
4750
|
};
|
|
@@ -6253,6 +6341,8 @@ function createChart(element, options = {}) {
|
|
|
6253
6341
|
const palette = drawing.colors.length > 0 ? drawing.colors : null;
|
|
6254
6342
|
const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
|
|
6255
6343
|
const move = p1.price - p0.price;
|
|
6344
|
+
const lineLeft = Math.min(x0, x1, x2);
|
|
6345
|
+
const lineRight = Math.max(x0, x1, x2);
|
|
6256
6346
|
const levelLines = FIB_EXT_RATIOS.map((ratio) => {
|
|
6257
6347
|
const price = p2.price + move * ratio;
|
|
6258
6348
|
return { ratio, price, y: yFromPrice(price) };
|
|
@@ -6265,7 +6355,7 @@ function createChart(element, options = {}) {
|
|
|
6265
6355
|
ctx.save();
|
|
6266
6356
|
ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
|
|
6267
6357
|
ctx.globalAlpha = draft ? 0.5 : 1;
|
|
6268
|
-
ctx.fillRect(
|
|
6358
|
+
ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
|
|
6269
6359
|
ctx.restore();
|
|
6270
6360
|
}
|
|
6271
6361
|
ctx.save();
|
|
@@ -6274,8 +6364,8 @@ function createChart(element, options = {}) {
|
|
|
6274
6364
|
levelLines.forEach((level, index) => {
|
|
6275
6365
|
ctx.strokeStyle = levelColorAt(index);
|
|
6276
6366
|
ctx.beginPath();
|
|
6277
|
-
ctx.moveTo(crisp(
|
|
6278
|
-
ctx.lineTo(crisp(
|
|
6367
|
+
ctx.moveTo(crisp(lineLeft), crisp(level.y));
|
|
6368
|
+
ctx.lineTo(crisp(lineRight), crisp(level.y));
|
|
6279
6369
|
ctx.stroke();
|
|
6280
6370
|
});
|
|
6281
6371
|
ctx.restore();
|
|
@@ -6285,7 +6375,7 @@ function createChart(element, options = {}) {
|
|
|
6285
6375
|
const labelText = `${level.ratio} (${formatPrice(level.price)})`;
|
|
6286
6376
|
const textWidth = measureTextWidth(labelText);
|
|
6287
6377
|
const padding = 4;
|
|
6288
|
-
const bgX = chartLeft + 4;
|
|
6378
|
+
const bgX = Math.max(chartLeft + 2, lineLeft - textWidth - padding * 2 - 4);
|
|
6289
6379
|
const bgY = level.y - 9;
|
|
6290
6380
|
ctx.fillStyle = mergedOptions.backgroundColor;
|
|
6291
6381
|
fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
|
|
@@ -7234,12 +7324,12 @@ function createChart(element, options = {}) {
|
|
|
7234
7324
|
const upColumns = new Path2D();
|
|
7235
7325
|
const downColumns = new Path2D();
|
|
7236
7326
|
for (const column of seriesColumns) {
|
|
7237
|
-
const
|
|
7327
|
+
const path2 = column.close >= column.open ? upColumns : downColumns;
|
|
7238
7328
|
const x = column.x + 0.5;
|
|
7239
7329
|
const top = crisp(yFromPrice(column.high));
|
|
7240
7330
|
const bottom = crisp(yFromPrice(column.low));
|
|
7241
|
-
|
|
7242
|
-
|
|
7331
|
+
path2.moveTo(x, top);
|
|
7332
|
+
path2.lineTo(x, bottom === top ? bottom + 1 : bottom);
|
|
7243
7333
|
}
|
|
7244
7334
|
ctx.lineWidth = 1;
|
|
7245
7335
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7382,16 +7472,16 @@ function createChart(element, options = {}) {
|
|
|
7382
7472
|
const displayLow = isLastCandle && actualDirection === "down" ? Math.min(point.l, displayClose) : point.l;
|
|
7383
7473
|
const roundedCenterX = Math.round(chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth);
|
|
7384
7474
|
const direction = isLastCandle ? actualDirection : getCandleDirectionByIndex(index);
|
|
7385
|
-
const
|
|
7475
|
+
const path2 = direction === "up" ? upBars : downBars;
|
|
7386
7476
|
const centerX = roundedCenterX + 0.5;
|
|
7387
|
-
|
|
7388
|
-
|
|
7477
|
+
path2.moveTo(centerX, crisp(yFromPrice(displayHigh)));
|
|
7478
|
+
path2.lineTo(centerX, crisp(yFromPrice(displayLow)));
|
|
7389
7479
|
const openY = crisp(yFromPrice(point.o));
|
|
7390
7480
|
const closeY = crisp(yFromPrice(displayClose));
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7481
|
+
path2.moveTo(centerX - tickLength, openY);
|
|
7482
|
+
path2.lineTo(centerX, openY);
|
|
7483
|
+
path2.moveTo(centerX, closeY);
|
|
7484
|
+
path2.lineTo(centerX + tickLength, closeY);
|
|
7395
7485
|
}
|
|
7396
7486
|
ctx.lineWidth = Math.max(1, candleWickWidth);
|
|
7397
7487
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7459,7 +7549,7 @@ function createChart(element, options = {}) {
|
|
|
7459
7549
|
for (const plan of comparePlans) {
|
|
7460
7550
|
const color = plan.state.options.color ?? "#f59e0b";
|
|
7461
7551
|
const lineWidth = Math.max(1, plan.state.options.lineWidth ?? 1.5);
|
|
7462
|
-
const
|
|
7552
|
+
const path2 = new Path2D();
|
|
7463
7553
|
let started = false;
|
|
7464
7554
|
let firstX = 0;
|
|
7465
7555
|
let lastX = 0;
|
|
@@ -7467,11 +7557,11 @@ function createChart(element, options = {}) {
|
|
|
7467
7557
|
let lastPrice = Number.NaN;
|
|
7468
7558
|
const emit = (x, y) => {
|
|
7469
7559
|
if (!started) {
|
|
7470
|
-
|
|
7560
|
+
path2.moveTo(x, y);
|
|
7471
7561
|
firstX = x;
|
|
7472
7562
|
started = true;
|
|
7473
7563
|
} else {
|
|
7474
|
-
|
|
7564
|
+
path2.lineTo(x, y);
|
|
7475
7565
|
}
|
|
7476
7566
|
lastX = x;
|
|
7477
7567
|
lastY = y;
|
|
@@ -7529,7 +7619,7 @@ function createChart(element, options = {}) {
|
|
|
7529
7619
|
}
|
|
7530
7620
|
if (!started) continue;
|
|
7531
7621
|
if (plan.state.options.style === "area") {
|
|
7532
|
-
const fillPath = new Path2D(
|
|
7622
|
+
const fillPath = new Path2D(path2);
|
|
7533
7623
|
fillPath.lineTo(lastX, chartBottom);
|
|
7534
7624
|
fillPath.lineTo(firstX, chartBottom);
|
|
7535
7625
|
fillPath.closePath();
|
|
@@ -7543,7 +7633,7 @@ function createChart(element, options = {}) {
|
|
|
7543
7633
|
ctx.strokeStyle = color;
|
|
7544
7634
|
ctx.lineWidth = lineWidth;
|
|
7545
7635
|
ctx.lineJoin = "round";
|
|
7546
|
-
ctx.stroke(
|
|
7636
|
+
ctx.stroke(path2);
|
|
7547
7637
|
ctx.restore();
|
|
7548
7638
|
if (Number.isFinite(lastPrice)) {
|
|
7549
7639
|
const label = plan.state.options.label ?? plan.state.options.id;
|
|
@@ -9351,12 +9441,16 @@ function createChart(element, options = {}) {
|
|
|
9351
9441
|
if (Math.hypot(x - x2, y - y2) <= 9 * hitTolerance) {
|
|
9352
9442
|
return { drawing, target: "handle", pointIndex: 1 };
|
|
9353
9443
|
}
|
|
9354
|
-
const
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
const
|
|
9358
|
-
|
|
9359
|
-
|
|
9444
|
+
const fibLeft = Math.min(x1, x2) - 5 * hitTolerance;
|
|
9445
|
+
const fibRight = Math.max(x1, x2) + 5 * hitTolerance;
|
|
9446
|
+
if (x >= fibLeft && x <= fibRight) {
|
|
9447
|
+
const fibRatios = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
|
|
9448
|
+
for (const ratio of fibRatios) {
|
|
9449
|
+
const price = first.price + (second.price - first.price) * (1 - ratio);
|
|
9450
|
+
const lineY = canvasYFromDrawingPrice(price);
|
|
9451
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9452
|
+
return { drawing, target: "line" };
|
|
9453
|
+
}
|
|
9360
9454
|
}
|
|
9361
9455
|
}
|
|
9362
9456
|
} else if (drawing.type === "fib-extension") {
|
|
@@ -9381,11 +9475,15 @@ function createChart(element, options = {}) {
|
|
|
9381
9475
|
return { drawing, target: "handle", pointIndex: 2 };
|
|
9382
9476
|
}
|
|
9383
9477
|
const move = p1.price - p0.price;
|
|
9384
|
-
const
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9478
|
+
const extLeft = Math.min(x0, x1, x2) - 5 * hitTolerance;
|
|
9479
|
+
const extRight = Math.max(x0, x1, x2) + 5 * hitTolerance;
|
|
9480
|
+
if (x >= extLeft && x <= extRight) {
|
|
9481
|
+
const fibExtRatios = [0, 0.382, 0.5, 0.618, 1, 1.272, 1.618, 2.618];
|
|
9482
|
+
for (const ratio of fibExtRatios) {
|
|
9483
|
+
const lineY = canvasYFromDrawingPrice(p2.price + move * ratio);
|
|
9484
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9485
|
+
return { drawing, target: "line" };
|
|
9486
|
+
}
|
|
9389
9487
|
}
|
|
9390
9488
|
}
|
|
9391
9489
|
if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
|
|
@@ -12339,6 +12437,9 @@ function createChart(element, options = {}) {
|
|
|
12339
12437
|
export {
|
|
12340
12438
|
CHART_THEMES,
|
|
12341
12439
|
CHART_THEME_NAMES,
|
|
12440
|
+
DRAWING_ICON_STROKE_WIDTH,
|
|
12441
|
+
DRAWING_ICON_VIEWBOX,
|
|
12442
|
+
DRAWING_TOOL_ICONS,
|
|
12342
12443
|
FIB_DEFAULT_PALETTE,
|
|
12343
12444
|
POSITION_DEFAULT_COLORS,
|
|
12344
12445
|
SCRIPT_SOURCE_INPUT_VALUES,
|
package/dist/index.cjs
CHANGED
|
@@ -22,6 +22,9 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
CHART_THEMES: () => CHART_THEMES,
|
|
24
24
|
CHART_THEME_NAMES: () => CHART_THEME_NAMES,
|
|
25
|
+
DRAWING_ICON_STROKE_WIDTH: () => DRAWING_ICON_STROKE_WIDTH,
|
|
26
|
+
DRAWING_ICON_VIEWBOX: () => DRAWING_ICON_VIEWBOX,
|
|
27
|
+
DRAWING_TOOL_ICONS: () => DRAWING_TOOL_ICONS,
|
|
25
28
|
FIB_DEFAULT_PALETTE: () => FIB_DEFAULT_PALETTE,
|
|
26
29
|
POSITION_DEFAULT_COLORS: () => POSITION_DEFAULT_COLORS,
|
|
27
30
|
SCRIPT_SOURCE_INPUT_VALUES: () => SCRIPT_SOURCE_INPUT_VALUES,
|
|
@@ -3168,6 +3171,94 @@ var compileScriptIndicator = (definition) => {
|
|
|
3168
3171
|
return plugin;
|
|
3169
3172
|
};
|
|
3170
3173
|
|
|
3174
|
+
// src/icons.ts
|
|
3175
|
+
var DRAWING_ICON_VIEWBOX = 28;
|
|
3176
|
+
var DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
3177
|
+
var dot = (cx, cy) => ({ kind: "circle", cx, cy, r: 2.1 });
|
|
3178
|
+
var path = (d, extra) => ({
|
|
3179
|
+
kind: "path",
|
|
3180
|
+
d,
|
|
3181
|
+
...extra
|
|
3182
|
+
});
|
|
3183
|
+
var DRAWING_TOOL_ICONS = {
|
|
3184
|
+
"cursor-cross": [path("M14 4v6.5M14 17.5V24M4 14h6.5M17.5 14H24")],
|
|
3185
|
+
"cursor-dot": [{ kind: "circle", cx: 14, cy: 14, r: 2.6, fill: true }],
|
|
3186
|
+
"cursor-arrow": [path("M10 4.5v16.4l4.3-4.1 3 6.7 2.9-1.3-3-6.7h5.9L10 4.5Z")],
|
|
3187
|
+
trendline: [dot(7, 21), dot(21, 7), path("M8.6 19.4 19.4 8.6")],
|
|
3188
|
+
"horizontal-line": [dot(14, 14), path("M3.5 14h8.4M16.1 14h8.4")],
|
|
3189
|
+
"vertical-line": [dot(14, 14), path("M14 3.5v8.4M14 16.1v8.4")],
|
|
3190
|
+
ray: [dot(7.5, 20.5), path("M9 19 24 4")],
|
|
3191
|
+
arrow: [dot(6, 22), path("M7.6 20.4 21.4 6.6"), path("M14.6 6.2h7.2v7.2")],
|
|
3192
|
+
"parallel-channel": [dot(6, 17), dot(17, 6), path("M7.5 15.5 15.5 7.5"), path("M11 23.5 23.5 11")],
|
|
3193
|
+
"fib-retracement": [
|
|
3194
|
+
dot(6, 7),
|
|
3195
|
+
path("M9.6 7h14.9"),
|
|
3196
|
+
path("M3.5 14h21"),
|
|
3197
|
+
dot(6, 21),
|
|
3198
|
+
path("M9.6 21h14.9")
|
|
3199
|
+
],
|
|
3200
|
+
"fib-extension": [
|
|
3201
|
+
dot(6.5, 21.5),
|
|
3202
|
+
dot(12.5, 6.5),
|
|
3203
|
+
path("M7.5 19.1l4-9.2"),
|
|
3204
|
+
path("M17 7h7.5M17 14h7.5M17 21h7.5")
|
|
3205
|
+
],
|
|
3206
|
+
// Long/short: three price levels (target, entry, stop) with anchor dots and
|
|
3207
|
+
// a dotted "price path" diagonal running from entry toward the target.
|
|
3208
|
+
"long-position": [
|
|
3209
|
+
dot(5, 6.5),
|
|
3210
|
+
path("M8.6 6.5h15.9"),
|
|
3211
|
+
dot(5, 16),
|
|
3212
|
+
path("M8.6 16h10.3"),
|
|
3213
|
+
dot(21, 16),
|
|
3214
|
+
path("M8.6 22.5h15.9"),
|
|
3215
|
+
dot(5, 22.5),
|
|
3216
|
+
path("M10.5 14 22 7.8", { dash: "2 3.2" })
|
|
3217
|
+
],
|
|
3218
|
+
"short-position": [
|
|
3219
|
+
dot(5, 21.5),
|
|
3220
|
+
path("M8.6 21.5h15.9"),
|
|
3221
|
+
dot(5, 12),
|
|
3222
|
+
path("M8.6 12h10.3"),
|
|
3223
|
+
dot(21, 12),
|
|
3224
|
+
path("M8.6 5.5h15.9"),
|
|
3225
|
+
dot(5, 5.5),
|
|
3226
|
+
path("M10.5 14 22 20.2", { dash: "2 3.2" })
|
|
3227
|
+
],
|
|
3228
|
+
"price-range": [
|
|
3229
|
+
path("M8 5h12M8 23h12"),
|
|
3230
|
+
path("M14 7v14"),
|
|
3231
|
+
path("M11.2 9.8 14 7l2.8 2.8M11.2 18.2 14 21l2.8-2.8")
|
|
3232
|
+
],
|
|
3233
|
+
// Fixed range VP: two vertical range anchors with the profile bars attached
|
|
3234
|
+
// to the left one.
|
|
3235
|
+
"fixed-range-volume-profile": [
|
|
3236
|
+
path("M5 3.5v15.4"),
|
|
3237
|
+
dot(5, 21.5),
|
|
3238
|
+
dot(23, 6.5),
|
|
3239
|
+
path("M23 9.1v15.4"),
|
|
3240
|
+
{ kind: "rect", x: 5, y: 6, width: 7, height: 3.2 },
|
|
3241
|
+
{ kind: "rect", x: 5, y: 11, width: 10.5, height: 3.2 },
|
|
3242
|
+
{ kind: "rect", x: 5, y: 16, width: 4.5, height: 3.2 }
|
|
3243
|
+
],
|
|
3244
|
+
measure: [
|
|
3245
|
+
path("M4.5 18.5 18.5 4.5l5 5L9.5 23.5Z"),
|
|
3246
|
+
path("m8 15 1.8 1.8M11.5 11.5 14 14M15 8l1.8 1.8")
|
|
3247
|
+
],
|
|
3248
|
+
rectangle: [
|
|
3249
|
+
dot(6, 8),
|
|
3250
|
+
dot(22, 8),
|
|
3251
|
+
dot(22, 20),
|
|
3252
|
+
dot(6, 20),
|
|
3253
|
+
path("M8.1 8h11.8M8.1 20h11.8M6 10.1v7.8M22 10.1v7.8")
|
|
3254
|
+
],
|
|
3255
|
+
ellipse: [path("M6.1 14a7.9 6.9 0 1 0 15.8 0 7.9 6.9 0 1 0-15.8 0"), dot(4, 14), dot(24, 14)],
|
|
3256
|
+
brush: [dot(5, 20), path("M6.9 18.4c2.6-6 5-.6 8.4-3.2 3-2.3 5.4-6 8.2-7.9")],
|
|
3257
|
+
text: [path("M7 8.5V6h14v2.5"), path("M14 6v16M11 22h6")],
|
|
3258
|
+
note: [path("M5.5 5h17v11.5l-6 6h-11V5Z"), path("M22.5 16.5h-6v6")],
|
|
3259
|
+
callout: [path("M4.5 6h19v11.5H13L8 22.5v-5H4.5V6Z")]
|
|
3260
|
+
};
|
|
3261
|
+
|
|
3171
3262
|
// src/themes.ts
|
|
3172
3263
|
var CHART_THEMES = {
|
|
3173
3264
|
midnight: {
|
|
@@ -4690,9 +4781,9 @@ function createChart(element, options = {}) {
|
|
|
4690
4781
|
const groupThousands = (value, decimals) => {
|
|
4691
4782
|
const negative = value < 0;
|
|
4692
4783
|
const fixed = Math.abs(value).toFixed(decimals);
|
|
4693
|
-
const
|
|
4694
|
-
const intPart =
|
|
4695
|
-
const decPart =
|
|
4784
|
+
const dot2 = fixed.indexOf(".");
|
|
4785
|
+
const intPart = dot2 === -1 ? fixed : fixed.slice(0, dot2);
|
|
4786
|
+
const decPart = dot2 === -1 ? "" : fixed.slice(dot2);
|
|
4696
4787
|
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4697
4788
|
return `${negative ? "-" : ""}${grouped}${decPart}`;
|
|
4698
4789
|
};
|
|
@@ -6289,6 +6380,8 @@ function createChart(element, options = {}) {
|
|
|
6289
6380
|
const palette = drawing.colors.length > 0 ? drawing.colors : null;
|
|
6290
6381
|
const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
|
|
6291
6382
|
const move = p1.price - p0.price;
|
|
6383
|
+
const lineLeft = Math.min(x0, x1, x2);
|
|
6384
|
+
const lineRight = Math.max(x0, x1, x2);
|
|
6292
6385
|
const levelLines = FIB_EXT_RATIOS.map((ratio) => {
|
|
6293
6386
|
const price = p2.price + move * ratio;
|
|
6294
6387
|
return { ratio, price, y: yFromPrice(price) };
|
|
@@ -6301,7 +6394,7 @@ function createChart(element, options = {}) {
|
|
|
6301
6394
|
ctx.save();
|
|
6302
6395
|
ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
|
|
6303
6396
|
ctx.globalAlpha = draft ? 0.5 : 1;
|
|
6304
|
-
ctx.fillRect(
|
|
6397
|
+
ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
|
|
6305
6398
|
ctx.restore();
|
|
6306
6399
|
}
|
|
6307
6400
|
ctx.save();
|
|
@@ -6310,8 +6403,8 @@ function createChart(element, options = {}) {
|
|
|
6310
6403
|
levelLines.forEach((level, index) => {
|
|
6311
6404
|
ctx.strokeStyle = levelColorAt(index);
|
|
6312
6405
|
ctx.beginPath();
|
|
6313
|
-
ctx.moveTo(crisp(
|
|
6314
|
-
ctx.lineTo(crisp(
|
|
6406
|
+
ctx.moveTo(crisp(lineLeft), crisp(level.y));
|
|
6407
|
+
ctx.lineTo(crisp(lineRight), crisp(level.y));
|
|
6315
6408
|
ctx.stroke();
|
|
6316
6409
|
});
|
|
6317
6410
|
ctx.restore();
|
|
@@ -6321,7 +6414,7 @@ function createChart(element, options = {}) {
|
|
|
6321
6414
|
const labelText = `${level.ratio} (${formatPrice(level.price)})`;
|
|
6322
6415
|
const textWidth = measureTextWidth(labelText);
|
|
6323
6416
|
const padding = 4;
|
|
6324
|
-
const bgX = chartLeft + 4;
|
|
6417
|
+
const bgX = Math.max(chartLeft + 2, lineLeft - textWidth - padding * 2 - 4);
|
|
6325
6418
|
const bgY = level.y - 9;
|
|
6326
6419
|
ctx.fillStyle = mergedOptions.backgroundColor;
|
|
6327
6420
|
fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
|
|
@@ -7270,12 +7363,12 @@ function createChart(element, options = {}) {
|
|
|
7270
7363
|
const upColumns = new Path2D();
|
|
7271
7364
|
const downColumns = new Path2D();
|
|
7272
7365
|
for (const column of seriesColumns) {
|
|
7273
|
-
const
|
|
7366
|
+
const path2 = column.close >= column.open ? upColumns : downColumns;
|
|
7274
7367
|
const x = column.x + 0.5;
|
|
7275
7368
|
const top = crisp(yFromPrice(column.high));
|
|
7276
7369
|
const bottom = crisp(yFromPrice(column.low));
|
|
7277
|
-
|
|
7278
|
-
|
|
7370
|
+
path2.moveTo(x, top);
|
|
7371
|
+
path2.lineTo(x, bottom === top ? bottom + 1 : bottom);
|
|
7279
7372
|
}
|
|
7280
7373
|
ctx.lineWidth = 1;
|
|
7281
7374
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7418,16 +7511,16 @@ function createChart(element, options = {}) {
|
|
|
7418
7511
|
const displayLow = isLastCandle && actualDirection === "down" ? Math.min(point.l, displayClose) : point.l;
|
|
7419
7512
|
const roundedCenterX = Math.round(chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth);
|
|
7420
7513
|
const direction = isLastCandle ? actualDirection : getCandleDirectionByIndex(index);
|
|
7421
|
-
const
|
|
7514
|
+
const path2 = direction === "up" ? upBars : downBars;
|
|
7422
7515
|
const centerX = roundedCenterX + 0.5;
|
|
7423
|
-
|
|
7424
|
-
|
|
7516
|
+
path2.moveTo(centerX, crisp(yFromPrice(displayHigh)));
|
|
7517
|
+
path2.lineTo(centerX, crisp(yFromPrice(displayLow)));
|
|
7425
7518
|
const openY = crisp(yFromPrice(point.o));
|
|
7426
7519
|
const closeY = crisp(yFromPrice(displayClose));
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7520
|
+
path2.moveTo(centerX - tickLength, openY);
|
|
7521
|
+
path2.lineTo(centerX, openY);
|
|
7522
|
+
path2.moveTo(centerX, closeY);
|
|
7523
|
+
path2.lineTo(centerX + tickLength, closeY);
|
|
7431
7524
|
}
|
|
7432
7525
|
ctx.lineWidth = Math.max(1, candleWickWidth);
|
|
7433
7526
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7495,7 +7588,7 @@ function createChart(element, options = {}) {
|
|
|
7495
7588
|
for (const plan of comparePlans) {
|
|
7496
7589
|
const color = plan.state.options.color ?? "#f59e0b";
|
|
7497
7590
|
const lineWidth = Math.max(1, plan.state.options.lineWidth ?? 1.5);
|
|
7498
|
-
const
|
|
7591
|
+
const path2 = new Path2D();
|
|
7499
7592
|
let started = false;
|
|
7500
7593
|
let firstX = 0;
|
|
7501
7594
|
let lastX = 0;
|
|
@@ -7503,11 +7596,11 @@ function createChart(element, options = {}) {
|
|
|
7503
7596
|
let lastPrice = Number.NaN;
|
|
7504
7597
|
const emit = (x, y) => {
|
|
7505
7598
|
if (!started) {
|
|
7506
|
-
|
|
7599
|
+
path2.moveTo(x, y);
|
|
7507
7600
|
firstX = x;
|
|
7508
7601
|
started = true;
|
|
7509
7602
|
} else {
|
|
7510
|
-
|
|
7603
|
+
path2.lineTo(x, y);
|
|
7511
7604
|
}
|
|
7512
7605
|
lastX = x;
|
|
7513
7606
|
lastY = y;
|
|
@@ -7565,7 +7658,7 @@ function createChart(element, options = {}) {
|
|
|
7565
7658
|
}
|
|
7566
7659
|
if (!started) continue;
|
|
7567
7660
|
if (plan.state.options.style === "area") {
|
|
7568
|
-
const fillPath = new Path2D(
|
|
7661
|
+
const fillPath = new Path2D(path2);
|
|
7569
7662
|
fillPath.lineTo(lastX, chartBottom);
|
|
7570
7663
|
fillPath.lineTo(firstX, chartBottom);
|
|
7571
7664
|
fillPath.closePath();
|
|
@@ -7579,7 +7672,7 @@ function createChart(element, options = {}) {
|
|
|
7579
7672
|
ctx.strokeStyle = color;
|
|
7580
7673
|
ctx.lineWidth = lineWidth;
|
|
7581
7674
|
ctx.lineJoin = "round";
|
|
7582
|
-
ctx.stroke(
|
|
7675
|
+
ctx.stroke(path2);
|
|
7583
7676
|
ctx.restore();
|
|
7584
7677
|
if (Number.isFinite(lastPrice)) {
|
|
7585
7678
|
const label = plan.state.options.label ?? plan.state.options.id;
|
|
@@ -9387,12 +9480,16 @@ function createChart(element, options = {}) {
|
|
|
9387
9480
|
if (Math.hypot(x - x2, y - y2) <= 9 * hitTolerance) {
|
|
9388
9481
|
return { drawing, target: "handle", pointIndex: 1 };
|
|
9389
9482
|
}
|
|
9390
|
-
const
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
const
|
|
9394
|
-
|
|
9395
|
-
|
|
9483
|
+
const fibLeft = Math.min(x1, x2) - 5 * hitTolerance;
|
|
9484
|
+
const fibRight = Math.max(x1, x2) + 5 * hitTolerance;
|
|
9485
|
+
if (x >= fibLeft && x <= fibRight) {
|
|
9486
|
+
const fibRatios = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
|
|
9487
|
+
for (const ratio of fibRatios) {
|
|
9488
|
+
const price = first.price + (second.price - first.price) * (1 - ratio);
|
|
9489
|
+
const lineY = canvasYFromDrawingPrice(price);
|
|
9490
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9491
|
+
return { drawing, target: "line" };
|
|
9492
|
+
}
|
|
9396
9493
|
}
|
|
9397
9494
|
}
|
|
9398
9495
|
} else if (drawing.type === "fib-extension") {
|
|
@@ -9417,11 +9514,15 @@ function createChart(element, options = {}) {
|
|
|
9417
9514
|
return { drawing, target: "handle", pointIndex: 2 };
|
|
9418
9515
|
}
|
|
9419
9516
|
const move = p1.price - p0.price;
|
|
9420
|
-
const
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
|
|
9517
|
+
const extLeft = Math.min(x0, x1, x2) - 5 * hitTolerance;
|
|
9518
|
+
const extRight = Math.max(x0, x1, x2) + 5 * hitTolerance;
|
|
9519
|
+
if (x >= extLeft && x <= extRight) {
|
|
9520
|
+
const fibExtRatios = [0, 0.382, 0.5, 0.618, 1, 1.272, 1.618, 2.618];
|
|
9521
|
+
for (const ratio of fibExtRatios) {
|
|
9522
|
+
const lineY = canvasYFromDrawingPrice(p2.price + move * ratio);
|
|
9523
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9524
|
+
return { drawing, target: "line" };
|
|
9525
|
+
}
|
|
9425
9526
|
}
|
|
9426
9527
|
}
|
|
9427
9528
|
if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
|
|
@@ -12376,6 +12477,9 @@ function createChart(element, options = {}) {
|
|
|
12376
12477
|
0 && (module.exports = {
|
|
12377
12478
|
CHART_THEMES,
|
|
12378
12479
|
CHART_THEME_NAMES,
|
|
12480
|
+
DRAWING_ICON_STROKE_WIDTH,
|
|
12481
|
+
DRAWING_ICON_VIEWBOX,
|
|
12482
|
+
DRAWING_TOOL_ICONS,
|
|
12379
12483
|
FIB_DEFAULT_PALETTE,
|
|
12380
12484
|
POSITION_DEFAULT_COLORS,
|
|
12381
12485
|
SCRIPT_SOURCE_INPUT_VALUES,
|
package/dist/index.d.cts
CHANGED
|
@@ -1441,6 +1441,45 @@ declare const validateScriptSource: (source: string) => string | null;
|
|
|
1441
1441
|
*/
|
|
1442
1442
|
declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
|
|
1443
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* Hyperprop drawing-tool icon pack — framework-agnostic geometry.
|
|
1446
|
+
*
|
|
1447
|
+
* Original artwork drawn in the visual language traders know from desktop
|
|
1448
|
+
* charting platforms: a 28x28 grid, thin round-capped outlines, and hollow
|
|
1449
|
+
* "anchor" dots on anything line-based (a dot marks a draggable point of the
|
|
1450
|
+
* tool). The data here is plain shape descriptions so every consumer renders
|
|
1451
|
+
* the identical set: the web terminal maps it to DOM `<svg>` elements and the
|
|
1452
|
+
* mobile app to react-native-svg components.
|
|
1453
|
+
*
|
|
1454
|
+
* Design rules when adding icons:
|
|
1455
|
+
* - viewBox 0 0 28 28, strokeWidth 1.6, round caps/joins, no fill (except
|
|
1456
|
+
* shapes marked `fill: true`).
|
|
1457
|
+
* - Anchor dots are hollow circles r=2.1; lines stop ~1.5px short of them.
|
|
1458
|
+
* - Keep 3.5px padding to the edges so glyphs optically match.
|
|
1459
|
+
*/
|
|
1460
|
+
type DrawingIconShape = {
|
|
1461
|
+
kind: "path";
|
|
1462
|
+
d: string;
|
|
1463
|
+
dash?: string;
|
|
1464
|
+
fill?: boolean;
|
|
1465
|
+
} | {
|
|
1466
|
+
kind: "circle";
|
|
1467
|
+
cx: number;
|
|
1468
|
+
cy: number;
|
|
1469
|
+
r: number;
|
|
1470
|
+
fill?: boolean;
|
|
1471
|
+
} | {
|
|
1472
|
+
kind: "rect";
|
|
1473
|
+
x: number;
|
|
1474
|
+
y: number;
|
|
1475
|
+
width: number;
|
|
1476
|
+
height: number;
|
|
1477
|
+
};
|
|
1478
|
+
type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout";
|
|
1479
|
+
declare const DRAWING_ICON_VIEWBOX = 28;
|
|
1480
|
+
declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
1481
|
+
declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
|
|
1482
|
+
|
|
1444
1483
|
/**
|
|
1445
1484
|
* Built-in palettes.
|
|
1446
1485
|
*
|
|
@@ -1465,4 +1504,4 @@ declare const SESSION_PRESETS: Record<SessionPresetName, SessionSpec>;
|
|
|
1465
1504
|
|
|
1466
1505
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
1467
1506
|
|
|
1468
|
-
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
|
1507
|
+
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, DRAWING_ICON_STROKE_WIDTH, DRAWING_ICON_VIEWBOX, DRAWING_TOOL_ICONS, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingIconName, type DrawingIconShape, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
package/dist/index.d.ts
CHANGED
|
@@ -1441,6 +1441,45 @@ declare const validateScriptSource: (source: string) => string | null;
|
|
|
1441
1441
|
*/
|
|
1442
1442
|
declare const compileScriptIndicator: (definition: ScriptIndicatorDefinition) => IndicatorPlugin;
|
|
1443
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* Hyperprop drawing-tool icon pack — framework-agnostic geometry.
|
|
1446
|
+
*
|
|
1447
|
+
* Original artwork drawn in the visual language traders know from desktop
|
|
1448
|
+
* charting platforms: a 28x28 grid, thin round-capped outlines, and hollow
|
|
1449
|
+
* "anchor" dots on anything line-based (a dot marks a draggable point of the
|
|
1450
|
+
* tool). The data here is plain shape descriptions so every consumer renders
|
|
1451
|
+
* the identical set: the web terminal maps it to DOM `<svg>` elements and the
|
|
1452
|
+
* mobile app to react-native-svg components.
|
|
1453
|
+
*
|
|
1454
|
+
* Design rules when adding icons:
|
|
1455
|
+
* - viewBox 0 0 28 28, strokeWidth 1.6, round caps/joins, no fill (except
|
|
1456
|
+
* shapes marked `fill: true`).
|
|
1457
|
+
* - Anchor dots are hollow circles r=2.1; lines stop ~1.5px short of them.
|
|
1458
|
+
* - Keep 3.5px padding to the edges so glyphs optically match.
|
|
1459
|
+
*/
|
|
1460
|
+
type DrawingIconShape = {
|
|
1461
|
+
kind: "path";
|
|
1462
|
+
d: string;
|
|
1463
|
+
dash?: string;
|
|
1464
|
+
fill?: boolean;
|
|
1465
|
+
} | {
|
|
1466
|
+
kind: "circle";
|
|
1467
|
+
cx: number;
|
|
1468
|
+
cy: number;
|
|
1469
|
+
r: number;
|
|
1470
|
+
fill?: boolean;
|
|
1471
|
+
} | {
|
|
1472
|
+
kind: "rect";
|
|
1473
|
+
x: number;
|
|
1474
|
+
y: number;
|
|
1475
|
+
width: number;
|
|
1476
|
+
height: number;
|
|
1477
|
+
};
|
|
1478
|
+
type DrawingIconName = "cursor-cross" | "cursor-dot" | "cursor-arrow" | "trendline" | "horizontal-line" | "vertical-line" | "ray" | "arrow" | "parallel-channel" | "fib-retracement" | "fib-extension" | "long-position" | "short-position" | "price-range" | "fixed-range-volume-profile" | "measure" | "rectangle" | "ellipse" | "brush" | "text" | "note" | "callout";
|
|
1479
|
+
declare const DRAWING_ICON_VIEWBOX = 28;
|
|
1480
|
+
declare const DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
1481
|
+
declare const DRAWING_TOOL_ICONS: Record<DrawingIconName, DrawingIconShape[]>;
|
|
1482
|
+
|
|
1444
1483
|
/**
|
|
1445
1484
|
* Built-in palettes.
|
|
1446
1485
|
*
|
|
@@ -1465,4 +1504,4 @@ declare const SESSION_PRESETS: Record<SessionPresetName, SessionSpec>;
|
|
|
1465
1504
|
|
|
1466
1505
|
declare function createChart(element: HTMLElement, options?: ChartOptions): ChartInstance;
|
|
1467
1506
|
|
|
1468
|
-
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
|
1507
|
+
export { type AccessibilityOptions, type AlertActionEvent, type AlertCondition, type AlertOptions, type AlertTriggerEvent, type AnimationOptions, type AxisOptions, type BarMarkOptions, type BuiltInIndicatorInfo, CHART_THEMES, CHART_THEME_NAMES, type ChartClickEvent, type ChartContextMenuEvent, type ChartContextMenuRegion, type ChartDatafeed, type ChartInstance, type ChartKeyboardAction, type ChartKeyboardShortcutEvent, type ChartLongPressEvent, type ChartOptions, type ChartSavedState, type ChartTheme, type ChartThemeName, type ChartTimezone, type ChartType, type CompareSeriesOptions, type CrosshairMoveEvent, type CrosshairOptions, type CrosshairPriceActionEvent, DRAWING_ICON_STROKE_WIDTH, DRAWING_ICON_VIEWBOX, DRAWING_TOOL_ICONS, type DashPatternOptions, type DataLineOptions, type DatafeedBarsRequest, type DatafeedOptions, type DownsamplingOptions, type DrawingBounds, type DrawingDefaults, type DrawingHoverEvent, type DrawingIconName, type DrawingIconShape, type DrawingObjectOptions, type DrawingPoint, type DrawingSelectEvent, type DrawingSelectionChangeEvent, type DrawingToolType, FIB_DEFAULT_PALETTE, type GridOptions, type HistoryOptions, type IndicatorInstanceOptions, type IndicatorPane, type IndicatorPaneActionEvent, type IndicatorPaneAxisOptions, type IndicatorPaneGuideLine, type IndicatorPaneHeightChangeEvent, type IndicatorPaneRenderInfo, type IndicatorPaneValue, type IndicatorPaneValueLabel, type IndicatorPlugin, type IndicatorRenderContext, type IndicatorUpdateOptions, type KeyboardOptions, type LabelsOptions, type MarkClickEvent, type MarkHoverEvent, type MarkShape, type OhlcDataPoint, type OrderActionButton, type OrderActionEvent, type OrderLineOptions, POSITION_DEFAULT_COLORS, type PriceLineOptions, type PriceScaleMode, type PriceScaleOptions, type ReplayStartOptions, type ReplayState, SCRIPT_SOURCE_INPUT_VALUES, SESSION_PRESETS, type ScriptComputeResult, type ScriptIndicatorDefinition, type ScriptIndicatorInputDef, type ScriptInputHelper, type ScriptInputOptions, type ScriptPlotSpec, type SessionOptions, type SessionPresetName, type SessionSegment, type SessionSpec, type TickerLineOptions, type TimeFormat, type TimescaleMarkOptions, type TouchOptions, type TradeMarkerOptions, type UndoRedoState, type ViewportState, type WatermarkOptions, compileScriptIndicator, createChart, extractScriptInputs, isValidTimeZone, validateScriptSource };
|
package/dist/index.js
CHANGED
|
@@ -3132,6 +3132,94 @@ var compileScriptIndicator = (definition) => {
|
|
|
3132
3132
|
return plugin;
|
|
3133
3133
|
};
|
|
3134
3134
|
|
|
3135
|
+
// src/icons.ts
|
|
3136
|
+
var DRAWING_ICON_VIEWBOX = 28;
|
|
3137
|
+
var DRAWING_ICON_STROKE_WIDTH = 1.6;
|
|
3138
|
+
var dot = (cx, cy) => ({ kind: "circle", cx, cy, r: 2.1 });
|
|
3139
|
+
var path = (d, extra) => ({
|
|
3140
|
+
kind: "path",
|
|
3141
|
+
d,
|
|
3142
|
+
...extra
|
|
3143
|
+
});
|
|
3144
|
+
var DRAWING_TOOL_ICONS = {
|
|
3145
|
+
"cursor-cross": [path("M14 4v6.5M14 17.5V24M4 14h6.5M17.5 14H24")],
|
|
3146
|
+
"cursor-dot": [{ kind: "circle", cx: 14, cy: 14, r: 2.6, fill: true }],
|
|
3147
|
+
"cursor-arrow": [path("M10 4.5v16.4l4.3-4.1 3 6.7 2.9-1.3-3-6.7h5.9L10 4.5Z")],
|
|
3148
|
+
trendline: [dot(7, 21), dot(21, 7), path("M8.6 19.4 19.4 8.6")],
|
|
3149
|
+
"horizontal-line": [dot(14, 14), path("M3.5 14h8.4M16.1 14h8.4")],
|
|
3150
|
+
"vertical-line": [dot(14, 14), path("M14 3.5v8.4M14 16.1v8.4")],
|
|
3151
|
+
ray: [dot(7.5, 20.5), path("M9 19 24 4")],
|
|
3152
|
+
arrow: [dot(6, 22), path("M7.6 20.4 21.4 6.6"), path("M14.6 6.2h7.2v7.2")],
|
|
3153
|
+
"parallel-channel": [dot(6, 17), dot(17, 6), path("M7.5 15.5 15.5 7.5"), path("M11 23.5 23.5 11")],
|
|
3154
|
+
"fib-retracement": [
|
|
3155
|
+
dot(6, 7),
|
|
3156
|
+
path("M9.6 7h14.9"),
|
|
3157
|
+
path("M3.5 14h21"),
|
|
3158
|
+
dot(6, 21),
|
|
3159
|
+
path("M9.6 21h14.9")
|
|
3160
|
+
],
|
|
3161
|
+
"fib-extension": [
|
|
3162
|
+
dot(6.5, 21.5),
|
|
3163
|
+
dot(12.5, 6.5),
|
|
3164
|
+
path("M7.5 19.1l4-9.2"),
|
|
3165
|
+
path("M17 7h7.5M17 14h7.5M17 21h7.5")
|
|
3166
|
+
],
|
|
3167
|
+
// Long/short: three price levels (target, entry, stop) with anchor dots and
|
|
3168
|
+
// a dotted "price path" diagonal running from entry toward the target.
|
|
3169
|
+
"long-position": [
|
|
3170
|
+
dot(5, 6.5),
|
|
3171
|
+
path("M8.6 6.5h15.9"),
|
|
3172
|
+
dot(5, 16),
|
|
3173
|
+
path("M8.6 16h10.3"),
|
|
3174
|
+
dot(21, 16),
|
|
3175
|
+
path("M8.6 22.5h15.9"),
|
|
3176
|
+
dot(5, 22.5),
|
|
3177
|
+
path("M10.5 14 22 7.8", { dash: "2 3.2" })
|
|
3178
|
+
],
|
|
3179
|
+
"short-position": [
|
|
3180
|
+
dot(5, 21.5),
|
|
3181
|
+
path("M8.6 21.5h15.9"),
|
|
3182
|
+
dot(5, 12),
|
|
3183
|
+
path("M8.6 12h10.3"),
|
|
3184
|
+
dot(21, 12),
|
|
3185
|
+
path("M8.6 5.5h15.9"),
|
|
3186
|
+
dot(5, 5.5),
|
|
3187
|
+
path("M10.5 14 22 20.2", { dash: "2 3.2" })
|
|
3188
|
+
],
|
|
3189
|
+
"price-range": [
|
|
3190
|
+
path("M8 5h12M8 23h12"),
|
|
3191
|
+
path("M14 7v14"),
|
|
3192
|
+
path("M11.2 9.8 14 7l2.8 2.8M11.2 18.2 14 21l2.8-2.8")
|
|
3193
|
+
],
|
|
3194
|
+
// Fixed range VP: two vertical range anchors with the profile bars attached
|
|
3195
|
+
// to the left one.
|
|
3196
|
+
"fixed-range-volume-profile": [
|
|
3197
|
+
path("M5 3.5v15.4"),
|
|
3198
|
+
dot(5, 21.5),
|
|
3199
|
+
dot(23, 6.5),
|
|
3200
|
+
path("M23 9.1v15.4"),
|
|
3201
|
+
{ kind: "rect", x: 5, y: 6, width: 7, height: 3.2 },
|
|
3202
|
+
{ kind: "rect", x: 5, y: 11, width: 10.5, height: 3.2 },
|
|
3203
|
+
{ kind: "rect", x: 5, y: 16, width: 4.5, height: 3.2 }
|
|
3204
|
+
],
|
|
3205
|
+
measure: [
|
|
3206
|
+
path("M4.5 18.5 18.5 4.5l5 5L9.5 23.5Z"),
|
|
3207
|
+
path("m8 15 1.8 1.8M11.5 11.5 14 14M15 8l1.8 1.8")
|
|
3208
|
+
],
|
|
3209
|
+
rectangle: [
|
|
3210
|
+
dot(6, 8),
|
|
3211
|
+
dot(22, 8),
|
|
3212
|
+
dot(22, 20),
|
|
3213
|
+
dot(6, 20),
|
|
3214
|
+
path("M8.1 8h11.8M8.1 20h11.8M6 10.1v7.8M22 10.1v7.8")
|
|
3215
|
+
],
|
|
3216
|
+
ellipse: [path("M6.1 14a7.9 6.9 0 1 0 15.8 0 7.9 6.9 0 1 0-15.8 0"), dot(4, 14), dot(24, 14)],
|
|
3217
|
+
brush: [dot(5, 20), path("M6.9 18.4c2.6-6 5-.6 8.4-3.2 3-2.3 5.4-6 8.2-7.9")],
|
|
3218
|
+
text: [path("M7 8.5V6h14v2.5"), path("M14 6v16M11 22h6")],
|
|
3219
|
+
note: [path("M5.5 5h17v11.5l-6 6h-11V5Z"), path("M22.5 16.5h-6v6")],
|
|
3220
|
+
callout: [path("M4.5 6h19v11.5H13L8 22.5v-5H4.5V6Z")]
|
|
3221
|
+
};
|
|
3222
|
+
|
|
3135
3223
|
// src/themes.ts
|
|
3136
3224
|
var CHART_THEMES = {
|
|
3137
3225
|
midnight: {
|
|
@@ -4654,9 +4742,9 @@ function createChart(element, options = {}) {
|
|
|
4654
4742
|
const groupThousands = (value, decimals) => {
|
|
4655
4743
|
const negative = value < 0;
|
|
4656
4744
|
const fixed = Math.abs(value).toFixed(decimals);
|
|
4657
|
-
const
|
|
4658
|
-
const intPart =
|
|
4659
|
-
const decPart =
|
|
4745
|
+
const dot2 = fixed.indexOf(".");
|
|
4746
|
+
const intPart = dot2 === -1 ? fixed : fixed.slice(0, dot2);
|
|
4747
|
+
const decPart = dot2 === -1 ? "" : fixed.slice(dot2);
|
|
4660
4748
|
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4661
4749
|
return `${negative ? "-" : ""}${grouped}${decPart}`;
|
|
4662
4750
|
};
|
|
@@ -6253,6 +6341,8 @@ function createChart(element, options = {}) {
|
|
|
6253
6341
|
const palette = drawing.colors.length > 0 ? drawing.colors : null;
|
|
6254
6342
|
const levelColorAt = (index) => palette ? palette[index % palette.length] : drawing.color;
|
|
6255
6343
|
const move = p1.price - p0.price;
|
|
6344
|
+
const lineLeft = Math.min(x0, x1, x2);
|
|
6345
|
+
const lineRight = Math.max(x0, x1, x2);
|
|
6256
6346
|
const levelLines = FIB_EXT_RATIOS.map((ratio) => {
|
|
6257
6347
|
const price = p2.price + move * ratio;
|
|
6258
6348
|
return { ratio, price, y: yFromPrice(price) };
|
|
@@ -6265,7 +6355,7 @@ function createChart(element, options = {}) {
|
|
|
6265
6355
|
ctx.save();
|
|
6266
6356
|
ctx.fillStyle = hexToRgba(levelColorAt(index), 0.1);
|
|
6267
6357
|
ctx.globalAlpha = draft ? 0.5 : 1;
|
|
6268
|
-
ctx.fillRect(
|
|
6358
|
+
ctx.fillRect(lineLeft, bandTop, lineRight - lineLeft, bandBottom - bandTop);
|
|
6269
6359
|
ctx.restore();
|
|
6270
6360
|
}
|
|
6271
6361
|
ctx.save();
|
|
@@ -6274,8 +6364,8 @@ function createChart(element, options = {}) {
|
|
|
6274
6364
|
levelLines.forEach((level, index) => {
|
|
6275
6365
|
ctx.strokeStyle = levelColorAt(index);
|
|
6276
6366
|
ctx.beginPath();
|
|
6277
|
-
ctx.moveTo(crisp(
|
|
6278
|
-
ctx.lineTo(crisp(
|
|
6367
|
+
ctx.moveTo(crisp(lineLeft), crisp(level.y));
|
|
6368
|
+
ctx.lineTo(crisp(lineRight), crisp(level.y));
|
|
6279
6369
|
ctx.stroke();
|
|
6280
6370
|
});
|
|
6281
6371
|
ctx.restore();
|
|
@@ -6285,7 +6375,7 @@ function createChart(element, options = {}) {
|
|
|
6285
6375
|
const labelText = `${level.ratio} (${formatPrice(level.price)})`;
|
|
6286
6376
|
const textWidth = measureTextWidth(labelText);
|
|
6287
6377
|
const padding = 4;
|
|
6288
|
-
const bgX = chartLeft + 4;
|
|
6378
|
+
const bgX = Math.max(chartLeft + 2, lineLeft - textWidth - padding * 2 - 4);
|
|
6289
6379
|
const bgY = level.y - 9;
|
|
6290
6380
|
ctx.fillStyle = mergedOptions.backgroundColor;
|
|
6291
6381
|
fillRoundedRect(bgX, bgY, textWidth + padding * 2, 16, 3);
|
|
@@ -7234,12 +7324,12 @@ function createChart(element, options = {}) {
|
|
|
7234
7324
|
const upColumns = new Path2D();
|
|
7235
7325
|
const downColumns = new Path2D();
|
|
7236
7326
|
for (const column of seriesColumns) {
|
|
7237
|
-
const
|
|
7327
|
+
const path2 = column.close >= column.open ? upColumns : downColumns;
|
|
7238
7328
|
const x = column.x + 0.5;
|
|
7239
7329
|
const top = crisp(yFromPrice(column.high));
|
|
7240
7330
|
const bottom = crisp(yFromPrice(column.low));
|
|
7241
|
-
|
|
7242
|
-
|
|
7331
|
+
path2.moveTo(x, top);
|
|
7332
|
+
path2.lineTo(x, bottom === top ? bottom + 1 : bottom);
|
|
7243
7333
|
}
|
|
7244
7334
|
ctx.lineWidth = 1;
|
|
7245
7335
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7382,16 +7472,16 @@ function createChart(element, options = {}) {
|
|
|
7382
7472
|
const displayLow = isLastCandle && actualDirection === "down" ? Math.min(point.l, displayClose) : point.l;
|
|
7383
7473
|
const roundedCenterX = Math.round(chartLeft + (index + 0.5 - xStart) / xSpan * chartWidth);
|
|
7384
7474
|
const direction = isLastCandle ? actualDirection : getCandleDirectionByIndex(index);
|
|
7385
|
-
const
|
|
7475
|
+
const path2 = direction === "up" ? upBars : downBars;
|
|
7386
7476
|
const centerX = roundedCenterX + 0.5;
|
|
7387
|
-
|
|
7388
|
-
|
|
7477
|
+
path2.moveTo(centerX, crisp(yFromPrice(displayHigh)));
|
|
7478
|
+
path2.lineTo(centerX, crisp(yFromPrice(displayLow)));
|
|
7389
7479
|
const openY = crisp(yFromPrice(point.o));
|
|
7390
7480
|
const closeY = crisp(yFromPrice(displayClose));
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7481
|
+
path2.moveTo(centerX - tickLength, openY);
|
|
7482
|
+
path2.lineTo(centerX, openY);
|
|
7483
|
+
path2.moveTo(centerX, closeY);
|
|
7484
|
+
path2.lineTo(centerX + tickLength, closeY);
|
|
7395
7485
|
}
|
|
7396
7486
|
ctx.lineWidth = Math.max(1, candleWickWidth);
|
|
7397
7487
|
ctx.strokeStyle = mergedOptions.upColor;
|
|
@@ -7459,7 +7549,7 @@ function createChart(element, options = {}) {
|
|
|
7459
7549
|
for (const plan of comparePlans) {
|
|
7460
7550
|
const color = plan.state.options.color ?? "#f59e0b";
|
|
7461
7551
|
const lineWidth = Math.max(1, plan.state.options.lineWidth ?? 1.5);
|
|
7462
|
-
const
|
|
7552
|
+
const path2 = new Path2D();
|
|
7463
7553
|
let started = false;
|
|
7464
7554
|
let firstX = 0;
|
|
7465
7555
|
let lastX = 0;
|
|
@@ -7467,11 +7557,11 @@ function createChart(element, options = {}) {
|
|
|
7467
7557
|
let lastPrice = Number.NaN;
|
|
7468
7558
|
const emit = (x, y) => {
|
|
7469
7559
|
if (!started) {
|
|
7470
|
-
|
|
7560
|
+
path2.moveTo(x, y);
|
|
7471
7561
|
firstX = x;
|
|
7472
7562
|
started = true;
|
|
7473
7563
|
} else {
|
|
7474
|
-
|
|
7564
|
+
path2.lineTo(x, y);
|
|
7475
7565
|
}
|
|
7476
7566
|
lastX = x;
|
|
7477
7567
|
lastY = y;
|
|
@@ -7529,7 +7619,7 @@ function createChart(element, options = {}) {
|
|
|
7529
7619
|
}
|
|
7530
7620
|
if (!started) continue;
|
|
7531
7621
|
if (plan.state.options.style === "area") {
|
|
7532
|
-
const fillPath = new Path2D(
|
|
7622
|
+
const fillPath = new Path2D(path2);
|
|
7533
7623
|
fillPath.lineTo(lastX, chartBottom);
|
|
7534
7624
|
fillPath.lineTo(firstX, chartBottom);
|
|
7535
7625
|
fillPath.closePath();
|
|
@@ -7543,7 +7633,7 @@ function createChart(element, options = {}) {
|
|
|
7543
7633
|
ctx.strokeStyle = color;
|
|
7544
7634
|
ctx.lineWidth = lineWidth;
|
|
7545
7635
|
ctx.lineJoin = "round";
|
|
7546
|
-
ctx.stroke(
|
|
7636
|
+
ctx.stroke(path2);
|
|
7547
7637
|
ctx.restore();
|
|
7548
7638
|
if (Number.isFinite(lastPrice)) {
|
|
7549
7639
|
const label = plan.state.options.label ?? plan.state.options.id;
|
|
@@ -9351,12 +9441,16 @@ function createChart(element, options = {}) {
|
|
|
9351
9441
|
if (Math.hypot(x - x2, y - y2) <= 9 * hitTolerance) {
|
|
9352
9442
|
return { drawing, target: "handle", pointIndex: 1 };
|
|
9353
9443
|
}
|
|
9354
|
-
const
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
const
|
|
9358
|
-
|
|
9359
|
-
|
|
9444
|
+
const fibLeft = Math.min(x1, x2) - 5 * hitTolerance;
|
|
9445
|
+
const fibRight = Math.max(x1, x2) + 5 * hitTolerance;
|
|
9446
|
+
if (x >= fibLeft && x <= fibRight) {
|
|
9447
|
+
const fibRatios = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.618];
|
|
9448
|
+
for (const ratio of fibRatios) {
|
|
9449
|
+
const price = first.price + (second.price - first.price) * (1 - ratio);
|
|
9450
|
+
const lineY = canvasYFromDrawingPrice(price);
|
|
9451
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9452
|
+
return { drawing, target: "line" };
|
|
9453
|
+
}
|
|
9360
9454
|
}
|
|
9361
9455
|
}
|
|
9362
9456
|
} else if (drawing.type === "fib-extension") {
|
|
@@ -9381,11 +9475,15 @@ function createChart(element, options = {}) {
|
|
|
9381
9475
|
return { drawing, target: "handle", pointIndex: 2 };
|
|
9382
9476
|
}
|
|
9383
9477
|
const move = p1.price - p0.price;
|
|
9384
|
-
const
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9478
|
+
const extLeft = Math.min(x0, x1, x2) - 5 * hitTolerance;
|
|
9479
|
+
const extRight = Math.max(x0, x1, x2) + 5 * hitTolerance;
|
|
9480
|
+
if (x >= extLeft && x <= extRight) {
|
|
9481
|
+
const fibExtRatios = [0, 0.382, 0.5, 0.618, 1, 1.272, 1.618, 2.618];
|
|
9482
|
+
for (const ratio of fibExtRatios) {
|
|
9483
|
+
const lineY = canvasYFromDrawingPrice(p2.price + move * ratio);
|
|
9484
|
+
if (Math.abs(y - lineY) <= 5 * hitTolerance) {
|
|
9485
|
+
return { drawing, target: "line" };
|
|
9486
|
+
}
|
|
9389
9487
|
}
|
|
9390
9488
|
}
|
|
9391
9489
|
if (distanceToSegment(x, y, x0, y0, x1, y1) <= 6 * hitTolerance || distanceToSegment(x, y, x1, y1, x2, y2) <= 6 * hitTolerance) {
|
|
@@ -12339,6 +12437,9 @@ function createChart(element, options = {}) {
|
|
|
12339
12437
|
export {
|
|
12340
12438
|
CHART_THEMES,
|
|
12341
12439
|
CHART_THEME_NAMES,
|
|
12440
|
+
DRAWING_ICON_STROKE_WIDTH,
|
|
12441
|
+
DRAWING_ICON_VIEWBOX,
|
|
12442
|
+
DRAWING_TOOL_ICONS,
|
|
12342
12443
|
FIB_DEFAULT_PALETTE,
|
|
12343
12444
|
POSITION_DEFAULT_COLORS,
|
|
12344
12445
|
SCRIPT_SOURCE_INPUT_VALUES,
|