Skip to main content

Customization And Styling

TradeScript Pro Charts uses typed customization contracts across themes, chart settings, component styles, and feature policy. One theme call is the difference between the two states below — the chart state itself (symbol, interval, indicators, drawings, data) is untouched:

TradeScript chart rendered with the dark theme and complete widget chrome
Before: the dark theme. Chart canvas, controls, panes, menus, semantic colors, and typography form one coordinated skin.
The same TradeScript chart rendered with the light theme
After: setTheme('light'). The same chart state with a different complete skin. Theme changes do not change symbol, interval, indicators, drawings, or data.

Choose a mechanism

Five mechanisms cover styling and capability. Start from what you want to change:

You want to...MechanismVisual example
Swap the entire skin at once — canvas, chrome, and widgetsThemes — one preset id or one theme objectThe dark/light pair above; both states on Themes
Retune individual UI tokens — one button color, one focus ring, one fontCSS VariablesChartTheme.ui fields mapped to --ts-chart-* tokensToken groups by visual target on CSS Variables
Change specific chart values — grid color, candle colors, crosshair, session shadingOverridesapplyOverrides / applyStyleOverridesEach override group's visible result described on Overrides
Attach your own class or style to the chart's own furniture — toolbar, rail, scalesChrome SlotsslotClassNames / slotStylesAnnotated toolbar and legend anatomy on Chrome Slots
Show or hide product capabilities — search, drawings, indicators, templatesFeature Gatesfeatures on the widget optionsGate-by-surface matrix on Feature Gates

The five are not alternatives to one another — they stack. A theme supplies everything, overrides pin individual chart values above it, CSS variables retune single UI tokens, chrome slots attach your own classes to the chart's furniture, and feature gates decide what exists at all:

Read it bottom-up: the theme fills in every value, and each layer above it replaces only the keys it actually sets. When two mechanisms set the same property, Customization Precedence defines the winner. For "my setting is not applied" cases, use Customization Troubleshooting.

Detailed routing

NeedUse
Enable or hide product capabilitiesfeatures on ChartWidgetOptions
Set the base visual skintheme on ChartWidgetOptions
Brand runtime boot, initial data, and history fetchingloading on ChartWidgetOptions
Change theme at runtimechart.customization().setTheme(...)
Set chart, series, grid, axis, and session stylingchart.customization().applyOverrides(...)
Set indicator, drawing, handle, candle, text, and low-level style groupschart.customization().applyStyleOverrides(...)
Set candle colors with a dedicated helperchart.customization().setCandleColors(...)
Set watermark, legend, toolbar, context menu, locale, timezone, shortcuts, and tooltip formattingchart.customization()
Seed customization when the chart is createdinitialState.customization
Persist user preferencesstorage plus features.userSettings

Runtime Shape

Everything is reachable from one controller:

const ui = chart.customization();

ui.setTheme('dark');
ui.setTimezone('America/New_York');
ui.setLegend({ visible: true, showIndicatorRows: true });
ui.setWatermark({ autoText: { tickerVisible: true, intervalVisible: true, descriptionVisible: true } });
ui.setCandleColors({ up: '#16a34a', down: '#dc2626' });
ui.applyOverrides({ grid: { horizontal: { color: '#1f2937' } } });
ui.applyStyleOverrides({ handles: { color: '#1677FF' } });

Constructor Shape

Full constructor example: theme, branded loading phases, feature gates, and seeded customization
sdk.chart.mount({
mount: '#chart',
symbol: 'AAPL',
interval: '1D',
datafeed,
theme: {
name: 'broker-dark',
colors: {
background: '#071018',
grid: '#1f2937',
text: '#dbeafe',
up: '#16a34a',
down: '#dc2626',
},
fontFamily: 'Inter, system-ui, sans-serif',
},
loading: {
runtime: {
text: 'Loading broker workspace',
backgroundColor: '#071018',
foregroundColor: '#dbeafe',
accentColor: '#38bdf8',
indicator: { type: 'image', url: '/broker-mark.svg', size: 36 },
},
initialData: {
text: 'Loading market data',
indicator: { type: 'image', url: '/broker-mark.svg', size: 32 },
},
history: {
text: 'Loading history',
placement: 'top-left',
indicator: { type: 'image', url: '/broker-mark.svg', size: 20 },
},
},
features: {
symbolSearch: { showLogos: true, showExchangeLogos: true },
drawings: true,
builtInIndicators: true,
contextMenu: true,
templates: true,
userSettings: true,
},
initialState: {
customization: {
chartOverrides: {
grid: { horizontal: { color: '#1f2937' }, vertical: { color: '#1f2937' } },
},
styleOverrides: {
candles: {
bar: {
upColor: '#16a34a',
downColor: '#dc2626',
},
},
},
legend: { visible: true, showValues: true },
watermark: {
autoText: true,
color: '#94a3b8',
opacity: 0.14,
},
},
},
});

Image indicators default to a gentle pulse, fall back to the built-in ring if the image cannot load, and become static when the user's reduced-motion preference is enabled. Set any phase to false to disable it, or pass loading: false to disable all three. The deprecated loadingScreen option continues to configure runtime boot only.

Next steps