@luxalgo/vela 0.7.2 → 0.7.4

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.
Files changed (37) hide show
  1. package/dist/{DataProvider-BALR0qPq.d.ts → DataProvider-CVpN5sCq.d.ts} +1 -1
  2. package/dist/{DataProvider-D5uMiJYz.d.cts → DataProvider-RF1axuy1.d.cts} +1 -1
  3. package/dist/{chunk-QBWLINWL.js → chunk-CSFNKXUW.js} +1 -1
  4. package/dist/{chunk-PTNO3YK2.js → chunk-DUURH3RN.js} +51 -10
  5. package/dist/{contributions-BbhbZd3c.d.ts → contributions-CspPrMAJ.d.ts} +2 -2
  6. package/dist/{contributions-CcBFe-91.d.cts → contributions-DpZeu7KP.d.cts} +2 -2
  7. package/dist/index.cjs +51 -10
  8. package/dist/index.d.cts +22 -11
  9. package/dist/index.d.ts +22 -11
  10. package/dist/index.js +1 -1
  11. package/dist/{options-C7b_Qssu.d.cts → options-XVpfr9HV.d.cts} +2 -1
  12. package/dist/{options-C7b_Qssu.d.ts → options-XVpfr9HV.d.ts} +2 -1
  13. package/dist/{plugin-Cnix5ZBh.d.ts → plugin-BoLOkblF.d.ts} +3 -3
  14. package/dist/{plugin-D6MlX4--.d.cts → plugin-D07HD2GL.d.cts} +3 -3
  15. package/dist/plugin.d.cts +4 -4
  16. package/dist/plugin.d.ts +4 -4
  17. package/dist/providers/binance.d.cts +2 -2
  18. package/dist/providers/binance.d.ts +2 -2
  19. package/dist/providers/coinbase.d.cts +2 -2
  20. package/dist/providers/coinbase.d.ts +2 -2
  21. package/dist/providers/hyperliquid.d.cts +2 -2
  22. package/dist/providers/hyperliquid.d.ts +2 -2
  23. package/dist/{statusline-model-DUKt7_TQ.d.cts → statusline-model-Bd4qKuD6.d.cts} +3 -3
  24. package/dist/{statusline-model-D8NL7o4L.d.ts → statusline-model-CPa_hmhd.d.ts} +3 -3
  25. package/dist/ui.d.cts +1 -1
  26. package/dist/ui.d.ts +1 -1
  27. package/dist/vela.global.js +51 -10
  28. package/dist/vela.global.min.js +14 -14
  29. package/dist/widget.cjs +51 -10
  30. package/dist/widget.d.cts +6 -6
  31. package/dist/widget.d.ts +6 -6
  32. package/dist/widget.js +3 -3
  33. package/dist/workspace.cjs +51 -10
  34. package/dist/workspace.d.cts +5 -5
  35. package/dist/workspace.d.ts +5 -5
  36. package/dist/workspace.js +2 -2
  37. package/package.json +1 -1
package/dist/widget.cjs CHANGED
@@ -27726,6 +27726,32 @@ function clusterMarks(marks, barTimes, intervalMs2, hidden) {
27726
27726
  }
27727
27727
  return out;
27728
27728
  }
