Skip to main content

Colour Picker

ColorPicker is a labelled swatch that opens a colour picker: a saturation and brightness square, hue and opacity strips, a hex box, and R, G, B and A boxes. It works from the keyboard, and closes on Escape or a click outside.

Its value is any CSS colour. It reports six-digit hex (#rrggbb) when the colour is opaque, and #rrggbbaa when it isn't. A drag calls onChange continuously, so debounce anything expensive.

The study settings forms use it for every colour setting, and it suits any colour setting of your own app. The examples below use it to recolour indicators on a live chart: an SMA line, and MACD's two lines.

TypeScript Example: Changing Indicator Colours with ColorPicker​

A chart of BTC-USD from Coinbase, with a 20-candle SMA and a MACD pane. The three colour pickers in the toolbar recolour the SMA line, the MACD line and the signal line as you drag.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import {
CandleInterval,
ColorPicker,
CoinbaseExchange,
defaultExchangeProvider,
EDescriptorSectionName,
idbPriceStore,
IStudy,
MACDStudy,
OHLCStudy,
SciFinanceChartPanel,
SMAStudy,
} 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);

// Change one colour setting of a live study.
// A study's settings are its descriptor: "inputs" and "styles" sections of named controls, each
// holding its value in `default`. Copy the descriptor with one control's value changed, and apply
// it: SMAStudy and MACDStudy restyle their series in place, without reloading any data
function setStudyColour(study: IStudy, control: string, colour: string) {
const descriptor = study.getDescriptor();
const styles = descriptor[EDescriptorSectionName.STYLES].controls;
study.applyDescriptor({
...descriptor,
[EDescriptorSectionName.STYLES]: {
controls: { ...styles, [control]: { ...styles[control], default: colour } },
},
});
}

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

// Give the studies their starting colours, so the colour pickers can start from them,
// and 2px lines, so colour changes are easy to see
const sma = new SMAStudy({ length: 20, renderOptions: { stroke: "#ff9f1c", strokeThickness: 2 } });
const macd = new MACDStudy({ bandOptions: { stroke: "#2ec4b6", strokeY1: "#e71d36", strokeThickness: 2 } });

const financeChartPanel = await SciFinanceChartPanel.create(document.getElementById("chart"), {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "1M", // the last month: fewer candles, so colour changes are easy to see
studies: [new OHLCStudy(), sma, macd],
});

// ColorPicker: a labelled swatch that opens a colour picker with opacity.
// onChange is called on every change, with "#rrggbb", or "#rrggbbaa" when not opaque
const pickers = [
ColorPicker.create(toolbar, {
label: "SMA 20",
value: "#ff9f1c",
onChange: (colour) => setStudyColour(sma, "strokeColor", colour),
}),
ColorPicker.create(toolbar, {
label: "MACD line",
value: "#2ec4b6",
onChange: (colour) => setStudyColour(macd, "bandMacdColor", colour),
}),
ColorPicker.create(toolbar, {
label: "Signal line",
value: "#e71d36",
onChange: (colour) => setStudyColour(macd, "bandSignalColor", colour),
}),
];

// When the page goes away: pickers.forEach((p) => p.destroy()); financeChartPanel.cleanup();
return { financeChartPanel, pickers };
}

// 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: "24px",
padding: "8px 12px",
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

createChart();

React Example: Changing Indicator Colours with ColorPicker​

The same chart in React, with the React ColorPicker from scichart-scitrader-react. Each picker is a controlled component: its colour lives in React state.

The code for this example is found below.

import "scichart-scitrader/scitrader.css";
import * as React from "react";
import {
CandleInterval,
CoinbaseExchange,
defaultExchangeProvider,
EDescriptorSectionName,
idbPriceStore,
ISciFinanceChartPanelConfig,
IStudy,
MACDStudy,
OHLCStudy,
SMAStudy,
} from "scichart-scitrader";
import { ColorPicker, SciFinanceChartView } from "scichart-scitrader-react";

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

