Skip to main content

Interval and Period Selectors

IntervalSelector and PeriodSelector are the SDK's ready-made toolbar buttons for the candle interval (1m, 1h, 1d, …) and the visible period (1D, 1M, 1Y, …). They work together: the period buttons disable the periods that don't suit the current interval, and an interval change can carry the period across.

Like the other toolbar controls, they only pick a value. Each calls onChange, and you pass the value on to the chart with changeInterval or setPeriod.

TypeScript Example: Interval and Period Selectors​

A chart of BTC-USD from Coinbase, with an IntervalSelector offering the intervals Coinbase supports and a PeriodSelector. Changing the interval keeps about the same span on screen, and the period buttons disable the periods that don't suit the new interval.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import {
CandleInterval,
carryPeriodToInterval,
CoinbaseExchange,
defaultExchangeProvider,
idbPriceStore,
IntervalSelector,
OHLCStudy,
PeriodSelector,
SciFinanceChartPanel,
VolumeStudy,
} from "scichart-scitrader";

// This example expects this HTML:
// <div style="display: flex; flex-direction: column; height: 100%">
// <div id="toolbar"></div>
// <div id="chart" style="flex: 1; min-height: 0"></div>
// </div>

// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);

// The intervals to offer: the ones Coinbase supports
const INTERVALS = [
CandleInterval.FIVE_MINUTES,
CandleInterval.FIFTEEN_MINUTES,
CandleInterval.ONE_HOUR,
CandleInterval.SIX_HOURS,
CandleInterval.ONE_DAY,
];

async function createChart() {
const toolbar = document.getElementById("toolbar");
Object.assign(toolbar.style, toolbarStyle);

const financeChartPanel = await SciFinanceChartPanel.create(document.getElementById("chart"), {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.ONE_HOUR,
period: "1M", // the last month
studies: [new OHLCStudy(), new VolumeStudy()],
});
const chart = financeChartPanel.financeApi; // SciFinanceChart

// IntervalSelector: a row of interval buttons. It calls onChange with the picked interval,
// and you pass it on to the chart with changeInterval
const intervals = IntervalSelector.create(toolbar, {
value: CandleInterval.ONE_HOUR,
intervals: INTERVALS,
onChange: (interval) => {
// Keep about the same span on screen, adjusted to suit the new interval
const period = carryPeriodToInterval(periods.value, interval);
// Tell the PeriodSelector, so it shows that period and disables the ones that don't suit
periods.update({ value: period, currentInterval: interval });
chart.changeInterval(interval, period);
},
});

// PeriodSelector: "Free" plus a row of period buttons. It calls onChange with the picked
// period, or null for "Free", and you pass it on to the chart with setPeriod
const periods = PeriodSelector.create(toolbar, {
value: "1M",
currentInterval: CandleInterval.ONE_HOUR, // disables the periods that don't suit 1h candles
onChange: (period) => chart.setPeriod(period),
});

// When the page goes away: intervals.destroy(); periods.destroy(); financeChartPanel.cleanup();
return { financeChartPanel, intervals, periods };
}