27729
+ function foldOverlappingClusters(clusters, xOf, bucketPx = MARK_CLUSTER_PX) {
27730
+ const byGroup = /* @__PURE__ */ new Map();
27731
+ for (const c of clusters) {
27732
+ const list = byGroup.get(c.group);
27733
+ if (list) list.push(c);
27734
+ else byGroup.set(c.group, [c]);
27735
+ }
27736
+ const out = [];
27737
+ for (const list of byGroup.values()) {
27738
+ list.sort((a, b) => a.bar - b.bar);
27739
+ const runs = [];
27740
+ let anchorX = Number.NaN;
27741
+ for (const c of list) {
27742
+ const x = xOf(c.bar);
27743
+ const run = runs[runs.length - 1];
27744
+ if (run && Number.isFinite(x) && Number.isFinite(anchorX) && x - anchorX < bucketPx) {
27745
+ run.marks.push(...c.marks);
27746
+ } else {
27747
+ runs.push({ key: c.key, bar: c.bar, group: c.group, marks: [...c.marks] });
27748
+ anchorX = x;
27749
+ }
27750
+ }
27751
+ out.push(...runs);
27752
+ }
27753
+ return out;
27754
+ }
27729
27755
  function groupRank(groups, clusters) {
27730
27756
  const rank = /* @__PURE__ */ new Map();
27731
27757
  groups.forEach((g, i) => rank.set(g.id, i));
@@ -27735,7 +27761,7 @@ function groupRank(groups, clusters) {
27735
27761
  return (group) => group === void 0 ? Number.MAX_SAFE_INTEGER : rank.get(group) ?? Number.MAX_SAFE_INTEGER - 1;
27736
27762
  }
27737
27763
  function layoutMarkLane(input) {
27738
- const clusters = clusterMarks(input.marks, input.barTimes, input.intervalMs, input.hidden);
27764
+ const clusters = foldOverlappingClusters(clusterMarks(input.marks, input.barTimes, input.intervalMs, input.hidden), input.xOf);
27739
27765
  const rankOf = groupRank(input.groups, clusters);
27740
27766
  const byBar = /* @__PURE__ */ new Map();
27741
27767
  for (const c of clusters) {
@@ -38379,7 +38405,7 @@ var NativeRenderer = class {
38379
38405
  for (const l of this.extLayers) {
38380
38406
  if (!l.def.repaintOnCursor) continue;
38381
38407
  const lp = this.layerPane(l) ?? pane;
38382
- if (lp.collapsed) continue;
38408
+ if (lp.collapsed || this.layerHiddenWithCandles(l)) continue;
38383
38409
  l.instance.render(this.extLayerArgs(l, lp.scale, lp.bounds, nowMs));
38384
38410
  if (this.animZoom.on && l.instance.animating?.()) this.animator.start();
38385
38411
  }
@@ -38441,7 +38467,7 @@ var NativeRenderer = class {
38441
38467
  let folded = null;
38442
38468
  for (const l of this.extLayers) {
38443
38469
  const lp = this.layerPane(l) ?? pane;
38444
- if (lp.collapsed) {
38470
+ if (lp.collapsed || this.layerHiddenWithCandles(l)) {
38445
38471
  this.clearLayerCanvas(l.canvas);
38446
38472
  continue;
38447
38473
  }
@@ -38609,7 +38635,7 @@ var NativeRenderer = class {
38609
38635
  const or = overlaySeriesRange(this.scene.indicators.values(), i0, i1, (id) => this.scene.offsetOf(id));
38610
38636
  if (or) dr = dr ? { min: Math.min(dr.min, or.min), max: Math.max(dr.max, or.max) } : or;
38611
38637
  }
38612
- const includeCandles = pane.kind === "price" && (!this.scene.candlesHidden || this.priceLayersAnchoredToBars(masterModels));
38638
+ const includeCandles = pane.kind === "price" && (!this.scene.candlesHidden || this.priceLayersAnchoredToBars(masterModels) || !this.paneHasMeasurableContent(masterModels, dr));
38613
38639
  pane.scaleTarget = computePaneScale(masterModels, this.bars, includeCandles, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id));
38614
38640
  pane.percentBaseline = pane.kind === "price" ? this.bars[i0]?.close ?? 0 : this.firstVisibleValue(masterModels, i0);
38615
38641
  pane.axisFormat = void 0;
@@ -38841,16 +38867,31 @@ var NativeRenderer = class {
38841
38867
  );
38842
38868
  }
38843
38869
  /**
38844
- * True when SDK-layer content on the price pane paints at BAR PRICES without
38845
- * contributing a series: the active chart type's own layer, or an overlay layer native
38846
- * (a series-less model whose type names a mounted layer). Hiding the candles must then
38847
- * keep the bars in the price scale with nothing else on the pane the scale would fall
38848
- * to the {0,1} placeholder and every such layer would paint off-screen and vanish.
38870
+ * True for the layer painting the ACTIVE chart type (the base entry whose id is the
38871
+ * current price style) while the price series is hidden. The chart type IS the price
38872
+ * series, so "hide chart" blanks its layer along with the bars; an indicator's layer
38873
+ * (an overlay layer native, on any pane) is independent content and keeps painting.
38874
+ */
38875
+ layerHiddenWithCandles(l) {
38876
+ return this.scene.candlesHidden && l.owner === null && l.def.id === this.scene.priceStyle;
38877
+ }
38878
+ /**
38879
+ * True when an overlay layer native (a series-less model whose type names a mounted
38880
+ * layer) sits on the price pane: it paints at BAR PRICES without contributing a series,
38881
+ * so hiding the candles must keep the bars in the price scale — with nothing else on the
38882
+ * pane the scale would fall to the {0,1} placeholder and the layer would paint off-screen
38883
+ * and vanish. The chart type's own layer does not count: it is blanked with the candles.
38849
38884
  */
38850
38885
  priceLayersAnchoredToBars(masterModels) {
38851
- if (this.extLayers.some((l) => l.owner === null && l.def.id === this.scene.priceStyle)) return true;
38852
38886
  return masterModels.some((m) => m.series.length === 0 && !!m.native && this.extLayers.some((l) => l.def.id === m.native.type));
38853
38887
  }
38888
+ /** True when the pane's master content contributes SOMETHING to its autoscale besides
38889
+ * the candles: a series painted on the pane (force_overlay ones scale elsewhere), a
38890
+ * price line, or a measured drawings range. Mirrors what `computePaneScale` considers. */
38891
+ paneHasMeasurableContent(masterModels, drawings) {
38892
+ if (drawings) return true;
38893
+ return masterModels.some((m) => m.priceLines.length > 0 || m.series.some((s) => s.overlay !== true));
38894
+ }
38854
38895
  /** Per-pane scale state for a host UI (e.g. a price-axis context menu): the pane's pixel
38855
38896
  * band (`top`/`height`, so a click y maps to a pane) plus its current axis `mode`/`log`.
38856
38897
  * Top-to-bottom order. Every pane is independent — the price pane from the scene setting,
package/dist/widget.d.cts CHANGED
@@ -1,10 +1,10 @@
1
- import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-CcBFe-91.cjs';
2
- export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-CcBFe-91.cjs';
3
- import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-C7b_Qssu.cjs';
4
- import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-DUKt7_TQ.cjs';
5
- export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-DUKt7_TQ.cjs';
1
+ import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-DpZeu7KP.cjs';
2
+ export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-DpZeu7KP.cjs';
3
+ import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-XVpfr9HV.cjs';
4
+ import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-Bd4qKuD6.cjs';
5
+ export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-Bd4qKuD6.cjs';
6
6
  import { K as KeymapManager } from './keymap-CGOz5F5f.cjs';
7
- import { a as SymbolDescriptor } from './DataProvider-D5uMiJYz.cjs';
7
+ import { a as SymbolDescriptor } from './DataProvider-RF1axuy1.cjs';
8
8
  import { d as SidePanel } from './side-panel-HF0IAzwf.cjs';
9
9
  export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-HF0IAzwf.cjs';
10
10
 
package/dist/widget.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-BbhbZd3c.js';
2
- export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-BbhbZd3c.js';
3
- import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-C7b_Qssu.js';
4
- import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-D8NL7o4L.js';
5
- export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-D8NL7o4L.js';
1
+ import { V as Vela, W as WidgetContext, K as SidePanelButton } from './contributions-CspPrMAJ.js';
2
+ export { C as CellStateContext, aA as DEFAULT_PANEL_ORDER, E as ExternalIndicatorEntry, O as OVERRIDABLE_TOPBAR_IDS, Q as SidePanelDescriptor, T as SidePanelHandle, X as StatePersistenceHandler, $ as SymbolRankingHook, a4 as WidgetActionDescriptor, a5 as WidgetActionTarget, a6 as WidgetAttachment, ag as registerSidePanel, ah as registerStatePersistence, ai as registerSymbolRanking, aj as registerWidgetAction, ak as registerWidgetAttachment, am as sidePanels, an as statePersistenceHandlers, ao as symbolRanking, ap as topbarActionOverride, au as unregisterSidePanel, av as unregisterStatePersistence, aw as unregisterWidgetAction, ax as unregisterWidgetAttachment, ay as widgetActions, az as widgetAttachments } from './contributions-CspPrMAJ.js';
3
+ import { b as VelaOptions, d as MarketSession, T as ThemeName, c as VelaTheme, v as DataWindowReadout } from './options-XVpfr9HV.js';
4
+ import { c as VelaShellOptions, W as WidgetHistory, b as RangePreset, f as WorkspaceState, j as TopbarComposition, a as StatuslinePart, P as PanelsState } from './statusline-model-CPa_hmhd.js';
5
+ export { B as Bottombar, k as BottombarOptions, C as CellState, g as ChartState, I as IndicatorLoader, l as IndicatorManifest, m as IndicatorManifestEntry, n as RANGE_PRESETS, R as ResolvedIndicator, o as ResolvedTopbarComposition, p as TOPBAR_BUILTIN_IDS, q as TOPBAR_DEFAULT_LEFT, r as TOPBAR_DEFAULT_RIGHT, V as VelaStorage, t as WidgetStorage, h as decodeState, i as encodeState, u as localStorageAdapter, v as pinnedTopbarActionIds, w as resolveIndicators, x as resolveTopbarComposition, s as sanitizeState, y as topbarHas } from './statusline-model-CPa_hmhd.js';
6
6
  import { K as KeymapManager } from './keymap-CGOz5F5f.js';
7
- import { a as SymbolDescriptor } from './DataProvider-BALR0qPq.js';
7
+ import { a as SymbolDescriptor } from './DataProvider-CVpN5sCq.js';
8
8
  import { d as SidePanel } from './side-panel-HF0IAzwf.js';
9
9
  export { D as DEFAULT_PANEL_MAX_WIDTH, a as DEFAULT_PANEL_MIN_WIDTH, b as DEFAULT_PANEL_WIDTH, S as SidePanelOptions, c as clampPanelWidth } from './side-panel-HF0IAzwf.js';
10
10
 
package/dist/widget.js CHANGED
@@ -1,6 +1,6 @@
1
- import { VelaWorkspace } from './chunk-QBWLINWL.js';
2
- export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-QBWLINWL.js';
3
- export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-PTNO3YK2.js';
1
+ import { VelaWorkspace } from './chunk-CSFNKXUW.js';
2
+ export { Bottombar, ChartContextMenu, DataWindow, IndicatorPicker, ObjectTree, PanelDock, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeQuick, Topbar, Watermark, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, localStorageAdapter, parseTimeframe, priceStyleLabel, resolveIndicators, sanitizeState, timeframeLabel, timeframeMs } from './chunk-CSFNKXUW.js';
3
+ export { TIMEZONES, normalizeTimezone, tzButtonLabel, tzMenuLabel, tzOffset } from './chunk-DUURH3RN.js';
4
4
  export { DEFAULT_PANEL_MAX_WIDTH, DEFAULT_PANEL_MIN_WIDTH, DEFAULT_PANEL_ORDER, DEFAULT_PANEL_WIDTH, OVERRIDABLE_TOPBAR_IDS, SidePanel, TOPBAR_BUILTIN_IDS, TOPBAR_DEFAULT_LEFT, TOPBAR_DEFAULT_RIGHT, clampPanelWidth, pinnedTopbarActionIds, registerSidePanel, registerStatePersistence, registerSymbolRanking, registerWidgetAction, registerWidgetAttachment, resolveTopbarComposition, sidePanels, statePersistenceHandlers, symbolRanking, topbarActionOverride, topbarHas, unregisterSidePanel, unregisterStatePersistence, unregisterWidgetAction, unregisterWidgetAttachment, widgetActions, widgetAttachments } from './chunk-BFA32GOU.js';
5
5
  import './chunk-ZADTVRUO.js';
6
6
  import './chunk-BKHSQ4YM.js';
@@ -27658,6 +27658,32 @@ function clusterMarks(marks, barTimes, intervalMs2, hidden) {
27658
27658
  }
27659
27659
  return out;
27660
27660
  }
27661
+ function foldOverlappingClusters(clusters, xOf, bucketPx = MARK_CLUSTER_PX) {
27662
+ const byGroup = /* @__PURE__ */ new Map();
27663
+ for (const c of clusters) {
27664
+ const list = byGroup.get(c.group);
27665
+ if (list) list.push(c);
27666
+ else byGroup.set(c.group, [c]);
27667
+ }
27668
+ const out = [];
27669
+ for (const list of byGroup.values()) {
27670
+ list.sort((a, b) => a.bar - b.bar);
27671
+ const runs = [];
27672
+ let anchorX = Number.NaN;
27673
+ for (const c of list) {
27674
+ const x = xOf(c.bar);
27675
+ const run = runs[runs.length - 1];
27676
+ if (run && Number.isFinite(x) && Number.isFinite(anchorX) && x - anchorX < bucketPx) {
27677
+ run.marks.push(...c.marks);
27678
+ } else {
27679
+ runs.push({ key: c.key, bar: c.bar, group: c.group, marks: [...c.marks] });
27680
+ anchorX = x;
27681
+ }
27682
+ }
27683
+ out.push(...runs);
27684
+ }
27685
+ return out;
27686
+ }
27661
27687
  function groupRank(groups, clusters) {
27662
27688
  const rank = /* @__PURE__ */ new Map();
27663
27689
  groups.forEach((g, i) => rank.set(g.id, i));
@@ -27667,7 +27693,7 @@ function groupRank(groups, clusters) {
27667
27693
  return (group) => group === void 0 ? Number.MAX_SAFE_INTEGER : rank.get(group) ?? Number.MAX_SAFE_INTEGER - 1;
27668
27694
  }
27669
27695
  function layoutMarkLane(input) {
27670
- const clusters = clusterMarks(input.marks, input.barTimes, input.intervalMs, input.hidden);
27696
+ const clusters = foldOverlappingClusters(clusterMarks(input.marks, input.barTimes, input.intervalMs, input.hidden), input.xOf);
27671
27697
  const rankOf = groupRank(input.groups, clusters);
27672
27698
  const byBar = /* @__PURE__ */ new Map();
27673
27699
  for (const c of clusters) {
@@ -38311,7 +38337,7 @@ var NativeRenderer = class {
38311
38337
  for (const l of this.extLayers) {
38312
38338
  if (!l.def.repaintOnCursor) continue;
38313
38339
  const lp = this.layerPane(l) ?? pane;
38314
- if (lp.collapsed) continue;
38340
+ if (lp.collapsed || this.layerHiddenWithCandles(l)) continue;
38315
38341
  l.instance.render(this.extLayerArgs(l, lp.scale, lp.bounds, nowMs));
38316
38342
  if (this.animZoom.on && l.instance.animating?.()) this.animator.start();
38317
38343
  }
@@ -38373,7 +38399,7 @@ var NativeRenderer = class {
38373
38399
  let folded = null;
38374
38400
  for (const l of this.extLayers) {
38375
38401
  const lp = this.layerPane(l) ?? pane;
38376
- if (lp.collapsed) {
38402
+ if (lp.collapsed || this.layerHiddenWithCandles(l)) {
38377
38403
  this.clearLayerCanvas(l.canvas);
38378
38404
  continue;
38379
38405
  }
@@ -38541,7 +38567,7 @@ var NativeRenderer = class {
38541
38567
  const or = overlaySeriesRange(this.scene.indicators.values(), i0, i1, (id) => this.scene.offsetOf(id));
38542
38568
  if (or) dr = dr ? { min: Math.min(dr.min, or.min), max: Math.max(dr.max, or.max) } : or;
38543
38569
  }
38544
- const includeCandles = pane.kind === "price" && (!this.scene.candlesHidden || this.priceLayersAnchoredToBars(masterModels));
38570
+ const includeCandles = pane.kind === "price" && (!this.scene.candlesHidden || this.priceLayersAnchoredToBars(masterModels) || !this.paneHasMeasurableContent(masterModels, dr));
38545
38571
  pane.scaleTarget = computePaneScale(masterModels, this.bars, includeCandles, i0, i1, dr, paneLogScale(this.scene, pane), (id) => this.scene.offsetOf(id));
38546
38572
  pane.percentBaseline = pane.kind === "price" ? this.bars[i0]?.close ?? 0 : this.firstVisibleValue(masterModels, i0);
38547
38573
  pane.axisFormat = void 0;
@@ -38773,16 +38799,31 @@ var NativeRenderer = class {
38773
38799
  );
38774
38800
  }
38775
38801
  /**
38776
- * True when SDK-layer content on the price pane paints at BAR PRICES without
38777
- * contributing a series: the active chart type's own layer, or an overlay layer native
38778
- * (a series-less model whose type names a mounted layer). Hiding the candles must then
38779
- * keep the bars in the price scale with nothing else on the pane the scale would fall
38780
- * to the {0,1} placeholder and every such layer would paint off-screen and vanish.
38802
+ * True for the layer painting the ACTIVE chart type (the base entry whose id is the
38803
+ * current price style) while the price series is hidden. The chart type IS the price
38804
+ * series, so "hide chart" blanks its layer along with the bars; an indicator's layer
38805
+ * (an overlay layer native, on any pane) is independent content and keeps painting.
38806
+ */
38807
+ layerHiddenWithCandles(l) {
38808
+ return this.scene.candlesHidden && l.owner === null && l.def.id === this.scene.priceStyle;
38809
+ }
38810
+ /**
38811
+ * True when an overlay layer native (a series-less model whose type names a mounted
38812
+ * layer) sits on the price pane: it paints at BAR PRICES without contributing a series,
38813
+ * so hiding the candles must keep the bars in the price scale — with nothing else on the
38814
+ * pane the scale would fall to the {0,1} placeholder and the layer would paint off-screen
38815
+ * and vanish. The chart type's own layer does not count: it is blanked with the candles.
38781
38816
  */
38782
38817
  priceLayersAnchoredToBars(masterModels) {
38783
- if (this.extLayers.some((l) => l.owner === null && l.def.id === this.scene.priceStyle)) return true;
38784
38818
  return masterModels.some((m) => m.series.length === 0 && !!m.native && this.extLayers.some((l) => l.def.id === m.native.type));
38785
38819
  }
38820
+ /** True when the pane's master content contributes SOMETHING to its autoscale besides
38821
+ * the candles: a series painted on the pane (force_overlay ones scale elsewhere), a
38822
+ * price line, or a measured drawings range. Mirrors what `computePaneScale` considers. */
38823
+ paneHasMeasurableContent(masterModels, drawings) {
38824
+ if (drawings) return true;
38825
+ return masterModels.some((m) => m.priceLines.length > 0 || m.series.some((s) => s.overlay !== true));
38826
+ }
38786
38827
  /** Per-pane scale state for a host UI (e.g. a price-axis context menu): the pane's pixel
38787
38828
  * band (`top`/`height`, so a click y maps to a pane) plus its current axis `mode`/`log`.
38788
38829
  * Top-to-bottom order. Every pane is independent — the price pane from the scene setting,
@@ -1,9 +1,9 @@
1
- import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-C7b_Qssu.cjs';
2
- import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-DUKt7_TQ.cjs';
3
- export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-DUKt7_TQ.cjs';
1
+ import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-XVpfr9HV.cjs';
2
+ import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-Bd4qKuD6.cjs';
3
+ export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-Bd4qKuD6.cjs';
4
4
  import { K as KeymapManager } from './keymap-CGOz5F5f.cjs';
5
- import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-CcBFe-91.cjs';
6
- import { M as MarketDataFeed } from './DataProvider-D5uMiJYz.cjs';
5
+ import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-DpZeu7KP.cjs';
6
+ import { M as MarketDataFeed } from './DataProvider-RF1axuy1.cjs';
7
7
 
8
8
  /** The cells that follow `originId` under `setting` — PURE (never includes the origin). */
9
9
  declare function syncTargets(originId: string, setting: SyncSetting | undefined, cellIds: readonly string[]): string[];
@@ -1,9 +1,9 @@
1
- import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-C7b_Qssu.js';
2
- import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-D8NL7o4L.js';
3
- export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-D8NL7o4L.js';
1
+ import { O as OHLCV, V as VisibleRangePreset, a as VisibleRange, b as VelaOptions, I as InputValue, c as VelaTheme, N as NativeBackend, d as MarketSession } from './options-XVpfr9HV.js';
2
+ import { S as SyncSetting, V as VelaStorage, C as CellState, W as WidgetHistory, R as ResolvedIndicator, a as StatuslinePart, b as RangePreset, T as TrackSizes, c as VelaShellOptions, d as SyncOptions, e as SyncKind, f as WorkspaceState } from './statusline-model-CPa_hmhd.js';
3
+ export { g as ChartState, P as PanelsState, h as decodeState, i as encodeState, s as sanitizeState } from './statusline-model-CPa_hmhd.js';
4
4
  import { K as KeymapManager } from './keymap-CGOz5F5f.js';
5
- import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-BbhbZd3c.js';
6
- import { M as MarketDataFeed } from './DataProvider-BALR0qPq.js';
5
+ import { I as IndicatorHandle, S as ScriptingEngine, W as WidgetContext, V as Vela, E as ExternalIndicatorEntry, a as ScriptRun } from './contributions-CspPrMAJ.js';
6
+ import { M as MarketDataFeed } from './DataProvider-CVpN5sCq.js';
7
7
 
8
8
  /** The cells that follow `originId` under `setting` — PURE (never includes the origin). */
9
9
  declare function syncTargets(originId: string, setting: SyncSetting | undefined, cellIds: readonly string[]): string[];
package/dist/workspace.js CHANGED
@@ -1,5 +1,5 @@
1
- export { ChartCell, GRID_PICKER_MAX, VelaWorkspace, activeAfterLayout, decodeState, encodeState, ensureLayout, evenTracks, gridStyles, layoutDefinition, layoutForGrid, layoutShape, layouts, memoryStorageAdapter, rangesWithin, registerBuiltinLayouts, registerLayout, resizeTracks, sanitizeState, syncTargets, trackOffsets, unregisterLayout } from './chunk-QBWLINWL.js';
2
- import './chunk-PTNO3YK2.js';
1
+ export { ChartCell, GRID_PICKER_MAX, VelaWorkspace, activeAfterLayout, decodeState, encodeState, ensureLayout, evenTracks, gridStyles, layoutDefinition, layoutForGrid, layoutShape, layouts, memoryStorageAdapter, rangesWithin, registerBuiltinLayouts, registerLayout, resizeTracks, sanitizeState, syncTargets, trackOffsets, unregisterLayout } from './chunk-CSFNKXUW.js';
2
+ import './chunk-DUURH3RN.js';
3
3
  import './chunk-BFA32GOU.js';
4
4
  import './chunk-ZADTVRUO.js';
5
5
  import './chunk-BKHSQ4YM.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luxalgo/vela",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "Open-source charting library with a native high-performance renderer, drawing tools, pluggable chart types and pluggable scripting engines.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://luxalgo.com/vela",