@luxalgo/vela 0.8.2 → 0.8.3
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/{DataProvider-DpOWZD8F.d.ts → DataProvider-oH78tYXL.d.ts} +1 -1
- package/dist/{DataProvider-COGDs9Xg.d.cts → DataProvider-wbtJ3-Sa.d.cts} +1 -1
- package/dist/{chunk-R2JMNIHY.js → chunk-2IPXYM4B.js} +258 -169
- package/dist/{chunk-NLDTVFOI.js → chunk-G7B7ZCBF.js} +129 -10
- package/dist/{chunk-T3DZIR5Y.js → chunk-HMHA733L.js} +306 -168
- package/dist/{chunk-DPAA3SRT.js → chunk-KWI3YDBW.js} +254 -9
- package/dist/{chunk-27UTYE7T.js → chunk-TO3GIK7Z.js} +49 -7
- package/dist/{chunk-HKNO24GD.js → chunk-VHGACEHO.js} +50 -1
- package/dist/{contributions-Cgm9RJYP.d.cts → contributions-BhOBRenr.d.cts} +44 -4
- package/dist/{contributions-bWgwyiVi.d.ts → contributions-HGqnNb_P.d.ts} +44 -4
- package/dist/index.cjs +497 -79
- package/dist/index.d.cts +34 -14
- package/dist/index.d.ts +34 -14
- package/dist/index.js +5 -5
- package/dist/{options-NAUHiQEC.d.ts → options-lMUwmRwh.d.cts} +66 -1
- package/dist/{options-NAUHiQEC.d.cts → options-lMUwmRwh.d.ts} +66 -1
- package/dist/{plugin-CqxWoDKS.d.ts → plugin-Cr2Pj8q8.d.ts} +4 -4
- package/dist/{plugin-CjjzZX2F.d.cts → plugin-Do5J5xuF.d.cts} +4 -4
- package/dist/plugin.cjs +18 -0
- package/dist/plugin.d.cts +5 -5
- package/dist/plugin.d.ts +5 -5
- package/dist/plugin.js +3 -3
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{side-panel-wMNfgyZb.d.cts → side-panel-_2UK1gSm.d.cts} +45 -3
- package/dist/{side-panel-wMNfgyZb.d.ts → side-panel-_2UK1gSm.d.ts} +45 -3
- package/dist/{statusline-model-Dpfpq54A.d.cts → statusline-model-B-2xGlB_.d.cts} +3 -3
- package/dist/{statusline-model-Dih6FGWP.d.ts → statusline-model-CY1wzxHg.d.ts} +3 -3
- package/dist/ui.cjs +224 -14
- package/dist/ui.d.cts +119 -87
- package/dist/ui.d.ts +119 -87
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +497 -79
- package/dist/vela.global.min.js +86 -52
- package/dist/widget.cjs +850 -167
- package/dist/widget.d.cts +24 -10
- package/dist/widget.d.ts +24 -10
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +849 -167
- package/dist/workspace.d.cts +47 -20
- package/dist/workspace.d.ts +47 -20
- package/dist/workspace.js +6 -6
- package/package.json +1 -1
- /package/dist/{chunk-JU4CWEBF.js → chunk-W5YPYZ2P.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES,
|
|
2
|
-
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, statePersistenceHandlers, topbarHas, rendererDefaults, mobilePlacement, widgetAttachments, getDrawingType, inputDeltas } from './chunk-
|
|
3
|
-
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-
|
|
4
|
-
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-
|
|
5
|
-
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, announceSurface, icon, categoricalColor } from './chunk-
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, SecondClock, isGroupRow, defaultMemberOf, groupKeyOf, groupMembers, LEGEND_AT_TOP_ATTR, normalizeSession, Vela, TypedEventBus, timeframeToMs, MultiProviderFeed, registerBuiltinChartTypes, resolveTheme, buildToolbar, createCustomMark, createAttributionMark, DrawingToolbar, applyAttributionMarkTheme, sharedBarStore, CANDLE_OVERRIDE_KEYS } from './chunk-HMHA733L.js';
|
|
2
|
+
import { chartType, resolveTopbarComposition, topbarActionOverride, TOPBAR_BUILTIN_IDS, widgetActions, tzButtonLabel, resolveTimezone, timezoneMenuRows, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, symbolRanking, paneScaleAt, composeMenu, priceAxisItems, scaleChoiceOf, timeAxisItems, bodyItems, scaleWrites, invertWrite, settingsSectionOf, resolveEngines, legendActionsProviderFor, legendCalloutsProviderFor, normalizeTimezone, isExchangeTimezone, statePersistenceHandlers, topbarHas, rendererDefaults, mobilePlacement, widgetAttachments, getDrawingType, inputDeltas } from './chunk-KWI3YDBW.js';
|
|
3
|
+
import { Tooltip, KeymapManager, isEditableTarget, Drawer } from './chunk-TO3GIK7Z.js';
|
|
4
|
+
import { Menu, Dialog, CalloutBubble, applyPlotOverlayTokens, ensureUIHost } from './chunk-G7B7ZCBF.js';
|
|
5
|
+
import { registerIcon, svg16, injectStyles, iconEl, iconMarkup, iconAt, SESSION_OFF, SESSION_POST, SESSION_PRE, announceSurface, holdForExit, icon, categoricalColor } from './chunk-VHGACEHO.js';
|
|
6
6
|
import { baseOf } from './chunk-W4EJWLEO.js';
|
|
7
7
|
|
|
8
8
|
// src/widget/timeframe.ts
|
|
@@ -108,11 +108,11 @@ function timeframeLabel(value) {
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// src/widget/layout-picker.ts
|
|
111
|
-
var STYLE_ID = "vela-widget-layout-picker-
|
|
111
|
+
var STYLE_ID = "vela-widget-layout-picker-v15";
|
|
112
112
|
var CSS = `
|
|
113
113
|
.vela-lp-layer { position: absolute; z-index: var(--vela-z-menu); }
|
|
114
114
|
.vela-lp {
|
|
115
|
-
background: var(--vela-surface
|
|
115
|
+
background: var(--vela-surface);
|
|
116
116
|
color: var(--vela-fg);
|
|
117
117
|
border: 1px solid var(--vela-border-strong);
|
|
118
118
|
border-radius: 8px;
|
|
@@ -241,6 +241,8 @@ var LayoutPicker = class {
|
|
|
241
241
|
constructor(opts) {
|
|
242
242
|
this.squares = [];
|
|
243
243
|
this.isOpen = false;
|
|
244
|
+
/** The card's exit animation after a close; a reopen cancels it. */
|
|
245
|
+
this.exit = null;
|
|
244
246
|
/** Hover preview (1-based rows/cols), null = show current shape. */
|
|
245
247
|
this.hover = null;
|
|
246
248
|
this.onDocPointerDown = (e) => {
|
|
@@ -335,6 +337,8 @@ var LayoutPicker = class {
|
|
|
335
337
|
open() {
|
|
336
338
|
if (this.isOpen) return;
|
|
337
339
|
this.isOpen = true;
|
|
340
|
+
this.exit?.cancel();
|
|
341
|
+
this.exit = null;
|
|
338
342
|
this.hover = null;
|
|
339
343
|
this.refresh();
|
|
340
344
|
this.layer.style.display = "";
|
|
@@ -349,7 +353,10 @@ var LayoutPicker = class {
|
|
|
349
353
|
if (!this.isOpen) return;
|
|
350
354
|
this.isOpen = false;
|
|
351
355
|
announceSurface(this.panel, false, "popover", this.opts.trigger);
|
|
352
|
-
this.
|
|
356
|
+
this.exit = holdForExit(this.panel, () => {
|
|
357
|
+
this.exit = null;
|
|
358
|
+
if (!this.isOpen) this.layer.style.display = "none";
|
|
359
|
+
});
|
|
353
360
|
this.opts.trigger.setAttribute("aria-expanded", "false");
|
|
354
361
|
this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
|
|
355
362
|
this.doc.removeEventListener("keydown", this.onDocKeydown, true);
|
|
@@ -364,6 +371,7 @@ var LayoutPicker = class {
|
|
|
364
371
|
}
|
|
365
372
|
destroy() {
|
|
366
373
|
this.close();
|
|
374
|
+
this.exit?.finish();
|
|
367
375
|
this.infoTip.destroy();
|
|
368
376
|
this.layer.remove();
|
|
369
377
|
}
|
|
@@ -430,7 +438,7 @@ var LayoutPicker = class {
|
|
|
430
438
|
const hostRect = this.opts.host.getBoundingClientRect();
|
|
431
439
|
const trigRect = this.opts.trigger.getBoundingClientRect();
|
|
432
440
|
let left = trigRect.left - hostRect.left;
|
|
433
|
-
const top = trigRect.bottom - hostRect.top +
|
|
441
|
+
const top = trigRect.bottom - hostRect.top + 8;
|
|
434
442
|
const width = this.layer.offsetWidth;
|
|
435
443
|
if (left + width > hostRect.width - 8) left = Math.max(8, hostRect.width - 8 - width);
|
|
436
444
|
this.layer.style.left = `${left}px`;
|
|
@@ -783,7 +791,8 @@ var Topbar = class {
|
|
|
783
791
|
triggerId: "vela-topbar-style",
|
|
784
792
|
host,
|
|
785
793
|
items: this.styleItems(),
|
|
786
|
-
onSelect: (id) => opts.onPriceStyle(id)
|
|
794
|
+
onSelect: (id) => opts.onPriceStyle(id),
|
|
795
|
+
iconBadges: true
|
|
787
796
|
});
|
|
788
797
|
}
|
|
789
798
|
setSymbol(symbol) {
|
|
@@ -849,8 +858,14 @@ var Topbar = class {
|
|
|
849
858
|
renderLayoutButton(doc) {
|
|
850
859
|
if (!this.layoutButton) return;
|
|
851
860
|
this.layoutButton.replaceChildren();
|
|
852
|
-
|
|
853
|
-
|
|
861
|
+
const glyph = this.opts.layout?.glyph?.();
|
|
862
|
+
if (glyph || iconMarkup("layout")) {
|
|
863
|
+
const icon2 = iconEl("layout", doc);
|
|
864
|
+
if (glyph) icon2.innerHTML = glyph;
|
|
865
|
+
this.layoutButton.appendChild(icon2);
|
|
866
|
+
} else {
|
|
867
|
+
this.layoutButton.appendChild(doc.createTextNode(this.layoutId ?? ""));
|
|
868
|
+
}
|
|
854
869
|
this.layoutButton.setAttribute("aria-label", `Layout \u2014 ${this.layoutId ?? ""}`);
|
|
855
870
|
}
|
|
856
871
|
renderStyleButton(doc) {
|
|
@@ -1704,8 +1719,8 @@ var ObjectTree = class extends SidePanel {
|
|
|
1704
1719
|
set groups(next) {
|
|
1705
1720
|
if (this.chart) this.groupsPerChart.set(this.chart, next);
|
|
1706
1721
|
}
|
|
1707
|
-
toggle(open = this.
|
|
1708
|
-
super.toggle(open);
|
|
1722
|
+
toggle(open = !this.open, instant = false) {
|
|
1723
|
+
super.toggle(open, instant);
|
|
1709
1724
|
if (open) this.refresh();
|
|
1710
1725
|
}
|
|
1711
1726
|
setSymbol(symbol) {
|
|
@@ -2739,8 +2754,8 @@ var DataWindow = class extends SidePanel {
|
|
|
2739
2754
|
this.unsubs = [];
|
|
2740
2755
|
injectStyles(STYLE_ID5, CSS5, host.ownerDocument);
|
|
2741
2756
|
}
|
|
2742
|
-
toggle(open = this.
|
|
2743
|
-
super.toggle(open);
|
|
2757
|
+
toggle(open = !this.open, instant = false) {
|
|
2758
|
+
super.toggle(open, instant);
|
|
2744
2759
|
if (open) this.refresh();
|
|
2745
2760
|
}
|
|
2746
2761
|
/** (Re)bind to a chart instance — called after every widget rebuild. */
|
|
@@ -2910,7 +2925,7 @@ var PanelDock = class {
|
|
|
2910
2925
|
}
|
|
2911
2926
|
this.pinned = new Set(state.pinned ?? []);
|
|
2912
2927
|
for (const entry of this.entries) entry.panel.setOverlay(!this.pinned.has(entry.id));
|
|
2913
|
-
for (const entry of this.entries) entry.panel.toggle(entry.id === state.open);
|
|
2928
|
+
for (const entry of this.entries) entry.panel.toggle(entry.id === state.open, true);
|
|
2914
2929
|
this.pendingOpen = state.open && !this.entries.some((e) => e.id === state.open) ? state.open : null;
|
|
2915
2930
|
}
|
|
2916
2931
|
/** Drop the contributed panels (the shell destroys its own). */
|
|
@@ -2926,7 +2941,7 @@ var PanelDock = class {
|
|
|
2926
2941
|
if (this.pinned.has(entry.id)) entry.panel.setOverlay(false);
|
|
2927
2942
|
entry.panel.onOpenChange = (open) => {
|
|
2928
2943
|
if (open) {
|
|
2929
|
-
for (const other of this.entries) if (other !== entry) other.panel.toggle(false);
|
|
2944
|
+
for (const other of this.entries) if (other !== entry) other.panel.toggle(false, true);
|
|
2930
2945
|
this.pendingOpen = null;
|
|
2931
2946
|
}
|
|
2932
2947
|
this.deps.chrome.setPanelActive(entry.id, open);
|
|
@@ -4042,15 +4057,48 @@ function syncTargets(originId, setting, cellIds) {
|
|
|
4042
4057
|
function rangesWithin(a, b, epsMs) {
|
|
4043
4058
|
return Math.abs(a.from - b.from) <= epsMs && Math.abs(a.to - b.to) <= epsMs;
|
|
4044
4059
|
}
|
|
4045
|
-
var STYLE_SYNC_CONFIG_KEYS = [
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4060
|
+
var STYLE_SYNC_CONFIG_KEYS = [
|
|
4061
|
+
"layout",
|
|
4062
|
+
"panes",
|
|
4063
|
+
"grid",
|
|
4064
|
+
"margins",
|
|
4065
|
+
"priceScale",
|
|
4066
|
+
"crosshair",
|
|
4067
|
+
"animations",
|
|
4068
|
+
"candles",
|
|
4069
|
+
"bars",
|
|
4070
|
+
"line",
|
|
4071
|
+
"area",
|
|
4072
|
+
"baseline",
|
|
4073
|
+
"sessions"
|
|
4074
|
+
];
|
|
4075
|
+
function styleConfigPatch(origin, follower) {
|
|
4076
|
+
const from = asRecord(origin);
|
|
4077
|
+
const to = asRecord(follower);
|
|
4078
|
+
if (!from || !to) return null;
|
|
4079
|
+
const patch = {};
|
|
4050
4080
|
for (const key of STYLE_SYNC_CONFIG_KEYS) {
|
|
4051
|
-
|
|
4081
|
+
const block = asRecord(from[key]);
|
|
4082
|
+
if (block && JSON.stringify(block) !== JSON.stringify(to[key])) patch[key] = block;
|
|
4052
4083
|
}
|
|
4053
|
-
|
|
4084
|
+
const spacing = asRecord(from.series)?.spacing;
|
|
4085
|
+
if (typeof spacing === "number" && spacing !== asRecord(to.series)?.spacing) patch.series = { spacing };
|
|
4086
|
+
const fromTypes = asRecord(from.chartTypes) ?? {};
|
|
4087
|
+
const toTypes = asRecord(to.chartTypes) ?? {};
|
|
4088
|
+
const types = {};
|
|
4089
|
+
for (const typeId of /* @__PURE__ */ new Set([...Object.keys(fromTypes), ...Object.keys(toTypes)])) {
|
|
4090
|
+
const src = asRecord(fromTypes[typeId]) ?? {};
|
|
4091
|
+
const dst = asRecord(toTypes[typeId]) ?? {};
|
|
4092
|
+
for (const key of CANDLE_OVERRIDE_KEYS) {
|
|
4093
|
+
const value = src[key] ?? null;
|
|
4094
|
+
if (value !== (dst[key] ?? null)) (types[typeId] ?? (types[typeId] = {}))[key] = value;
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
if (Object.keys(types).length > 0) patch.chartTypes = types;
|
|
4098
|
+
return Object.keys(patch).length > 0 ? patch : null;
|
|
4099
|
+
}
|
|
4100
|
+
function asRecord(v) {
|
|
4101
|
+
return v != null && typeof v === "object" ? v : null;
|
|
4054
4102
|
}
|
|
4055
4103
|
|
|
4056
4104
|
// src/workspace/persist.ts
|
|
@@ -4812,113 +4860,28 @@ var Watermark = class {
|
|
|
4812
4860
|
}
|
|
4813
4861
|
};
|
|
4814
4862
|
|
|
4815
|
-
// src/widget/context-menu-model.ts
|
|
4816
|
-
var SETTINGS_SECTION = {
|
|
4817
|
-
body: "Canvas",
|
|
4818
|
-
"price-axis": "Scales and lines",
|
|
4819
|
-
"time-axis": "Scales and lines"
|
|
4820
|
-
};
|
|
4821
|
-
function settingsItem(zone, label) {
|
|
4822
|
-
return { id: `settings:${SETTINGS_SECTION[zone]}`, label, separatorBefore: true };
|
|
4823
|
-
}
|
|
4824
|
-
function settingsSectionOf(id) {
|
|
4825
|
-
return id.slice("settings:".length) || void 0;
|
|
4826
|
-
}
|
|
4827
|
-
var SCALE_CHOICES = [
|
|
4828
|
-
["regular", "Regular"],
|
|
4829
|
-
["percent", "Percent"],
|
|
4830
|
-
["indexed", "Indexed to 100"],
|
|
4831
|
-
["log", "Logarithmic"]
|
|
4832
|
-
];
|
|
4833
|
-
function paneScaleAt(panes, y) {
|
|
4834
|
-
return panes.find((p) => y >= p.top && y < p.top + p.height) ?? panes[0] ?? null;
|
|
4835
|
-
}
|
|
4836
|
-
function scaleChoiceOf(scale) {
|
|
4837
|
-
if (scale.log) return "log";
|
|
4838
|
-
if (scale.mode === "percent") return "percent";
|
|
4839
|
-
if (scale.mode === "indexed") return "indexed";
|
|
4840
|
-
return "regular";
|
|
4841
|
-
}
|
|
4842
|
-
function mainScale(pane) {
|
|
4843
|
-
return pane === null || pane.kind === "price";
|
|
4844
|
-
}
|
|
4845
|
-
function scaleWrites(choice, pane) {
|
|
4846
|
-
const mode = choice === "percent" ? "percent" : choice === "indexed" ? "indexed" : "price";
|
|
4847
|
-
const log = choice === "log";
|
|
4848
|
-
if (mainScale(pane)) {
|
|
4849
|
-
return [
|
|
4850
|
-
["scaleMode", mode],
|
|
4851
|
-
["logScale", log]
|
|
4852
|
-
];
|
|
4853
|
-
}
|
|
4854
|
-
return [
|
|
4855
|
-
["scaleMode", { pane: pane.id, mode }],
|
|
4856
|
-
["logScale", { pane: pane.id, value: log }]
|
|
4857
|
-
];
|
|
4858
|
-
}
|
|
4859
|
-
function invertWrite(next, pane) {
|
|
4860
|
-
return mainScale(pane) ? ["invertScale", next] : ["invertScale", { pane: pane.id, value: next }];
|
|
4861
|
-
}
|
|
4862
|
-
function priceAxisItems(s) {
|
|
4863
|
-
return [
|
|
4864
|
-
{ id: "auto", label: "Auto (fits data to screen)", checked: s.auto },
|
|
4865
|
-
{ id: "invert", label: "Invert scale", checked: s.invert },
|
|
4866
|
-
...SCALE_CHOICES.map(([choice, label], i) => ({
|
|
4867
|
-
id: `scale:${choice}`,
|
|
4868
|
-
label,
|
|
4869
|
-
checked: s.choice === choice,
|
|
4870
|
-
separatorBefore: i === 0
|
|
4871
|
-
})),
|
|
4872
|
-
{
|
|
4873
|
-
id: "labels",
|
|
4874
|
-
label: "Labels",
|
|
4875
|
-
separatorBefore: true,
|
|
4876
|
-
submenu: [
|
|
4877
|
-
{ id: "toggle:axisLabels", label: "Price axis labels", checked: s.axisLabels },
|
|
4878
|
-
{ id: "toggle:priceLabel", label: "Last price label", checked: s.priceLabel },
|
|
4879
|
-
{ id: "toggle:countdown", label: "Countdown to bar close", checked: s.countdown }
|
|
4880
|
-
]
|
|
4881
|
-
},
|
|
4882
|
-
{
|
|
4883
|
-
id: "levels",
|
|
4884
|
-
label: "Levels",
|
|
4885
|
-
submenu: [{ id: "toggle:currentPriceLine", label: "Last Price Line", checked: s.priceLine }]
|
|
4886
|
-
},
|
|
4887
|
-
settingsItem("price-axis", "More settings\u2026")
|
|
4888
|
-
];
|
|
4889
|
-
}
|
|
4890
|
-
function timeAxisItems(timezone) {
|
|
4891
|
-
return [
|
|
4892
|
-
{
|
|
4893
|
-
id: "timezone",
|
|
4894
|
-
label: "Time zone",
|
|
4895
|
-
submenu: timezoneMenuRows(timezone).map((r) => ({ id: `tz:${r.value}`, label: r.label, checked: r.checked }))
|
|
4896
|
-
},
|
|
4897
|
-
settingsItem("time-axis", "More settings\u2026")
|
|
4898
|
-
];
|
|
4899
|
-
}
|
|
4900
|
-
function bodyItems(counts) {
|
|
4901
|
-
return [
|
|
4902
|
-
{ id: "reset-view", label: "Reset chart view" },
|
|
4903
|
-
{ id: "remove-drawings", label: "Remove drawings", disabled: counts.drawings === 0, separatorBefore: true },
|
|
4904
|
-
{ id: "remove-indicators", label: "Remove indicators", disabled: counts.indicators === 0 },
|
|
4905
|
-
settingsItem("body", "Settings\u2026")
|
|
4906
|
-
];
|
|
4907
|
-
}
|
|
4908
|
-
|
|
4909
4863
|
// src/widget/context-menu.ts
|
|
4910
4864
|
var PRICE_AXIS_W = 60;
|
|
4911
4865
|
var TIME_AXIS_H = 26;
|
|
4866
|
+
var OFF_PLOT = { price: null, time: null, paneKind: null };
|
|
4912
4867
|
var ChartContextMenu = class {
|
|
4913
4868
|
constructor(host, cbs) {
|
|
4914
4869
|
this.cbs = cbs;
|
|
4915
4870
|
this.chart = null;
|
|
4871
|
+
this.offCrosshair = null;
|
|
4872
|
+
/** The bound chart's latest crosshair report — a right-click always follows a pointer
|
|
4873
|
+
* move to its spot, so this is where it landed. */
|
|
4874
|
+
this.crosshair = OFF_PLOT;
|
|
4875
|
+
/** {@link crosshair} as it stood when the menu opened: the pointer moves on through the
|
|
4876
|
+
* menu before a row is picked, and `run` must see the right-clicked spot. */
|
|
4877
|
+
this.pointer = OFF_PLOT;
|
|
4916
4878
|
this.lastZone = "body";
|
|
4917
4879
|
/** The pane whose scale the open price-axis menu targets (null ⇒ the main scale). */
|
|
4918
4880
|
this.lastPane = null;
|
|
4919
4881
|
this.onContextMenu = (e) => {
|
|
4920
4882
|
e.preventDefault();
|
|
4921
4883
|
if (!this.chart) return;
|
|
4884
|
+
this.pointer = this.crosshair;
|
|
4922
4885
|
this.lastZone = this.zoneOf(e);
|
|
4923
4886
|
this.lastPane = this.lastZone === "price-axis" ? this.paneAt(e) : null;
|
|
4924
4887
|
this.menu.setItems(this.itemsFor(this.lastZone));
|
|
@@ -4932,15 +4895,23 @@ var ChartContextMenu = class {
|
|
|
4932
4895
|
// Pointer-anchored action menu: checked state reads as a leading ✓, not a
|
|
4933
4896
|
// washed row (which would read as hover in a menu with no trigger button).
|
|
4934
4897
|
checkmarks: true,
|
|
4898
|
+
iconBadges: true,
|
|
4935
4899
|
onSelect: (id) => this.run(id)
|
|
4936
4900
|
});
|
|
4937
4901
|
host.addEventListener("contextmenu", this.onContextMenu);
|
|
4938
4902
|
}
|
|
4939
4903
|
/** (Re)bind to a chart instance — called after every widget rebuild. */
|
|
4940
4904
|
onChart(chart) {
|
|
4905
|
+
this.offCrosshair?.();
|
|
4941
4906
|
this.chart = chart;
|
|
4907
|
+
this.crosshair = OFF_PLOT;
|
|
4908
|
+
this.offCrosshair = chart.renderer.onCrosshairMove((e) => {
|
|
4909
|
+
this.crosshair = { price: e.price, time: e.time, paneKind: e.paneKind ?? null };
|
|
4910
|
+
});
|
|
4942
4911
|
}
|
|
4943
4912
|
destroy() {
|
|
4913
|
+
this.offCrosshair?.();
|
|
4914
|
+
this.offCrosshair = null;
|
|
4944
4915
|
this.host.removeEventListener("contextmenu", this.onContextMenu);
|
|
4945
4916
|
this.menu.destroy();
|
|
4946
4917
|
}
|
|
@@ -4959,49 +4930,52 @@ var ChartContextMenu = class {
|
|
|
4959
4930
|
flag(feature) {
|
|
4960
4931
|
return Boolean(this.chart?.renderer.get(feature));
|
|
4961
4932
|
}
|
|
4962
|
-
|
|
4933
|
+
/** A fresh widget context carrying the pointer captured at open. Copied by property
|
|
4934
|
+
* descriptor: the context's getters must stay LIVE, and a spread would freeze them. */
|
|
4935
|
+
context() {
|
|
4963
4936
|
const ctx = this.cbs.getContext?.();
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4937
|
+
if (!ctx) return void 0;
|
|
4938
|
+
return Object.create(Object.getPrototypeOf(ctx), {
|
|
4939
|
+
...Object.getOwnPropertyDescriptors(ctx),
|
|
4940
|
+
pointer: { value: this.pointer, enumerable: true }
|
|
4941
|
+
});
|
|
4942
|
+
}
|
|
4943
|
+
contributed(zone) {
|
|
4944
|
+
return widgetActions(`context:${zone}`, this.context()).map((a) => ({
|
|
4945
|
+
item: { id: `action:${a.id}`, label: a.label, icon: a.icon },
|
|
4946
|
+
order: a.order
|
|
4969
4947
|
}));
|
|
4970
4948
|
}
|
|
4971
4949
|
itemsFor(zone) {
|
|
4950
|
+
return composeMenu(zone, this.builtinItems(zone), this.contributed(zone));
|
|
4951
|
+
}
|
|
4952
|
+
builtinItems(zone) {
|
|
4972
4953
|
if (zone === "price-axis") {
|
|
4973
4954
|
const pane = this.lastPane;
|
|
4974
|
-
return
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
}),
|
|
4984
|
-
...this.contributed(zone)
|
|
4985
|
-
];
|
|
4955
|
+
return priceAxisItems({
|
|
4956
|
+
auto: this.chart?.renderer.get("autoScale") !== false,
|
|
4957
|
+
invert: pane ? pane.invert : this.flag("invertScale"),
|
|
4958
|
+
choice: scaleChoiceOf(pane ?? { mode: String(this.chart?.renderer.get("scaleMode") ?? "price"), log: this.flag("logScale") }),
|
|
4959
|
+
axisLabels: this.flag("axisLabels"),
|
|
4960
|
+
priceLabel: this.flag("priceLabel"),
|
|
4961
|
+
countdown: this.flag("countdown"),
|
|
4962
|
+
priceLine: this.flag("currentPriceLine")
|
|
4963
|
+
});
|
|
4986
4964
|
}
|
|
4987
4965
|
if (zone === "time-axis") {
|
|
4988
|
-
|
|
4989
|
-
return [...timeAxisItems(tz), ...this.contributed("time-axis")];
|
|
4966
|
+
return timeAxisItems(this.cbs.timezone?.() ?? String(this.chart?.renderer.get("timezone") ?? "Etc/UTC"));
|
|
4990
4967
|
}
|
|
4991
4968
|
const chart = this.chart;
|
|
4992
|
-
return
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
}),
|
|
4997
|
-
...this.contributed("body")
|
|
4998
|
-
];
|
|
4969
|
+
return bodyItems({
|
|
4970
|
+
drawings: chart?.drawings.supported ? chart.drawings.all().length : 0,
|
|
4971
|
+
indicators: chart?.indicators().length ?? 0
|
|
4972
|
+
});
|
|
4999
4973
|
}
|
|
5000
4974
|
run(id) {
|
|
5001
4975
|
const chart = this.chart;
|
|
5002
4976
|
if (!chart) return;
|
|
5003
4977
|
if (id.startsWith("action:")) {
|
|
5004
|
-
const ctx = this.
|
|
4978
|
+
const ctx = this.context();
|
|
5005
4979
|
if (ctx) widgetActions(`context:${this.lastZone}`, ctx).find((a) => a.id === id.slice("action:".length))?.run(ctx);
|
|
5006
4980
|
return;
|
|
5007
4981
|
}
|
|
@@ -5651,8 +5625,8 @@ function seedDefaults(opts) {
|
|
|
5651
5625
|
};
|
|
5652
5626
|
}
|
|
5653
5627
|
function cellChartDefaults(opts) {
|
|
5654
|
-
const { renderer, defaultLanguage, currentPriceLine, logScale, animations, glow, upColor, downColor, drawings, settings } = opts;
|
|
5655
|
-
return { renderer, defaultLanguage, currentPriceLine, logScale, animations, glow, upColor, downColor, drawings, settings };
|
|
5628
|
+
const { renderer, defaultLanguage, currentPriceLine, logScale, animations, glow, upColor, downColor, drawings, settings, priceAxis } = opts;
|
|
5629
|
+
return { renderer, defaultLanguage, currentPriceLine, logScale, animations, glow, upColor, downColor, drawings, settings, priceAxis };
|
|
5656
5630
|
}
|
|
5657
5631
|
function cellDrawings(opt) {
|
|
5658
5632
|
if (opt === false) return false;
|
|
@@ -6222,12 +6196,14 @@ var ChartCell = class {
|
|
|
6222
6196
|
this.watermarkOn = visible;
|
|
6223
6197
|
this.watermark?.setVisible(visible);
|
|
6224
6198
|
this.deps.onStateDirty();
|
|
6199
|
+
this.deps.onStatusPrefsChanged(this.id);
|
|
6225
6200
|
}
|
|
6226
6201
|
/** Show/hide the "Replay" line under this cell's watermark while it replays (persisted per cell). */
|
|
6227
6202
|
setReplayWatermarkVisible(visible) {
|
|
6228
6203
|
this.replayWatermarkOn = visible;
|
|
6229
6204
|
this.watermark?.setReplayVisible(visible);
|
|
6230
6205
|
this.deps.onStateDirty();
|
|
6206
|
+
this.deps.onStatusPrefsChanged(this.id);
|
|
6231
6207
|
}
|
|
6232
6208
|
/** Show/hide this cell's indicator titles — the in-chart legend rows (persisted per cell). */
|
|
6233
6209
|
setIndicatorTitlesVisible(visible) {
|
|
@@ -6248,18 +6224,20 @@ var ChartCell = class {
|
|
|
6248
6224
|
this.statusline?.setPartVisible(part, visible);
|
|
6249
6225
|
this.deps.onStatusPrefsChanged(this.id);
|
|
6250
6226
|
}
|
|
6251
|
-
/** This cell's Status line tab prefs as one bundle (see {@link CellStatusPrefs}). */
|
|
6227
|
+
/** This cell's Status line tab and watermark prefs as one bundle (see {@link CellStatusPrefs}). */
|
|
6252
6228
|
statusPrefs() {
|
|
6253
6229
|
const sl = this.statusline;
|
|
6254
6230
|
return {
|
|
6255
6231
|
parts: sl ? { logo: sl.partVisible("logo"), name: sl.partVisible("name"), market: sl.partVisible("market"), ohlc: sl.partVisible("ohlc"), change: sl.partVisible("change") } : null,
|
|
6256
6232
|
indicatorTitles: this.indicatorTitlesOn,
|
|
6257
|
-
indicatorValues: this.indicatorValuesOn
|
|
6233
|
+
indicatorValues: this.indicatorValuesOn,
|
|
6234
|
+
watermark: this.watermarkOn,
|
|
6235
|
+
replayWatermark: this.replayWatermarkOn
|
|
6258
6236
|
};
|
|
6259
6237
|
}
|
|
6260
|
-
/** Converge this cell's Status line tab prefs to `prefs` — the
|
|
6261
|
-
* the workspace's style link. Idempotent: matching values change
|
|
6262
|
-
* propagated echo dies on its own. */
|
|
6238
|
+
/** Converge this cell's Status line tab and watermark prefs to `prefs` — the
|
|
6239
|
+
* follower half of the workspace's style link. Idempotent: matching values change
|
|
6240
|
+
* nothing, so a propagated echo dies on its own. */
|
|
6263
6241
|
applyStatusPrefs(prefs) {
|
|
6264
6242
|
if (prefs.parts && this.statusline) {
|
|
6265
6243
|
for (const part of Object.keys(prefs.parts)) {
|
|
@@ -6268,6 +6246,8 @@ var ChartCell = class {
|
|
|
6268
6246
|
}
|
|
6269
6247
|
if (prefs.indicatorTitles !== this.indicatorTitlesOn) this.setIndicatorTitlesVisible(prefs.indicatorTitles);
|
|
6270
6248
|
if (prefs.indicatorValues !== this.indicatorValuesOn) this.setIndicatorValuesVisible(prefs.indicatorValues);
|
|
6249
|
+
if (prefs.watermark !== this.watermarkOn) this.setWatermarkVisible(prefs.watermark);
|
|
6250
|
+
if (prefs.replayWatermark !== this.replayWatermarkOn) this.setReplayWatermarkVisible(prefs.replayWatermark);
|
|
6271
6251
|
}
|
|
6272
6252
|
/** The LIVE chart of this cell — never cache it across a layout change (the cell's
|
|
6273
6253
|
* identity is what endures; the chart dies with the cell). */
|
|
@@ -7139,6 +7119,55 @@ function occupancyGrid(def) {
|
|
|
7139
7119
|
const cols = def.cols.length;
|
|
7140
7120
|
return def.rows.map((_, r) => def.cols.map((_2, c) => def.cells[r * cols + c]?.id ?? `\xB7${r}x${c}`));
|
|
7141
7121
|
}
|
|
7122
|
+
var GLYPH_MIN = 1.5;
|
|
7123
|
+
var GLYPH_SPAN = 13;
|
|
7124
|
+
function glyphStops(weights, n) {
|
|
7125
|
+
const w = Array.from({ length: n }, (_, i) => {
|
|
7126
|
+
const v = weights[i];
|
|
7127
|
+
return v !== void 0 && Number.isFinite(v) && v > 0 ? v : 1;
|
|
7128
|
+
});
|
|
7129
|
+
const total = w.reduce((a, b) => a + b, 0);
|
|
7130
|
+
const stops = [GLYPH_MIN];
|
|
7131
|
+
let acc = 0;
|
|
7132
|
+
for (const v of w) {
|
|
7133
|
+
acc += v;
|
|
7134
|
+
stops.push(Math.round((GLYPH_MIN + GLYPH_SPAN * acc / total) * 100) / 100);
|
|
7135
|
+
}
|
|
7136
|
+
return stops;
|
|
7137
|
+
}
|
|
7138
|
+
function layoutGlyph(def) {
|
|
7139
|
+
const grid = occupancyGrid(def);
|
|
7140
|
+
const rows = grid.length;
|
|
7141
|
+
const cols = grid.reduce((n, row) => Math.max(n, row.length), 0);
|
|
7142
|
+
const xs = glyphStops(def.cols, cols);
|
|
7143
|
+
const ys = glyphStops(def.rows, rows);
|
|
7144
|
+
const at = (r, c) => grid[r]?.[c];
|
|
7145
|
+
const seams = [];
|
|
7146
|
+
for (let c = 1; c < cols; c += 1) {
|
|
7147
|
+
let start = -1;
|
|
7148
|
+
for (let r = 0; r <= rows; r += 1) {
|
|
7149
|
+
const split = r < rows && at(r, c - 1) !== at(r, c);
|
|
7150
|
+
if (split && start < 0) start = r;
|
|
7151
|
+
if (!split && start >= 0) {
|
|
7152
|
+
seams.push(`M${xs[c]} ${ys[start]}V${ys[r]}`);
|
|
7153
|
+
start = -1;
|
|
7154
|
+
}
|
|
7155
|
+
}
|
|
7156
|
+
}
|
|
7157
|
+
for (let r = 1; r < rows; r += 1) {
|
|
7158
|
+
let start = -1;
|
|
7159
|
+
for (let c = 0; c <= cols; c += 1) {
|
|
7160
|
+
const split = c < cols && at(r - 1, c) !== at(r, c);
|
|
7161
|
+
if (split && start < 0) start = c;
|
|
7162
|
+
if (!split && start >= 0) {
|
|
7163
|
+
seams.push(`M${xs[start]} ${ys[r]}H${xs[c]}`);
|
|
7164
|
+
start = -1;
|
|
7165
|
+
}
|
|
7166
|
+
}
|
|
7167
|
+
}
|
|
7168
|
+
const frame = `<rect x="${GLYPH_MIN}" y="${GLYPH_MIN}" width="${GLYPH_SPAN}" height="${GLYPH_SPAN}" rx="1.5"/>`;
|
|
7169
|
+
return svg16(seams.length > 0 ? `${frame}<path d="${seams.join("")}"/>` : frame);
|
|
7170
|
+
}
|
|
7142
7171
|
function gridStyles(def, trackSizes) {
|
|
7143
7172
|
const cols = trackSizes?.cols?.length === def.cols.length ? trackSizes.cols : def.cols;
|
|
7144
7173
|
const rows = trackSizes?.rows?.length === def.rows.length ? trackSizes.rows : def.rows;
|
|
@@ -8049,7 +8078,11 @@ var MoreDrawer = class {
|
|
|
8049
8078
|
row(doc, label, opts) {
|
|
8050
8079
|
const el = doc.createElement("div");
|
|
8051
8080
|
el.className = "vela-md-row";
|
|
8052
|
-
if (opts.icon)
|
|
8081
|
+
if (opts.icon) {
|
|
8082
|
+
const icon2 = iconEl(opts.icon, doc);
|
|
8083
|
+
if (opts.glyph) icon2.innerHTML = opts.glyph;
|
|
8084
|
+
el.appendChild(icon2);
|
|
8085
|
+
}
|
|
8053
8086
|
const text = doc.createElement("span");
|
|
8054
8087
|
text.className = "vela-md-row-label";
|
|
8055
8088
|
text.textContent = label;
|
|
@@ -8091,7 +8124,7 @@ var MoreDrawer = class {
|
|
|
8091
8124
|
if (this.opts.layout) {
|
|
8092
8125
|
const shape = this.opts.layout.shape();
|
|
8093
8126
|
const value = shape ? `${shape.cols} \xD7 ${shape.rows}` : this.opts.layout.presets().find((p) => p.checked)?.label;
|
|
8094
|
-
list.appendChild(this.row(doc, "Layout", { icon: "layout", value, chevron: true, onClick: () => this.show("layout") }));
|
|
8127
|
+
list.appendChild(this.row(doc, "Layout", { icon: "layout", glyph: this.opts.layout.glyph?.(), value, chevron: true, onClick: () => this.show("layout") }));
|
|
8095
8128
|
}
|
|
8096
8129
|
for (const act of this.opts.primaryActions?.() ?? []) list.appendChild(this.actionRow(doc, act));
|
|
8097
8130
|
for (const panel of this.opts.panels()) {
|
|
@@ -8955,7 +8988,8 @@ var VelaWorkspace = class {
|
|
|
8955
8988
|
onToggleSync: (id) => {
|
|
8956
8989
|
const kind = id;
|
|
8957
8990
|
this.sync.set(kind, this.syncOpts[kind] ? false : true);
|
|
8958
|
-
}
|
|
8991
|
+
},
|
|
8992
|
+
glyph: () => layoutGlyph(this.def)
|
|
8959
8993
|
},
|
|
8960
8994
|
getContext: () => this.context()
|
|
8961
8995
|
});
|
|
@@ -9454,6 +9488,7 @@ var VelaWorkspace = class {
|
|
|
9454
9488
|
this.applyGrid();
|
|
9455
9489
|
this.buildCells();
|
|
9456
9490
|
this.alignNewCellStyles(preexisting);
|
|
9491
|
+
this.alignNewCellDrawings(preexisting);
|
|
9457
9492
|
this.syncCellPresentation();
|
|
9458
9493
|
this.refreshCellControls();
|
|
9459
9494
|
this.topbar.setLayout(next.id);
|
|
@@ -9870,6 +9905,7 @@ var VelaWorkspace = class {
|
|
|
9870
9905
|
const chart = cell.chart;
|
|
9871
9906
|
chart.on("indicator:error", ({ error }) => this.toastHost.show(`[${cell.id}] ${error.message}`, "error", 5e3));
|
|
9872
9907
|
chart.on("script:run", (run) => this.events.emit("script:run", { ...run, cell: cell.id }));
|
|
9908
|
+
chart.on("priceStyle:change", ({ from, to }) => this.events.emit("cell:priceStyle", { id: cell.id, from, to }));
|
|
9873
9909
|
chart.on("alert", (alert) => {
|
|
9874
9910
|
const source = [parseSymbol(cell.symbol).ticker || cell.symbol, timeframeLabel(cell.timeframe), alert.indicator].filter(Boolean).join(" ");
|
|
9875
9911
|
this.alerts.unshift({ cellId: cell.id, source, title: alert.title ?? "Alert", message: alert.message, time: alert.time });
|
|
@@ -9987,12 +10023,66 @@ var VelaWorkspace = class {
|
|
|
9987
10023
|
}
|
|
9988
10024
|
}
|
|
9989
10025
|
/**
|
|
9990
|
-
*
|
|
9991
|
-
*
|
|
9992
|
-
*
|
|
9993
|
-
*
|
|
9994
|
-
* in
|
|
9995
|
-
*
|
|
10026
|
+
* Bring cells minted by a layout change into their drawings group: with the link
|
|
10027
|
+
* on, a NEW cell (fresh slot, or one returning from the pool that missed edits
|
|
10028
|
+
* while dormant) receives the drawings of a pre-existing group peer — the active
|
|
10029
|
+
* cell when it is one. A drawing the arriving cell already holds a linked copy of
|
|
10030
|
+
* is refreshed in place; any other is copied and linked like a freshly synced
|
|
10031
|
+
* drawing, so later edits and removals follow both ways. The arrival is the cell's
|
|
10032
|
+
* starting state, not an edit: it stays out of the cell's undo timeline, and the
|
|
10033
|
+
* busy guard keeps the copies' own events from fanning back out.
|
|
10034
|
+
*/
|
|
10035
|
+
alignNewCellDrawings(preexisting) {
|
|
10036
|
+
const setting = this.syncOpts.drawings;
|
|
10037
|
+
if (!setting) return;
|
|
10038
|
+
const ids = [...this.cellsById.keys()];
|
|
10039
|
+
for (const id of ids) {
|
|
10040
|
+
if (preexisting.has(id)) continue;
|
|
10041
|
+
const cell = this.cellsById.get(id);
|
|
10042
|
+
if (!cell?.chart.drawings.supported) continue;
|
|
10043
|
+
const peers = syncTargets(id, setting, ids).filter((p) => preexisting.has(p));
|
|
10044
|
+
if (peers.length === 0) continue;
|
|
10045
|
+
const sourceId = this.activeId && peers.includes(this.activeId) ? this.activeId : peers[0];
|
|
10046
|
+
const source = this.cellsById.get(sourceId);
|
|
10047
|
+
if (!source) continue;
|
|
10048
|
+
const drawings = cell.chart.drawings;
|
|
10049
|
+
this.drawingSyncBusy = true;
|
|
10050
|
+
try {
|
|
10051
|
+
cell.history.silently(() => {
|
|
10052
|
+
const held = new Set(drawings.all().map((d) => d.id));
|
|
10053
|
+
for (const doc of source.chart.drawings.all()) {
|
|
10054
|
+
const group = this.drawingLinks.get(`${sourceId}\0${doc.id}`) ?? /* @__PURE__ */ new Map([[sourceId, doc.id]]);
|
|
10055
|
+
const peerId = group.get(id);
|
|
10056
|
+
if (peerId != null && held.has(peerId)) {
|
|
10057
|
+
drawings.update(peerId, { anchors: doc.anchors, style: doc.style, text: doc.text, props: doc.props });
|
|
10058
|
+
continue;
|
|
10059
|
+
}
|
|
10060
|
+
const copy = drawings.add(doc.type, {
|
|
10061
|
+
paneId: doc.paneId,
|
|
10062
|
+
anchors: doc.anchors,
|
|
10063
|
+
style: doc.style,
|
|
10064
|
+
text: doc.text,
|
|
10065
|
+
props: doc.props,
|
|
10066
|
+
zIndex: doc.zIndex
|
|
10067
|
+
});
|
|
10068
|
+
if (!copy) continue;
|
|
10069
|
+
if (peerId != null) this.drawingLinks.delete(`${id}\0${peerId}`);
|
|
10070
|
+
group.set(id, copy.id);
|
|
10071
|
+
for (const [cellId, dId] of group) this.drawingLinks.set(`${cellId}\0${dId}`, group);
|
|
10072
|
+
}
|
|
10073
|
+
});
|
|
10074
|
+
} finally {
|
|
10075
|
+
this.drawingSyncBusy = false;
|
|
10076
|
+
}
|
|
10077
|
+
}
|
|
10078
|
+
}
|
|
10079
|
+
/**
|
|
10080
|
+
* Mirror an origin cell's presentation — the style-link slice of its renderer
|
|
10081
|
+
* config ({@link styleConfigPatch}) plus its Status line and watermark prefs —
|
|
10082
|
+
* onto its same-group followers (the style link). Loop-safe two ways: the busy
|
|
10083
|
+
* guard eats the followers' SYNCHRONOUS echoes (their `applyConfig` re-fires
|
|
10084
|
+
* `onConfigChanged` in the same tick), and the equality short-circuits leave
|
|
10085
|
+
* already-converged followers untouched, so nothing re-emits once the group agrees.
|
|
9996
10086
|
*/
|
|
9997
10087
|
propagateStylePrefs(originId) {
|
|
9998
10088
|
if (this.styleSyncBusy || this.destroyed) return;
|
|
@@ -10000,17 +10090,15 @@ var VelaWorkspace = class {
|
|
|
10000
10090
|
if (targets.length === 0) return;
|
|
10001
10091
|
const origin = this.cellsById.get(originId);
|
|
10002
10092
|
if (!origin) return;
|
|
10003
|
-
const
|
|
10004
|
-
const sliceJson = slice ? JSON.stringify(slice) : null;
|
|
10093
|
+
const config = origin.chart.renderer.getConfig();
|
|
10005
10094
|
const prefs = origin.statusPrefs();
|
|
10006
10095
|
this.styleSyncBusy = true;
|
|
10007
10096
|
try {
|
|
10008
10097
|
for (const id of targets) {
|
|
10009
10098
|
const cell = this.cellsById.get(id);
|
|
10010
10099
|
if (!cell) continue;
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
}
|
|
10100
|
+
const patch = styleConfigPatch(config, cell.chart.renderer.getConfig());
|
|
10101
|
+
if (patch) cell.chart.renderer.applyConfig(patch);
|
|
10014
10102
|
cell.applyStatusPrefs(prefs);
|
|
10015
10103
|
}
|
|
10016
10104
|
} finally {
|
|
@@ -10331,7 +10419,8 @@ var VelaWorkspace = class {
|
|
|
10331
10419
|
onToggleSync: (id) => {
|
|
10332
10420
|
const kind = id;
|
|
10333
10421
|
this.sync.set(kind, this.syncOpts[kind] ? false : true);
|
|
10334
|
-
}
|
|
10422
|
+
},
|
|
10423
|
+
glyph: () => layoutGlyph(this.def)
|
|
10335
10424
|
},
|
|
10336
10425
|
onOpenChange: (open) => this.trackDialog(open)
|
|
10337
10426
|
}));
|