Stock Chart.

PRO

Combine price history with financial exploration controls.

Live preview13 feature examples

LIVE EXAMPLE

Explore prices

Match the page theme
Interact with the chart to see selection and range-change results here.
OptionsChanges are reflected in the preview and code.
Appearance and style9
Title and dimensions3

Browse price history with Navigator and the range selector. All values are sample data.

View code
Current preview
<div id="chart-container" style="width: 100%; min-width: 0;"></div>

<script type="module">
  import { defineCustomElement as define0 } from '@syidax/advanced-pro/components/sy-stock-chart.js';
  define0();

  // Pro: complete registerLicense at app startup using your issued certificate.
  // The website preview certificate is not for use in customer apps.
  const specs = [
    {
      "id": "example-chart",
      "tag": "sy-stock-chart",
      "props": {
        "data": [
          {
            "time": 1767225600000,
            "open": 100,
            "close": 95,
            "high": 103,
            "low": 92,
            "volume": 1200
          },
          {
            "time": 1767312000000,
            "open": 104,
            "close": 106,
            "high": 109,
            "low": 101,
            "volume": 1337
          },
          {
            "time": 1767398400000,
            "open": 107,
            "close": 105,
            "high": 110,
            "low": 102,
            "volume": 1474
          },
          {
            "time": 1767484800000,
            "open": 109,
            "close": 114,
            "high": 117,
            "low": 106,
            "volume": 1611
          },
          {
            "time": 1767571200000,
            "open": 108,
            "close": 109,
            "high": 112,
            "low": 105,
            "volume": 1748
          },
          {
            "time": 1767657600000,
            "open": 106,
            "close": 103,
            "high": 109,
            "low": 100,
            "volume": 1885
          },
          {
            "time": 1767744000000,
            "open": 102,
            "close": 106,
            "high": 109,
            "low": 99,
            "volume": 2022
          },
          {
            "time": 1767830400000,
            "open": 100,
            "close": 100,
            "high": 103,
            "low": 97,
            "volume": 2159
          },
          {
            "time": 1767916800000,
            "open": 98,
            "close": 94,
            "high": 101,
            "low": 91,
            "volume": 2296
          },
          {
            "time": 1768003200000,
            "open": 99,
            "close": 102,
            "high": 105,
            "low": 96,
            "volume": 2433
          },
          {
            "time": 1768089600000,
            "open": 101,
            "close": 100,
            "high": 104,
            "low": 97,
            "volume": 2570
          },
          {
            "time": 1768176000000,
            "open": 105,
            "close": 100,
            "high": 108,
            "low": 97,
            "volume": 2707
          },
          {
            "time": 1768262400000,
            "open": 109,
            "close": 111,
            "high": 114,
            "low": 106,
            "volume": 2844
          },
          {
            "time": 1768348800000,
            "open": 113,
            "close": 111,
            "high": 116,
            "low": 108,
            "volume": 2981
          },
          {
            "time": 1768435200000,
            "open": 115,
            "close": 120,
            "high": 123,
            "low": 112,
            "volume": 1318
          },
          {
            "time": 1768521600000,
            "open": 115,
            "close": 116,
            "high": 119,
            "low": 112,
            "volume": 1455
          },
          {
            "time": 1768608000000,
            "open": 114,
            "close": 111,
            "high": 117,
            "low": 108,
            "volume": 1592
          },
          {
            "time": 1768694400000,
            "open": 111,
            "close": 115,
            "high": 118,
            "low": 108,
            "volume": 1729
          },
          {
            "time": 1768780800000,
            "open": 108,
            "close": 108,
            "high": 111,
            "low": 105,
            "volume": 1866
          },
          {
            "time": 1768867200000,
            "open": 105,
            "close": 101,
            "high": 108,
            "low": 98,
            "volume": 2003
          },
          {
            "time": 1768953600000,
            "open": 105,
            "close": 108,
            "high": 111,
            "low": 102,
            "volume": 2140
          },
          {
            "time": 1769040000000,
            "open": 107,
            "close": 106,
            "high": 110,
            "low": 103,
            "volume": 2277
          },
          {
            "time": 1769126400000,
            "open": 110,
            "close": 105,
            "high": 113,
            "low": 102,
            "volume": 2414
          },
          {
            "time": 1769212800000,
            "open": 114,
            "close": 116,
            "high": 119,
            "low": 111,
            "volume": 2551
          },
          {
            "time": 1769299200000,
            "open": 119,
            "close": 117,
            "high": 122,
            "low": 114,
            "volume": 2688
          },
          {
            "time": 1769385600000,
            "open": 121,
            "close": 126,
            "high": 129,
            "low": 118,
            "volume": 2825
          },
          {
            "time": 1769472000000,
            "open": 123,
            "close": 124,
            "high": 127,
            "low": 120,
            "volume": 2962
          },
          {
            "time": 1769558400000,
            "open": 121,
            "close": 118,
            "high": 124,
            "low": 115,
            "volume": 1299
          },
          {
            "time": 1769644800000,
            "open": 119,
            "close": 123,
            "high": 126,
            "low": 116,
            "volume": 1436
          },
          {
            "time": 1769731200000,
            "open": 116,
            "close": 116,
            "high": 119,
            "low": 113,
            "volume": 1573
          },
          {
            "time": 1769817600000,
            "open": 113,
            "close": 109,
            "high": 116,
            "low": 106,
            "volume": 1710
          },
          {
            "time": 1769904000000,
            "open": 112,
            "close": 115,
            "high": 118,
            "low": 109,
            "volume": 1847
          }
        ],
        "session": "24x7",
        "seriesStyle": "candlestick",
        "showNavigator": true,
        "showRangeSelector": true,
        "width": 640,
        "height": 440,
        "brandPosition": "bottom-right",
        "brandLogo": ""
      }
    }
  ];
  const container = document.querySelector('#chart-container');
  const elements = specs.map(({ tag, id, props }) => {
    const element = document.createElement(tag);
    element.id = id;
    Object.assign(element, props);
    element.setAttribute('aria-label', 'stock-chart example chart');
    return element;
  });
  container.replaceChildren(...elements);
  const chart = elements.at(-1);
  const onEvent = event => {
    console.log('flagClick', event.detail);
  };
  chart.addEventListener('flagClick', onEvent);
  const observer = new ResizeObserver(([entry]) => {
    const width = Math.max(160, Math.floor(entry.contentRect.width));
    elements.forEach(element => { element.width = width; });
  });
  observer.observe(container);

  // In an SPA, call this function when the view is disposed.
  function disposeChart() {
    observer.disconnect();
    chart.removeEventListener('flagClick', onEvent);
    container.replaceChildren();
  }
