SciFinanceChart: the Trading Chart Component
The chart itself: a candlestick chart of one symbol, with a pane for each indicator that needs one, live data, and zoom and pan. It comes in two forms, with the same config and the same API:
| Plain TypeScript | React | |
|---|---|---|
| The component | Sci | <, from scichart- |
| Create it | await | < |
| Its API | What create resolves with | on, or ref |
| Remove it | finance | Unmount it |
Both create:
- the panes: the price pane, and a pane for each study that needs one, with dividers to resize them and a control bar on each;
- a data feed for the symbol, from the exchange you name, which loads older candles as the user pans back and adds live ones;
- the chart's interaction: zoom, pan, axis drag, crosshair and legend, by mouse or by touch.
The config is an ISciFinanceChartPanelConfig, and the API an ISciFinanceChartPanelApi, called financeChartPanel in these docs. Its financeApi is the chart, a SciFinanceChart, and its paneGroupApi the panes.
TypeScript Example: Creating a Chart
SciFinanceChartPanel.create builds the chart inside an element. The element needs a size: the chart fills it, and follows it when it resizes.
The code for this example is found below.
- TS
import "scichart-scitrader/scitrader.css";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
idbPriceStore,
OHLCStudy,
SciFinanceChartPanel,
VolumeStudy,
} from "scichart-scitrader";
// 1. Register a data source, once, at app startup.
// idbPriceStore caches candles in IndexedDB, so a reload only fetches what is new.
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);
// 2. Create the chart inside an element that has a size, e.g. <div id="chart" style="height: 600px">
async function createChart(elementId: string) {
const financeChartPanel = await SciFinanceChartPanel.create(document.getElementById(elementId), {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD", // Coinbase's symbol format
interval: CandleInterval.ONE_HOUR, // Coinbase offers 1m, 5m, 15m, 1h, 6h and 1d candles
// OHLCStudy draws the candles; VolumeStudy adds volume columns along the bottom of the price pane
studies: [new OHLCStudy(), new VolumeStudy()],
});
// 3. When the element goes away, free the chart's resources with financeChartPanel.cleanup()
return financeChartPanel;
}
createChart("chart");
React Example: Creating a Chart
<SciFinanceChartView> takes the same config, and fills its parent, so give the parent a height. It is in the React package, scichart-scitrader-react, along with React versions of the other UI components. It needs the core package and its peer dependencies too:
npm install scichart-scitrader-react scichart-scitrader scichart scichart-financial-tools rxjs react react-dom
See Installation for the versions, the stylesheet and serving SciChart's WebAssembly.
The code for this example is found below.
- React
import "scichart-scitrader/scitrader.css";
import * as React from "react";
import {
ADXStudy,
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
idbPriceStore,
ISciFinanceChartPanelApi,
ISciFinanceChartPanelConfig,
IStudy,
MACDStudy,
OHLCStudy,
RSIStudy,
VolumeStudy,
} from "scichart-scitrader";
import { SciFinanceChartView } from "scichart-scitrader-react";
// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);
export function TradingChart() {
// The same ISciFinanceChartPanelApi that SciFinanceChartPanel.create returns
const chartRef = React.useRef<ISciFinanceChartPanelApi>(null);
// The studies on the chart, kept in state so the buttons re-render when they change
const [studies, setStudies] = React.useState<readonly IStudy[]>([]);
const [ready, setReady] = React.useState(false);
// Create the config once per mounted chart: studies are live objects bound to one chart
const config = React.useMemo<ISciFinanceChartPanelConfig>(
() => ({
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "ETH-USD", // Coinbase's symbol format
interval: CandleInterval.ONE_DAY,
period: "1Y",
studies: [new OHLCStudy(), new VolumeStudy(), new RSIStudy()],
}),
[]
);
// financeApi throws until the chart has initialised, so only use it from onInit
const onInit = (api: ISciFinanceChartPanelApi) => {
const chart = api.financeApi;
setReady(true);
setStudies(chart.studies); // studies returns a new array each time, so React sees the change
// Also fires when the user closes a study's pane from the chart.
// The chart is deleted when this component unmounts, so there's no need to unsubscribe.
chart.studiesChanged.subscribe(() => setStudies(chart.studies));
};
// Detach the study of this type if the chart has one, otherwise attach a new one
const toggleStudy = (StudyType: new () => IStudy) => {
const chart = chartRef.current;
if (!chart?.isInitialized) return;
const existing = chart.financeApi.studies.find((study) => study instanceof StudyType);
if (existing) {
chart.financeApi.detachStudy(existing);
} else {
chart.financeApi.attachStudy(new StudyType());
}
};
const hasMacd = studies.some((study) => study instanceof MACDStudy);
const hasAdx = studies.some((study) => study instanceof ADXStudy);
// Fills its parent, so give the parent a height
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<div style={toolbarStyle}>
<button style={buttonStyle(hasMacd, ready)} disabled={!ready} onClick={() => toggleStudy(MACDStudy)}>
{hasMacd ? "Remove MACD" : "Add MACD"}
</button>
<button style={buttonStyle(hasAdx, ready)} disabled={!ready} onClick={() => toggleStudy(ADXStudy)}>
{hasAdx ? "Remove ADX" : "Add ADX"}
</button>
</div>
<div style={{ flex: 1, minHeight: 0 }}>
<SciFinanceChartView ref={chartRef} config={config} onInit={onInit} />
</div>
</div>
);
}
// The toolbar uses SciTrader's UI colours: its --st-ui-* CSS variables, with the stylesheet's defaults
const toolbarStyle: React.CSSProperties = {
display: "flex",
gap: 8,
padding: 8,
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};
const buttonStyle = (active: boolean, enabled: boolean): React.CSSProperties => ({
padding: "6px 14px",
fontSize: 14,
fontFamily: "var(--st-font-family, sans-serif)",
color: "var(--st-ui-text, #ffffff)",
background: active ? "var(--st-ui-accent, #7464ff)" : "var(--st-ui-surface, #373447)",
border: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
borderRadius: 4,
cursor: enabled ? "pointer" : "default",
opacity: enabled ? 1 : 0.5,
});
- Wait for
onInit.ref.currentis set as soon as the view mounts, but itsfinanceApithrows until the chart has initialised. UseonInit, or checkisInitialized, first. configis read once. Changing it doesn't rebuild the chart: change a live chart throughfinanceApi, or remount it with a newkeyto start again.paneControlsis live. Unlikeconfig, a change to thepaneControlsprop applies to the running chart.- Unmounting cleans up. The view calls
cleanup()itself.
Pane Sizes, and Pane State in Code
Set each pane's size when you create the chart with paneSizing, by pane id. Afterwards, paneGroupApi reads and sets the same state the pane control bars do: size, hidden, maximised and closed. financeApi sets each pane's Y-axis autorange.
const RSI_PANE = new PaneId("rsi");
const financeChartPanel = await SciFinanceChartPanel.create(element, {
// …
studies: [new OHLCStudy(), new VolumeStudy(), new RSIStudy({ paneId: RSI_PANE })],
paneSizing: {
[PaneId.DEFAULT.value]: { grow: 3 }, // the price pane takes 3 shares of the height
[RSI_PANE.value]: { size: 110 }, // the RSI pane is 110 px high
},
});
financeChartPanel.paneGroupApi.setExpanded(RSI_PANE.value); // maximise the RSI pane
financeChartPanel.financeApi.getYAxisAutoRangeController(RSI_PANE).isYAxisAutoRangeEnabled = false;
Pane Sizes and Pane State covers each of them, with live examples.
Mobile and Desktop Modes
The chart works by mouse and by touch, but some parts have a touch layout, which your app turns on: the chart doesn't detect touch screens. Decide from your app's own breakpoint, and pass it in:
const touch = matchMedia("(pointer: coarse)").matches; // or your app's breakpoint
const financeChartPanel = await SciFinanceChartPanel.create(element, { /* … */ paneControls: { touch } });
const drawing = DrawingToolsController.attach(financeChartPanel.financeApi, { touch, selectFinishedDrawing: !touch });
Mobile and Desktop Modes lists what changes, and how the SciTrader app decides.
Pages in This Section
| Page | What it covers |
|---|---|
| Pane Sizes and Pane State | Pane sizes; Y-axis autorange, maximising, hiding and closing panes in code |
| Mobile and Desktop Modes | Touch and mouse layouts, and how your app chooses |
| Layout, Panes and PaneGroup | Sub-chart and multi-chart modes, pane control bars, loading states, and the layout underneath |
| Finance Chart API | ISci, and the Sci class |
| Chart Config Object | Every ISci option |
Where to read next
- Symbols, Intervals and Periods: change what the chart shows.
- Studies and Indicators: add RSI, MACD, Bollinger Bands and more.
- UI Components: the toolbar controls, drawing toolbar, market depth and watchlist around the chart.