// The toolbar uses SciTrader's UI colours: its --st-ui-* CSS variables, with the stylesheet's defaults
const toolbarStyle: Partial<CSSStyleDeclaration> = {
display: "flex",
flexWrap: "wrap",
alignItems: "center",
gap: "8px",
padding: "8px",
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

createChart();

React Example: Interval and Period Selectors​

The same chart in React, with the React IntervalSelector and PeriodSelector from scichart-scitrader-react. They are controlled components: the interval and period live in React state.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import * as React from "react";
import {
CandleInterval,
carryPeriodToInterval,
CoinbaseExchange,
defaultExchangeProvider,
idbPriceStore,
ISciFinanceChartPanelApi,
ISciFinanceChartPanelConfig,
OHLCStudy,
TPeriod,
VolumeStudy,
} from "scichart-scitrader";
import { IntervalSelector, PeriodSelector, SciFinanceChartView } from "scichart-scitrader-react";

// Register a data source, once, at app startup
defaultExchangeProvider.registerExchange(CoinbaseExchange, idbPriceStore);

// The intervals to offer: the ones Coinbase supports
const INTERVALS = [
CandleInterval.FIVE_MINUTES,
CandleInterval.FIFTEEN_MINUTES,
CandleInterval.ONE_HOUR,
CandleInterval.SIX_HOURS,
CandleInterval.ONE_DAY,
];

export function IntervalPeriodChart() {
const chartRef = React.useRef<ISciFinanceChartPanelApi>(null);
// The controls are controlled components: their value lives in React state
const [interval, setInterval] = React.useState(CandleInterval.ONE_HOUR);
const [period, setPeriod] = React.useState<TPeriod | null>("1M");

// Read once, when the chart is created. Later changes go through financeApi
const config = React.useMemo<ISciFinanceChartPanelConfig>(
() => ({
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.ONE_HOUR,
period: "1M",
studies: [new OHLCStudy(), new VolumeStudy()],
}),
[]
);

// financeApi throws until the chart has initialised
const chart = () => (chartRef.current?.isInitialized ? chartRef.current.financeApi : undefined);

// Fills its parent, so give the parent a height
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<div style={toolbarStyle}>
<IntervalSelector
value={interval}
intervals={INTERVALS}
onChange={(next) => {
// Keep about the same span on screen, adjusted to suit the new interval
const carried = carryPeriodToInterval(period, next);
setInterval(next);
setPeriod(carried);
chart()?.changeInterval(next, carried);
}}
/>
<PeriodSelector
value={period}
// Disables the periods that don't suit the interval
currentInterval={interval}
// next is a TPeriod, or null for "Free"
onChange={(next) => {
setPeriod(next);
chart()?.setPeriod(next);
}}
/>
</div>
<div style={{ flex: 1, minHeight: 0 }}>
<SciFinanceChartView ref={chartRef} config={config} />
</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",
flexWrap: "wrap",
alignItems: "center",
gap: 8,
padding: 8,
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

IntervalSelector: Interval Buttons​

A row of interval buttons. Picking one selects it and calls onChange with the interval.

OptionTypeWhat it does
valueCandleIntervalThe selected interval
intervalsreadonly CandleInterval[]The intervals to offer, in order. Default DEFAULT_INTERVALS: the common ones, from 1s to 1M. ALL_INTERVALS lists every interval
onChange(interval: CandleInterval) => voidCalled when the user picks a different interval
autoSelectbooleanWhether a pick is selected straight away. Default true; see How the Components Work

Every interval it shows is enabled, so pass it only the intervals the exchange supports. DEFAULT_INTERVALS includes some that Coinbase doesn't have, such as 4h; see Which Intervals an Exchange Supports.

The IntervalSelector class, IIntervalSelectorOptions and DEFAULT_INTERVALS, with their TSDoc
/**
* A row of interval buttons (1s, 1m, 5m … 1M), in plain DOM. Picking one selects it and calls
* `onChange`; pass the interval on to the chart with `financeApi.changeInterval(interval)`. Every
* interval is always enabled: the period selector is the one that rules out combinations.
*
* Its look is `.st-toggle-group.st-interval-selector` in `scitrader.css`.
*
* ```ts
* const intervals = IntervalSelector.create(toolbar, {
* value: CandleInterval.ONE_DAY,
* onChange: (interval) => panel.financeApi.changeInterval(interval),
* });
* ```
*
* React apps use the React `IntervalSelector`.
*/
class IntervalSelector {
/** The control's element, inside the container passed to {@link create}. */
readonly element: HTMLDivElement;
static create(container: HTMLElement, options: IIntervalSelectorOptions): IntervalSelector;
/**
* The control's HTML for these options, without behaviour: for rendering on a server. A
* control created with the same options produces the same markup.
*/
static toHTML(options: IIntervalSelectorOptions): string;
/** The selected interval. */
get value(): CandleInterval;
/** Change any of the options; the ones not given stay as they are. */
update(options: Partial<IIntervalSelectorOptions>): void;
destroy(): void;
}

/** Options for {@link IntervalSelector}. */
interface IIntervalSelectorOptions {
/** The selected interval. */
value: CandleInterval;
/** The intervals to offer, in order. Default {@link DEFAULT_INTERVALS}. */
intervals?: readonly CandleInterval[];
/** Called when the user picks a different interval (never with the selected one). */
onChange?: (interval: CandleInterval) => void;
/**
* Whether picking an option selects it straight away. Default `true`. With `false` the control
* only calls `onChange`, and shows the new selection once you pass it back with
* `update({ value })`; the React wrappers work this way, so the parent's state decides.
*/
autoSelect?: boolean;
}

/**
* The intervals {@link IntervalSelector} shows by default: the common ones, leaving out the rarer
* cadences (3m, 2h, 6h, 8h, 12h, 3d) to keep a toolbar compact. `ALL_INTERVALS` lists every
* interval, in duration order.
*/
const DEFAULT_INTERVALS: readonly CandleInterval[];
The React IntervalSelector and its props, with their TSDoc
/** Props for {@link IntervalSelector}. */
interface IIntervalSelectorProps extends IHostProps {
/** The selected interval. */
value: CandleInterval;
/** Called when the user picks a different interval. */
onChange: (interval: CandleInterval) => void;
/** The intervals to offer, in order. Default `DEFAULT_INTERVALS`. */
intervals?: readonly CandleInterval[];
}

/**
* The SDK's interval buttons in React: the vanilla `IntervalSelector` in a `<div>`, controlled by
* `value` and `onChange`.
*
* ```tsx
* <IntervalSelector value={interval} onChange={(next) => { setInterval(next); chart.financeApi.changeInterval(next); }} />
* ```
*/
function IntervalSelector({ value, onChange, intervals, className, style }: IIntervalSelectorProps): React.JSX.Element;

/** Props every React finance control takes besides its own. */
interface IHostProps {
className?: string;
style?: React.CSSProperties;
}

PeriodSelector: Period Buttons​

"Free" followed by a row of period buttons. Picking one selects it and calls onChange with the period. "Free", or a click on the selected period, calls onChange(null): no period.

OptionTypeWhat it does
valueTPeriod | nullThe selected period, or null for "Free"
periodsreadonly TPeriod[]The periods to offer, in order, after "Free". Default ALL_PERIODS: all twelve
currentIntervalCandleIntervalThe chart's interval. The periods that don't suit it are disabled, as validPeriodsForInterval decides
onChange(period: TPeriod | null) => voidCalled when the user picks a period, or "Free"
autoSelectbooleanWhether a pick is selected straight away. Default true
The PeriodSelector class and IPeriodSelectorOptions, with their TSDoc
/**
* A row of period buttons ("Free", 1D, 5D, 1M … ALL), in plain DOM. Picking one selects it and
* calls `onChange`; pass it on to the chart with `financeApi.setPeriod(period)`. Clicking the
* selected period again clears it, like "Free".
*
* Give it the chart's interval (`currentInterval`) and it disables the periods that don't suit
* it. Its look is `.st-toggle-group.st-period-selector` in `scitrader.css`.
*
* ```ts
* const periods = PeriodSelector.create(toolbar, {
* value: "3M",
* currentInterval: CandleInterval.ONE_DAY,
* onChange: (period) => period && panel.financeApi.setPeriod(period),
* });
* // after an interval change:
* periods.update({ currentInterval: interval });
* ```
*
* React apps use the React `PeriodSelector`.
*/
class PeriodSelector {
/** The control's element, inside the container passed to {@link create}. */
readonly element: HTMLDivElement;
static create(container: HTMLElement, options: IPeriodSelectorOptions): PeriodSelector;
/**
* The control's HTML for these options, without behaviour: for rendering on a server. A
* control created with the same options produces the same markup.
*/
static toHTML(options: IPeriodSelectorOptions): string;
/** The selected period, or `null` for none. */
get value(): TPeriod | null;
/** Change any of the options; the ones not given stay as they are. */
update(options: Partial<IPeriodSelectorOptions>): void;
destroy(): void;
}

/** Options for {@link PeriodSelector}. */
interface IPeriodSelectorOptions {
/** The selected period, or `null` for none (the "Free" button). */
value: TPeriod | null;
/** The periods to offer, in order, after "Free". Default `ALL_PERIODS`. */
periods?: readonly TPeriod[];
/**
* The chart's interval. When set, periods that don't suit it are disabled, as
* `validPeriodsForInterval` decides: at a 1d interval, for example, "1D" would show one candle.
*/
currentInterval?: CandleInterval;
/**
* Called when the selection changes: with a period, or with `null` when the user picks "Free"
* or clicks the selected period again.
*/
onChange?: (period: TPeriod | null) => void;
/**
* Whether picking an option selects it straight away. Default `true`. With `false` the control
* only calls `onChange`, and shows the new selection once you pass it back with
* `update({ value })`; the React wrappers work this way, so the parent's state decides.
*/
autoSelect?: boolean;
}
The React PeriodSelector and its props, with their TSDoc
/** Props for {@link PeriodSelector}. */
interface IPeriodSelectorProps extends IHostProps {
/** The selected period, or `null` for none ("Free"). */
value: TPeriod | null;
/** Called with the picked period, or `null` for "Free" (or a click on the selected period). */
onChange: (period: TPeriod | null) => void;
/** The periods to offer, in order. Default `ALL_PERIODS`. */
periods?: readonly TPeriod[];
/** The chart's interval; periods that don't suit it are disabled. */
currentInterval?: CandleInterval;
}

/**
* The SDK's period buttons in React: the vanilla `PeriodSelector` in a `<div>`, controlled by
* `value` and `onChange`.
*
* ```tsx
* <PeriodSelector value={period} currentInterval={interval} onChange={setPeriod} />
* ```
*/
function PeriodSelector({ value, onChange, periods, currentInterval, className, style }: IPeriodSelectorProps): React.JSX.Element;

/** Props every React finance control takes besides its own. */
interface IHostProps {
className?: string;
style?: React.CSSProperties;
}

Keeping the Two Selectors in Step​

When the interval changes, tell the PeriodSelector the new interval, so it disables the right periods. Pass it the period to show, too. carryPeriodToInterval keeps about the same span, adjusted to suit the new interval:

import { carryPeriodToInterval } from "scichart-scitrader";

const intervals = IntervalSelector.create(toolbar, {
value: CandleInterval.ONE_HOUR,
onChange: (interval) => {
// The period to land on: about the span the user had, adjusted to suit the new interval
const period = carryPeriodToInterval(periods.value, interval);
// Update the PeriodSelector: its selection, and which periods it disables
periods.update({ value: period, currentInterval: interval });
// Change the chart's interval and period in one load
chart.changeInterval(interval, period);
},
});

In React, keep the interval and period in state and pass currentInterval={interval}, as the React example does. See Keeping the User's Span.

Styling the Interval and Period Selectors​

Both are toggle groups: a rounded pill of buttons. The stylesheet gives them these classes:

ElementClass
The groupst-toggle-group, plus st-interval-selector or st-period-selector
Each buttonst-toggle-group__button

States use attributes, not extra classes: the selected button has aria-pressed="true", and a period that doesn't suit the interval is :disabled. The colours come from the theme variables: --st-ui-surface for the pill, --st-ui-background for the selected button, and --st-ui-text and --st-ui-text-muted for the labels.

Override them in your own CSS, loaded after scitrader.css. Scope the rules under a class of your own, so they apply to one toolbar and win over the stylesheet's:

/* Square buttons, with the selected interval or period in the accent colour */
.my-toolbar .st-toggle-group {
border-radius: 2px;
}
.my-toolbar .st-toggle-group__button {
border-radius: 2px;
font-size: 13px;
}
.my-toolbar .st-toggle-group__button[aria-pressed="true"] {
background: var(--st-ui-accent, #7464ff);
}

/* Only the period buttons: hide the ones that don't suit the interval, instead of greying them */
.my-toolbar .st-period-selector .st-toggle-group__button:disabled {
display: none;
}

In React, className and style apply to the wrapper's host <div>. To change colours everywhere, change the theme instead; see Styling and Themes.

See also​