</script>

Usage and data

#

Build financial interfaces with range selection, Navigator, and flags.

Align date time zones and trading sessions. The example uses fictional data to demonstrate display features.

Data contract

PropertyInput format
dataChronological OHLCV records.
session24x7 or a trading session.
flagsEvents with time, text, and title.
seriesStyleHow prices are drawn.

Updating data

Assign a new array or object to the property instead of mutating values inside an array. Chart events provide selection results through event.detail. When disposing of the view, clean up ResizeObserver and event listeners registered by your app.

Feature examples

#

Try 13 interactive feature examples and inspect their code. Select “Edit in preview” to combine more options in the settings panel above.

Hollow candlesticksPRO

Follow price trends with unfilled rising candle bodies.

Interact with the chart to see results here.
View code

Area price chartPRO

Show price trends as an area.

Interact with the chart to see results here.
View code

Explore time rangesPRO

Choose a period with the range selector and Navigator.

Interact with the chart to see results here.
View code

OverviewPRO

Compare 20 examples of Overview. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

DashboardPRO

Compare 2 examples of Dashboard. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

DrawingPRO

Compare 8 examples of Drawing. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

Highcharts GalleryPRO

Compare 14 examples of Highcharts Gallery. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

NavigationPRO

Compare 7 examples of Navigation. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

