Skip to Content
TutorialsAdvanced Features

Advanced Features

This tutorial covers the SDK capabilities beyond a basic chart and trading setup: multi-chart layouts, the runtime chart API, chart marks, tailoring the UI surface, real-time streaming, and state persistence.

Prerequisites

Multi-Chart Layouts & Sync

The SDK terminal supports up to 4 charts in a single widget. Users switch layouts from the layout chooser in the bottom bar — one chart, two charts (stacked or side-by-side), and all three- and four-chart grid variants.

Below the layout grid, the same menu exposes six SYNC toggles that link the charts together:

ToggleEffect
SYNC CursorsCrosshair position mirrors across all charts
SYNC TimeVisible time range pans/zooms together
SYNC All SymbolsChanging the symbol on one chart changes all
SYNC All IntervalsChanging the interval on one chart changes all
SYNC Chart TypesCandlestick/line/bar type applies to all charts
SYNC DrawingsDrawings replicate across charts

Layout changes are reported to your app — see the Layout Change Events guide for the event payloads if you need to react to them (e.g. resizing surrounding UI).

Runtime Chart API

createChart() returns a handle you can use to drive the chart after creation — no need to recreate it:

const chart = GoChartingSDK.createChart("#chart-container", { symbol: "BYBIT:FUTURE:BTCUSDT", interval: "1D", datafeed: myDatafeed, licenseKey: "your-license-key", }); // Later, from your own UI: await chart.setSymbol("BYBIT:FUTURE:ETHUSDT"); // switch instrument await chart.setInterval("15m"); // switch timeframe await chart.setChartType("Line"); // change series type chart.setTheme("light"); // "light" | "dark"

In multi-chart layouts, the per-chart variants target a specific pane by index:

await chart.setIntervalAtIndex("1h", 1); // second chart only await chart.setChartTypeAtIndex("Area", 2); // third chart only

When you’re done with the chart (for example on a SPA route change), always destroy it so streaming subscriptions and observers are cleaned up:

chart.destroy();

Chart Marks & Timescale Marks

Implement getMarks and/or getTimescaleMarks on your datafeed to render event badges on the chart. getMarks draws labeled dots on the price series (earnings, news, signals); getTimescaleMarks draws markers on the time axis.

const datafeed = { // ...getBars, resolveSymbol, etc. async getMarks(symbolInfo, startDate, endDate, onDataCallback, resolution) { onDataCallback([ { id: 1, time: 1767139200, // unix seconds color: "red", label: "E", // letter inside the badge labelFontColor: "white", minSize: 25, text: ["Earnings Report", "Q3 results", "Beat by 15%"], // tooltip lines }, ]); }, async getTimescaleMarks(symbolInfo, startDate, endDate, onDataCallback, resolution) { onDataCallback([ { id: 1, time: 1767139200, color: "blue", label: "T1", minSize: 30, tooltip: ["Economic Data", "GDP release"], }, ]); }, };

The chart requests marks for the visible range and re-requests as the user scrolls. If your datafeed doesn’t implement these methods, no marks are drawn — they’re fully optional.

Customizing the UI Surface

Embedders rarely want the whole terminal. The exclude option and a few top-level flags let you trim it:

GoChartingSDK.createChart("#chart-container", { // ... exclude: { leftPanel: true, // hide the drawing tools sidebar rightPanel: false, // keep the right icon bar topBar: false, // keep the top bar bottomBar: false, // keep durations/timezone bar // Remove specific indicators from the Study menu by type: indicators: ["VWAP", "SMA", "ONBALANCEVOLUME"], }, disableSearch: true, // no symbol search in the top bar disableCompare: true, // no Compare button showCrosshairPlusIcon: false, // hide the "+" quick-action on the crosshair });

Indicator types in exclude.indicators are the internal type codes (e.g. "SMA", "MACD", "VWAP"), not display names.

Real-Time Streaming

For live updates the chart calls subscribeTicks on your datafeed once a symbol resolves, and unsubscribeTicks when it no longer needs the stream. Push each trade to the callback and the chart builds bars from ticks itself:

const datafeed = { subscriptions: new Map(), subscribeTicks(symbolInfo, resolution, onRealtimeCallback, subscriberUID) { const ws = new WebSocket("wss://stream.bybit.com/v5/public/linear"); const topic = `publicTrade.${symbolInfo.symbol}`; ws.onopen = () => ws.send(JSON.stringify({ op: "subscribe", args: [topic] })); ws.onmessage = (event) => { const { topic: t, data } = JSON.parse(event.data); if (t !== topic || !data) return; data.forEach(({ T, s, S, p, i, v }) => { onRealtimeCallback({ type: "trade", productId: `BYBIT:FUTURE:${s}`, symbol: s, exchange: "BYBIT", segment: "FUTURE", timeStamp: new Date(T), tradeID: i, price: Number(p), quantity: Number(v), amount: Number(p) * Number(v), side: S.toUpperCase(), // "BUY" | "SELL" }); }); }; this.subscriptions.set(subscriberUID, ws); }, unsubscribeTicks(subscriberUID) { this.subscriptions.get(subscriberUID)?.close(); this.subscriptions.delete(subscriberUID); }, };

A complete, runnable version of this (including reconnect handling and shared sockets across charts) is in the Advanced Trading Demo on CodePen  and examples/codepen-advanced2.html in the SDK package.

State Persistence & Templates

Auto-save is on by default: the chart persists its state (symbol, interval, indicators, drawings) to sessionStorage and restores it on reload. Disable it if you manage state yourself:

GoChartingSDK.createChart("#chart-container", { // ... autoSave: false, });

For durable, server-side persistence, listen for the save events in appCallback:

appCallback: ({ eventType, message }) => { switch (eventType) { case "SAVE_CONFIGURATION_STORE": // Chart state changed — snapshot it to your backend break; case "SAVE_TEMPLATE": // User saved an indicator/drawing template break; case "DELETE_TEMPLATE": // User deleted a template break; } },

Configuration Extras

Localization

The UI ships with 20 locale keys. Pass one at creation:

GoChartingSDK.createChart("#chart-container", { // ... locale: "de-DE", });

Available: en-US, zh-CN, zh-TW, fr-FR, br-BR, ja-JP, jp-JP, pl-PL, es-ES, it-IT, ru-RU, de-DE, ar-AR, il-IL, th-TH, vn-VN, id-ID, my-MY, kr-KR, tr-TR. (ja-JP and jp-JP both resolve to Japanese.)

Theme overrides

Beyond theme: "dark" | "light", you can seed the initial chart configuration and accent color:

GoChartingSDK.createChart("#chart-container", { theme: "dark", themeColor: "#1e222d", // base UI color override defaultInitialChartConfig: { /* initial chart config overrides */ }, });

Mobile & native hosts

Use touchMode for the full JS mobile Chart-tab shell, or isNativeApp when a native WebView owns chrome and listens on the sendToNative bridge.

GoChartingSDK.createChart("#chart-container", { isNativeApp: true, // canvas only; events → RN / Flutter / Android / iOS });

See Mobile Integration for bridge setup, message shapes, and platform snippets (React Native, Flutter, Android, iOS).

Debug logging

Production bundles are console-silent by design. To see the SDK’s internal logging during development:

GoChartingSDK.createChart("#chart-container", { debugLog: true, // prefixes output with [GoCharting SDK] });
Last updated on