Untitled
Anonymous
plain_text
10/03/2026 12:47 PM
14.1 KB
1
Indexable
D:\Vela_TradingCharts\Vela>type playground\workspace.ts
// The workspace playground page: a 4-cell VelaWorkspace on live Binance data with the
// page's demo scripting engine and the full shared chrome ΓÇö topbar (symbol / timeframe /
// style / LAYOUT dropdowns, indicator picker, alerts, screenshot, object tree, settings),
// bottombar (range chips, clock, timezone), one keymap. Served straight from src/ (HMR).
//
// Vela ships no scripting engine ΓÇö `demo-engine.ts` is the page's own, written against
// the public port (see widget.ts's header). For Pine Script:
// `npm i @luxalgo/vela-pinets pinets` and `engines: { pine: () => new PineWorkerEngine() }`.
import type { Vela } from "../src";
import { VelaWorkspace } from "../src/workspace";
import { BinanceProvider } from "../src/data/providers/binance";
import { IBKRProvider } from "../src/data/providers/ibkr";
import { DemoEngine } from "./demo-engine";
import { playgroundStorage } from "./persistence";
import { addSampleMarks } from "./marks";
const ws = new VelaWorkspace("#workspace", {
layout: "4",
// The unified vocabulary: top-level chart options are every cell's DEFAULT,
// `cells` overrides per cell. A cell's NAME is its durable identity (persistence,
// sync groups, ws.cell(name)) ΓÇö DECLARATION ORDER fills the layout's slots, and
// any entry is optional (an undeclared slot boots on the defaults above).
symbol: "BTCUSDT", // bare = first declared provider; 'coinbase:BTC-USD' pins a venue
timeframe: "60",
cells: {
btc: { symbol: "BTCUSDT", timeframe: "60" },
eth: { symbol: "ETHUSDT", timeframe: "15" },
sol: { symbol: "SOLUSDT", timeframe: "240" },
bnb: { symbol: "BNBUSDT", timeframe: "D" },
},
providers: {
binance: () => new BinanceProvider(),
ibkr: () => new IBKRProvider(),
},
engines: { demo: () => new DemoEngine() }, // ONE instance per cell (a worker engine would get a thread each)
defaultLanguage: "demo", // scripts added without a `language` run on the engine above
// No script manifest: the indicators dialog lists the built-in catalog only.
live: true,
theme: "dark",
autofocus: true, // the workspace IS the page ΓÇö shortcuts work from the first keystroke
// The playground's CUSTOM persistence (shared with the widget page): the whole
// workspace document ΓÇö layout, sync, timezone, and per cell the market, renderer
// config, DRAWINGS and indicators ΓÇö survives a reload via localStorage.
persist: true, // key 'vela-workspace' → 'vela-play:vela-workspace' in devtools
storage: playgroundStorage(),
settings: { hidden: ["advanced"] },
// ΓöÇΓöÇ The rest of the CHART options (every cell's DEFAULT), at their defaults ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
// bars: 500, // history depth per cell
// data: myBars, // offline OHLCV[] for every cell ΓÇö a `cells` entry can override
// visibleRange: '3M', // initial window per cell: '1D'…'5Y', 'YTD', 'ALL' or {from,to} ms
// priceStyle: 'candles', // default style of every cell ΓÇö a `cells` entry can override
// volume: true, // the built-in volume columns, per cell; false opts out
// logScale: false, // logarithmic price scale, per cell
// currentPriceLine: true, // dashed line + axis chip at the latest price, per cell
// upColor: '#089981', // bullish candles (default: the palette's bullish green)
// downColor: '#f23645', // bearish candles (default: the palette's bearish red)
// glow: 0, // neon glow on line series, 0..~0.6 ΓÇö WebGL2 cells only
// animations: { zoom: true, pan: true, liveBar: false }, // eased zoom + inertial pan + forming-bar glide (true = 90 ms, or a duration in ms); false disables all
// nativeBackend: 'auto', // explicit 'canvas2d'/'webgl2' wins over the maxWebglCells policy
// renderer: NativeRenderer, // a custom IChartRenderer class for every cell
// drawings: true, // per-cell tools config ΓÇö its `toolbar` key is ignored: the grid's
// // ONE shared bar replaces per-cell bars (see drawingToolbar)
// (no `height` here: the grid sizes its cells)
// ΓöÇΓöÇ The rest of the SHELL options, at their defaults ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
// timeframes: ['1', '5', '15', '30', '60', '240', 'D', 'W', 'M'], // topbar timeframe presets
// timezone: 'Etc/UTC', // display timezone (IANA), one zone for every cell
// statusline: true, // chrome: the per-cell status line
// watermark: true, // chrome: the per-cell symbol watermark
// bottombar: true, // chrome: the range-presets + timezone bar
// topbar: { // COMPOSE the topbar: each side lists its VISIBLE
// left: ["symbol", "timeframes", "style", "layout", "indicators", "actions", "undo-redo"],
// right: ["actions", "alerts", "panels", "screenshot"],
// },
// // These values ARE the defaults ΓÇö an undeclared side keeps
// // them, so the option is pure opt-in. Entries render in
// // LIST ORDER; an id you omit disappears WITH its mobile
// // entry and its keyboard chord (mod+alt+S goes with
// // 'screenshot', `/` with 'indicators' ΓÇö Ctrl+Z/Y always
// // stay). 'actions' is the slot where contributed actions
// // flow; naming a contributed action's ID instead pins it
// // at that exact spot (its align/order are then ignored).
// // An explicit list is the side's COMPLETE contract: it
// // also freezes it ΓÇö chrome a future release adds won't
// // appear for a curating host. A plugin can also take a
// // slot over by registering an action under its id
// // ('indicators' | 'screenshot') ΓÇö see the plugin SDK.
// ΓöÇΓöÇ The rest of the WORKSPACE options, at their defaults ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
// sync: { viewport: true, crosshair: true }, // links between cells, per kind ('viewport' |
// // 'symbol' | 'timeframe' | 'crosshair'): true = all cells,
// // or {cellId: group} so only same-group cells follow
// drawingToolbar: true, // the ONE shared drawing toolbar (acts on the active cell)
// maxWebglCells: 8, // above this many cells, every cell renders canvas2d
// // (browser WebGL-context budget; glow unavailable there)
});
// The page shell follows the app theme — flip it from any cell's chart settings →
// Canvas → Theme (or `__ws.setTheme('light')` in the console); every LIVE cell relays
// the change, and cells minted by later layout switches are wired as they appear.
const syncShellTheme = (t: { background: string }): void => {
document.body.style.background = t.background;
};
for (const cell of ws.cells()) cell.chart.on("theme:changed", syncShellTheme);
ws.on("cell:created", ({ id }) =>
ws.cell(id)?.chart.on("theme:changed", syncShellTheme),
);
// Sample timeline marks (chart.marks) on every cell ΓÇö the ones alive now and those a
// later layout switch mints. Each waits for its own chart to paint, then spreads the
// marks over that chart's visible range (see marks.ts).
const seedMarks = (chart: Vela): void => {
void chart.ready().then(() => addSampleMarks(chart));
};
for (const cell of ws.cells()) seedMarks(cell.chart);
ws.on("cell:created", ({ id }) => {
const cell = ws.cell(id);
if (cell) seedMarks(cell.chart);
});
// Handy for poking around from the browser console (and for the automated probes).
(window as unknown as { __ws: VelaWorkspace }).__ws = ws;
// ΓöÇΓöÇ State surface demo (uncomment to try) ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
// The workspace speaks the SAME state triplet and document format as the widget ΓÇö
// multi-cell here. `persist` above writes exactly this document; the calls below
// are how a host composes custom flows (server snapshots, share links, templates).
//
// // READ ΓÇö the WHOLE grid as one versioned document: layout, splitter tracks,
// // active cell, sync links, timezone, favorites, and per cell (live AND dormant)
// // the market, renderer config, user drawings, and indicator ledger.
// const snapshot = ws.getState();
// console.log('[state] workspace document:', snapshot);
//
// // EVENT ΓÇö fires debounced (~500ms) after any persistable change in ANY cell
// // (pan-synced viewports excluded; drawings, markets, layout, prefs included).
// const offState = ws.on('state:changed', () => {
// console.log('[state] changed → active cell:', ws.getState().activeCellId);
// });
//
// // WRITE ΓÇö the whole grid rebuilds from the document (cells diff by IDENTITY ΓÇö the
// // names declared above; a layout id must be registered ΓÇö registerLayout ΓÇö before
// // applying). Untrusted-safe: malformed fields are dropped by the shared codec.
// setTimeout(() => {
// const doc = ws.getState();
// doc.layout = '2h'; // switch the grid…
// const btc = doc.charts.find((c) => c.id === 'btc');
// if (btc) btc.symbol = 'DOGEUSDT'; // …retarget the btc cell…
// doc.sync = { viewport: true }; // …and link every cell's viewport
// ws.applyState(doc);
// offState();
// }, 5000);
//
// // CROSS-SHELL ΓÇö one format: a WIDGET document (layout '1', one `c1` cell)
// // applies here verbatim, and a workspace cell's state restores into a widget.
// // ws.applyState(widget.getState());
D:\Vela_TradingCharts\Vela>Editor is loading...
Leave a Comment