OscillatorsPRO

Compare 15 examples of Oscillators. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

OverlaysPRO

Compare 18 examples of Overlays. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

StylesPRO

Compare 16 examples of Styles. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

WorkspacePRO

Compare 4 examples of Workspace. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

Streaming · Add and update live dataPRO

Compare 1 examples of Add and update live data. Buttons and options update both the live result and source code.

Interact with the chart to see results here.
View code

API reference

#

The full public API for sy-stock-chart. Pass objects and arrays as JavaScript properties. Select a name to view usage code and type definitions.

Key properties

Attribute / PropertyType / DefaultDescription
numberDefault: 760Chart width in pixels. Update with ResizeObserver when the container changes.
numberDefault: 420Chart height in pixels.
brandLogostringDefault: undefinedThe default is the Syidax logo. With the Pro chart.branding entitlement, use none or a PNG, JPEG, or WebP data URL.
brandPosition'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'Default: 'bottom-right'The corner where the logo is anchored. Applies equally to Community and Pro, on screen and in image exports.
StockDataInputDefault: undefinedChronological OHLCV records.
'24x7' | 'us-equity' | StockSessionInputDefault: '24x7'24x7 or a trading session.
showNavigatorbooleanDefault: falseSet as an HTML attribute or JavaScript property. type: boolean.
showRangeSelectorbooleanDefault: falseSet as an HTML attribute or JavaScript property. type: boolean.
StockResolutionDefault: '1d'Tape resolution: `1d` raw / `1w` / `1M` calendar roll-ups.
seriesStyleStockSeriesStyle | DerivedStockStyleDefault: 'candlestick'How prices are drawn.
upColorstringDefault: '#16a34a'Up/down candle colours (close ≥ open → up).
downColorstringDefault: '#dc2626'Set as an HTML attribute or JavaScript property. type: string.
booleanDefault: trueSet as an HTML attribute or JavaScript property. type: boolean.
showLegendbooleanDefault: trueSet as an HTML attribute or JavaScript property. type: boolean.
ReadonlyArray<StockFlagInput>Default: undefinedEvents with time, text, and title.
showToolbarbooleanDefault: falseSet as an HTML attribute or JavaScript property. type: boolean.
chartTitlestringDefault: undefinedThe title inside the chart. Explain the data's unit and meaning alongside it.
chartSubtitlestringDefault: undefinedThe subtitle inside the chart.
Other properties 24
Attribute / PropertyType / DefaultDescription
visibleFromnumberDefault: undefinedVisible bar range (indices; defaults to everything).
visibleTonumberDefault: undefinedSet as an HTML attribute or JavaScript property. type: number.
dataGroupingstringDefault: 'auto'View-density grouping: `auto` (default) / `off` / a forced factor.
historyLoader(oldestTime: number, count: number) => Promise<ReadonlyArray<StockBarInput>> | ReadonlyArray<StockBarInput>Default: undefinedPass as a JavaScript property. type: (oldestTime: number, count: number) => Promise<ReadonlyArray<StockBarInput>> | ReadonlyArray<StockBarInput>.
historyThresholdnumberDefault: 30Bars from the head that trigger a history load (default 30).
ReadonlyArray<PaneSpecInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<PaneSpecInput>.
brickSizenumberDefault: undefinedRenko brick size in price units (default auto — close range/50, nice).
reversalPctnumberDefault: 4Kagi reversal, percent (default 4).
boxSizenumberDefault: undefinedPoint & Figure box size (default auto) and reversal boxes (default 3).
reversalBoxesnumberDefault: 3Set as an HTML attribute or JavaScript property. type: number.
lineBreakCountnumberDefault: 3Line Break lookback (default 3-line break).
baselineValuenumberDefault: undefinedBaseline anchor for `series-style="baseline"` (default first visible close).
lineColorstringDefault: '#2563eb'Line/area/hilo ink.
priceScaleModestringDefault: 'linear'Right-scale space: `linear` (default) / `log` / `percent` / `indexed`.
referenceLinesstringDefault: undefinedReference lines, comma list: `current,previous-close,high,low,bid,ask`.
numberDefault: undefinedQuotes for the `bid`/`ask` reference lines.
numberDefault: undefinedSet as an HTML attribute or JavaScript property. type: number.
compareSymbolsReadonlyArray<CompareSymbolInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<CompareSymbolInput>.
ReadonlyArray<StockIndicatorInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<StockIndicatorInput>.
ReadonlyArray<StockDrawingInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<StockDrawingInput>.
exportScalenumberDefault: 2Set as an HTML attribute or JavaScript property. type: number.
stringDefault: 'en-US'Set as an HTML attribute or JavaScript property. type: string.
ReadonlyArray<StockTradeInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<StockTradeInput>.
ReadonlyArray<StockPositionInput>Default: undefinedPass as a JavaScript property. type: ReadonlyArray<StockPositionInput>.
Events 19
EventsDetail typeDescription
{ bars: number; visibleBars: number; renderMs: number }Emits rendering results in detail when chart drawing completes.
{ panes: Array<{ id: string; weight: number }> }The pane stack changed (drag, add/remove/reorder, weight set).
{ from: number; to: number }The visible window changed (navigator/scrollbar; fires on release).
{ range: StockRangeKey; from: number; to: number }A range button was applied.
{ resolution: StockResolution }The resolution changed.
{ oldestTime: number; count: number }A history load started / finished.
{ added: number; exhausted: boolean }CustomEvent.detail type: { added: number; exhausted: boolean }. Event names are case-sensitive.
{ index: number; time: number; price: number } | nullThe crosshair moved to a bar (`null` on leave).
{ ids: string[] }The compare set changed.
{ id: string; time: number; text: string; title?: string }A flag was clicked / hovered (`null` on hover leave).
{ id: string; time: number; text: string; title?: string } | nullCustomEvent.detail type: { id: string; time: number; text: string; title?: string } | null. Event names are case-sensitive.
{ ids: string[] }The indicator set changed (add/remove/update).
{ count: number; canUndo: boolean; canRedo: boolean }The drawing document changed (add/update/move/remove/undo/redo/load).
{ id: string } | nullA drawing was selected (`null` on deselect).
{ tool: string | null }The active placement tool changed (`null` = the cursor).
{ appended: boolean; time: number; close: number; bars: number }A live tick was applied (`appended` = a new bar opened).
{ id: string; time: number; side: 'buy' | 'sell'; price: number; quantity?: number }A trade marker was clicked.
{ applied: string[] }A template was imported (`applied` names the fields that landed).
{ format: string; filename: string }An export finished (`png` | `svg` | `csv`).
Methods 45