// Change one colour setting of a live study.
// A study's settings are its descriptor: "inputs" and "styles" sections of named controls, each
// holding its value in `default`. Copy the descriptor with one control's value changed, and apply
// it: SMAStudy and MACDStudy restyle their series in place, without reloading any data
function setStudyColour(study: IStudy, control: string, colour: string) {
const descriptor = study.getDescriptor();
const styles = descriptor[EDescriptorSectionName.STYLES].controls;
study.applyDescriptor({
...descriptor,
[EDescriptorSectionName.STYLES]: {
controls: { ...styles, [control]: { ...styles[control], default: colour } },
},
});
}

export function StudyColoursChart() {
// The pickers are controlled components: their colours live in React state
const [smaColour, setSmaColour] = React.useState("#ff9f1c");
const [macdColour, setMacdColour] = React.useState("#2ec4b6");
const [signalColour, setSignalColour] = React.useState("#e71d36");

// Create the studies and config once per mounted chart: studies are live objects bound to one chart.
// 2px lines, so colour changes are easy to see
const { sma, macd, config } = React.useMemo(() => {
const sma = new SMAStudy({ length: 20, renderOptions: { stroke: "#ff9f1c", strokeThickness: 2 } });
const macd = new MACDStudy({ bandOptions: { stroke: "#2ec4b6", strokeY1: "#e71d36", strokeThickness: 2 } });
const config: ISciFinanceChartPanelConfig = {
exchangeName: CoinbaseExchange.name, // name="Coinbase" matches the built-in CoinbaseExchange
symbol: "BTC-USD",
interval: CandleInterval.SIX_HOURS,
period: "1M", // the last month: fewer candles, so colour changes are easy to see
studies: [new OHLCStudy(), sma, macd],
};
return { sma, macd, config };
}, []);

// Fills its parent, so give the parent a height
return (
<div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
<div style={toolbarStyle}>
<ColorPicker
label="SMA 20"
value={smaColour}
onChange={(colour) => {
setSmaColour(colour);
setStudyColour(sma, "strokeColor", colour);
}}
/>
<ColorPicker
label="MACD line"
value={macdColour}
onChange={(colour) => {
setMacdColour(colour);
setStudyColour(macd, "bandMacdColor", colour);
}}
/>
<ColorPicker
label="Signal line"
value={signalColour}
onChange={(colour) => {
setSignalColour(colour);
setStudyColour(macd, "bandSignalColor", colour);
}}
/>
</div>
<div style={{ flex: 1, minHeight: 0 }}>
<SciFinanceChartView 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: 24,
padding: "8px 12px",
background: "var(--st-ui-background, #2b2839)",
borderBottom: "1px solid var(--st-ui-divider, rgba(255,255,255,0.1))",
};

Applying a Colour to a Study​

A study's settings are its descriptor: an inputs section and a styles section, each a set of named controls holding their value in default. A colour setting is a control of type "color", such as SMA's strokeColor. To change one setting:

  1. Read the study's current settings with study.getDescriptor().
  2. Make a copy with that one control's value changed.
  3. Apply the copy with study.applyDescriptor(descriptor).
import { EDescriptorSectionName, IStudy } from "scichart-scitrader";

// Change one colour setting of a live study, e.g. setStudyColour(sma, "strokeColor", "#ff9f1c")
function setStudyColour(study: IStudy, control: string, colour: string) {
const descriptor = study.getDescriptor();
const styles = descriptor[EDescriptorSectionName.STYLES].controls;
study.applyDescriptor({
...descriptor,
[EDescriptorSectionName.STYLES]: {
controls: { ...styles, [control]: { ...styles[control], default: colour } },
},
});
}

Studies whose supportsLiveApply is true, such as SMAStudy and MACDStudy, restyle their series in place, without reloading any data. Each study has its own control names. To see them, log study.getDescriptor().styles.controls; for example:

StudyColour controls
SMAStudystrokeColor
MACDStudybandMacdColor (MACD line), bandSignalColor (signal line), fillMacdAboveSignal, fillMacdBelowSignal, histogramAboveZero, histogramBelowZero

The settings you apply are saved with the chart, so they survive toJSON and fromJSON. For a complete form of a study's settings, with a ColorPicker for each colour, use StudySettingsForm instead; see Study Settings Form and Study List.

The descriptor's types, TStudyDescriptor, IuiDescriptor and EDescriptorSectionName, are documented under Study Settings Are a Descriptor, and getDescriptor, applyDescriptor and the other settings members of a study under The IStudy Interface.

ColorPicker Options​

OptionTypeWhat it does
labelstringThe label shown before the swatch
valuestringThe colour: any CSS colour; #rrggbbaa for one with opacity
onChange(value: string) => voidCalled on every change, with #rrggbb, or #rrggbbaa when not opaque
trailingHTMLElement (React: ReactNode)Shown after the swatch, on the same row
popoverContainerHTMLElementWhere the open picker is attached. Default document.body. Not in the React props
The ColorPicker class and IColorPickerOptions, with their TSDoc
/**
* A colour field with an opacity channel, in plain DOM: a label and a swatch (over a
* checkerboard, so transparency shows) that opens a picker with a saturation/brightness square,
* hue and opacity strips, a hex box and R/G/B/A byte boxes.
*
* Every part works from the keyboard: the square and strips are sliders (arrow keys, Shift for
* bigger steps). The picker closes on Escape or a click outside. The look is `.st-color-field` and
* `.st-color-popover` in `scitrader.css`.
*
* While the picker is open it holds the colour as HSVA, so the hue strip still works on white or
* black, which have no hue of their own.
*/
class ColorPicker {
/** The field row, inside the container passed to {@link create}. */
readonly element: HTMLDivElement;
static create(container: HTMLElement, options: IColorPickerOptions): ColorPicker;
/** The current colour, as `onChange` would report it. */
get value(): string;
/** Whether the picker is open. */
get isOpen(): boolean;
/** Change any of the options; the ones not given stay as they are. */
update(options: Partial<IColorPickerOptions>): void;
destroy(): void;
}

/** Options for {@link ColorPicker}. */
interface IColorPickerOptions {
label: string;
/** The colour: any CSS colour; 8-digit hex is `#rrggbbaa`. */
value: string;
/**
* Called on every change, with 6-digit hex when opaque and `#rrggbbaa` when not. A drag calls
* it continuously, so debounce expensive work.
*/
onChange?: (value: string) => void;
/**
* Shown after the swatch on the same row, taking the remaining width (the gradient editor puts
* a stop's position here). The label then shrinks to its text.
*/
trailing?: HTMLElement;
/** Where the open picker is attached. Default `document.body`. */
popoverContainer?: HTMLElement;
}
The React ColorPicker and its props, with their TSDoc
/** Props for {@link ColorPicker}. */
interface IColorPickerProps extends IHostProps {
label: string;
/** Any CSS colour; 8-digit hex is `#rrggbbaa`. */
value: string;
/** Called on every change: 6-digit hex when opaque, `#rrggbbaa` when not. */
onChange: (value: string) => void;
/** Shown after the swatch on the same row. */
trailing?: React.ReactNode;
}

/**
* The SDK's colour field in React: a label and swatch that open a picker with opacity. Controlled
* by `value` and `onChange`.
*/
function ColorPicker({ label, value, onChange, trailing, className, style }: IColorPickerProps): JSX.Element;

/** Props every React study-settings component takes besides its own. */
interface IHostProps {
className?: string;
style?: React.CSSProperties;
}

GradientRampEditor edits a colour ramp, such as the order-book heatmap's, with a draggable handle for each stop. It is the gradient field of the settings form, and has no React wrapper.

Styling the Colour Picker​

ElementClass
The field: label and swatchst-color-field (--with-trailing with a trailing element), __label, __swatch, __swatch-color, __trailing
The open pickerst-color-popover, __picker, __saturation, __hue, __alpha, __hex, __channels, __channel
/* A round swatch */
.st-color-field__swatch,
.st-color-field__swatch-color {
border-radius: 50%;
}

The picker is attached to document.body, outside your toolbar, so scope its rules by its own class, or attach it inside your container with popoverContainer. See Styling and Themes.

See also​