Stencil methods return Promises. Use await within an async function to read the result.

Method / ArgumentsReturn typeDescription
symbol: CompareSymbolInputPromise<void>Add a compare overlay (duplicate ids replace).
id: stringPromise<void>Remove a compare overlay by id.
spec: StockIndicatorInputPromise<StockIndicatorInput>Add an indicator instance (an explicit duplicate id replaces). A missing id is minted HERE and persisted into the spec, so later removals never re-number method-added instances.
id: stringPromise<void>Remove an indicator by resolved id (its synthesized pane goes with it).
id: string, params: Record<string, number | string>Promise<void>Merge params into an instance (by resolved id).
Promise<Array<{ id: string; kind: string; params: Record<string, number>; linkedTo: string; paneId: string | null; label: string; }>>Resolved indicator list (serialisable — no definition objects).
definition: IndicatorDefinitionPromise<{ ok: boolean; errors: string[] }>An asynchronous method. Check the argument and return types below.
kind: stringPromise<{ removed: boolean }>Remove a definition; live instances of the kind resolve away.
Promise<string[]>Registered indicator kinds (built-ins + custom), sorted.
id: stringPromise<Record<string, Array<number | null>> | null>Computed columns for one instance over the current render tape.
input: StockDrawingInputPromise<StockDrawing | null>Add a drawing (data-coordinate anchors); returns it with the minted id.
id: string, patch: Partial<Omit<StockDrawing, 'id'>>Promise<void>Merge a patch (anchors/style/meta/visible/locked) into a drawing.
id: string, deltaTime: number, deltaPrice: numberPromise<void>Translate a drawing by data-space deltas (locked drawings hold).
id: stringPromise<void>An asynchronous method. Check the argument and return types below.
Promise<void>An asynchronous method. Check the argument and return types below.
Promise<{ count: number; canUndo: boolean; canRedo: boolean }>An asynchronous method. Check the argument and return types below.
Promise<{ count: number; canUndo: boolean; canRedo: boolean }>An asynchronous method. Check the argument and return types below.
Promise<StockDrawing[]>The current document (deep-copied, serialisable).
Promise<string>Versioned JSON export of the document.
json: stringPromise<number>Restore a serialized document (undoable — it goes through the history).
id: stringPromise<Array<{ x: number; y: number }> | null>Projected css-px points for one drawing on the CURRENT render tape.
tool: string | nullPromise<void>Activate a placement tool (`null` = the select cursor).
Promise<string | null>An asynchronous method. Check the argument and return types below.
scale: number, anchorFraction?: numberPromise<{ from: number; to: number }>Zoom programmatically around an anchor fraction (default centre).
bars: numberPromise<{ from: number; to: number }>Pan programmatically by (ungrouped) bars.
data: StockDataInputPromise<void>Replace the bar set.
tick: StockTickInputPromise<{ appended: boolean; time: number } | null>An asynchronous method. Check the argument and return types below.
ticks: ReadonlyArray<StockTickInput>Promise<{ appended: boolean; time: number } | null>Batch ticks in ONE repaint (returns the last applied result).
Promise<string>An asynchronous method. Check the argument and return types below.
json: stringPromise<{ ok: boolean; applied: string[] }>Apply a template (per-field whitelist; drawings land undoably).
Promise<string | null>The composed standalone SVG snapshot (canvas raster + SVG chrome + the brand).
Promise<string>The tape as a CSV table (ISO time, OHLC, volume).
Promise<void>Download the composed snapshot as a PNG at `export-scale`. The grant is confirmed again after the rasterisation await: one lost (or changed) meanwhile rejects with the §4.1 `stale` refusal — no download, no `exported`.
Promise<void>Download the composed snapshot as an SVG file (composed and saved in one turn, under a confirmed grant).
Promise<void>Download the tape as a CSV file (under a confirmed grant; getCSV stays the ungated read).
Promise<void>Print view with the inlined snapshot (the facade `print` mirror), opened under a confirmed grant.
Promise<{ bars: number; from: number; to: number }>Normalised bar count + visible range (diagnostics/tooling).
Promise<{ panes: Array<{ id: string; top: number; height: number }> }>Current pane rects (layout-local px).
pane: PaneSpecInput, at?: numberPromise<void>Append a pane (default at the bottom).
id: stringPromise<void>Remove a pane by id (the last pane stays).
id: string, to: numberPromise<void>Move a pane to a new stack position.
id: string, weight: numberPromise<void>Set a pane's weight directly.
count?: numberPromise<number>Pull older bars through `historyLoader` and keep the view anchored. chart.stock: when the grant ends (or changes) while the loader runs, nothing merges into the frozen tape and the call rejects with the §4.1 `stale` refusal. The licenseFeatureRefused event (code `stale`, method `loadOlderHistory`) is dispatched FIRST; the request then still ends with `historyLoaded { added: 0, exhausted: false }` so a loading state the app shows for historyRequested clears.
range: StockRangeKeyPromise<{ from: number; to: number }>Apply a range button: window the CURRENT tape by calendar maths.
resolution: StockResolutionPromise<void>Switch the tape resolution (resets the window — indices change).