npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sbx-react-stock-chart

v3.5.56

Published

React stock chart component with candlestick/line/area/bars rendering, indicators, drawing tools, alerts, and a runtime API.

Readme

sbx-react-stock-chart

React stock chart component with candlestick/line/area/bars rendering, indicators, drawing tools, alerts, and a runtime API.

Installation

npm i sbx-react-stock-chart

Alternative:

yarn add sbx-react-stock-chart
pnpm add sbx-react-stock-chart

Requirements

  • react 16.x
  • react-dom 16.x
  • Browser environment (window, document, requestAnimationFrame)

Quick Start

import React, { useRef, useState } from 'react';
import Chart from 'sbx-react-stock-chart';

const Feed = {
  onFeeder(symbol, cb) {
    // subscribe and call cb({ symbol, bid, ask, time, volume? })
  },
  offFeeder(symbol, cb) {
    // unsubscribe
  },
};

async function getHistory({ symbol, frame, count }) {
  return {
    data: [
      // [open, high, low, close, volume, timeSec]
      [1.081, 1.084, 1.079, 1.082, 1200, 1710000000],
      [1.082, 1.085, 1.080, 1.084, 950, 1710014400],
    ],
  };
}

export default function App() {
  const chartRef = useRef(null);
  const [assets, setAssets] = useState([
    {
      key: 'eurusd-main',
      symbol: 'EURUSD',
      digits: 5,
      timeFrame: 4 * 60 * 60,
      type: 'candle',
      indicators: {},
      drawing_tools: {},
      orders: [],
      alerts: [],
      priceLabels: [],
    },
  ]);

  return (
    <div style={{ height: 560 }}>
      <Chart
        ref={chartRef}
        assets={assets}
        feed={Feed}
        getHistory={getHistory}
        settings={{
          hideTooltips: true,
          showVolume: true,
          showStats: false,
          showPriceAlerts: true,
          autoScale: false,
          display: { contextMenu: true },
          controls: { enable: true },
        }}
        onChange={(ctx) => {
          if (ctx.event === 'change:timeFrame') {
            setAssets((prev) =>
              prev.map((a) => (a.key === ctx._id ? { ...a, timeFrame: ctx.data } : a))
            );
          }
        }}
      />
    </div>
  );
}

Component Props (Wrapper Export)

The package default export is the multi-asset wrapper component (src/Chart/chart-wrapper.jsx).

| Prop | Type | Required | Description | |---|---|---|---| | assets | Asset[] | yes | List of charts to render. Each asset is one chart tab/pane. | | feed | { onFeeder, offFeeder } | yes | Real-time quote subscribe/unsubscribe adapter. | | getHistory | (params) => Promise<{data: Candle[]}> | yes | Historical candles loader. | | settings | ChartSettings | yes (practically) | Main configuration object (UI + rendering + style). | | onChange | (ctx) => void | no | Main event callback. | | tokens | Record<string, string> | no | UI localization overrides. | | templates | { indicators?: any[] } | no | Indicator templates source for dropdown UI. | | favorites | any[] | no | Favorite indicators list (used in UI). | | containers | Array<{name, position, component, collapse?}> | no | Custom overlay widgets mounted on each chart box. | | delta_width | number | no | Right-side future space (in chart coordinates). | | timeFrame | number | no | Fallback timeframe in seconds (when not set in asset). | | type | ChartType | no | Initial chart type override. | | style | Record<string, string> | no | Custom named colors injected into chart color registry. | | serverUTCTimeOffset | number | no | Seconds offset for grid/time labels. | | mainPaneMask | {enable?: boolean, color?: string, opacity?: number} | no | Runtime main pane mask override. | | license | string | no | License key used by built-in license check. | | onMove | (ctx) => void | no | Passed through but currently not used by core logic. |

Data Contracts

Candle

type Candle = [open, high, low, close, volume, timeSec];

Asset

type Asset = {
  key: string;
  symbol: string;
  digits?: number;
  timeFrame?: number; // seconds, e.g. 60 / 300 / 14400
  type?: ChartType;
  indicators?: Record<string, any>;
  drawing_tools?: Record<string, any>;
  orders?: Array<any>;
  alerts?: Array<any>;
  priceLabels?: Array<{ price: number; color: string }>;
};

Feed

type Feed = {
  onFeeder: (symbol: string, cb: (tick: Tick) => void) => void;
  offFeeder: (symbol: string, cb: (tick: Tick) => void) => void;
};

type Tick = {
  symbol: string;
  bid: number;
  ask?: number;
  time: number; // unix sec
  volume?: number;
};

getHistory

type GetHistory = (params: {
  symbol: string;
  frame: number; // seconds
  count: number;
}) => Promise<{ data: Candle[] }>;

Full settings Reference

settings combines:

  • wrapper/UI settings (controls panel, footer, visibility, menu)
  • render engine settings (candles, grid, cursor, orders, etc.)

1) Wrapper/UI settings

| Key | Type | Description | |---|---|---| | hideTooltips | boolean | Hides tooltips in left controls. | | display.contextMenu | boolean | Enables right-click chart context menu. | | controls.enable | boolean | Enables/disables left controls bar. | | controls.visible | string[] | Controls order/visibility allowlist. | | controls.hidden | string[] | Controls denylist (removed from visible result). | | indicators.visible | string[] | Indicator systemName allowlist in indicator picker. | | indicators.hidden | string[] | Indicator denylist in indicator picker. | | indicators.templates | boolean | Enables indicator templates save/load UI block. | | drawingTools.visible | string[] | Drawing tool systemName allowlist. | | drawingTools.hidden | string[] | Drawing tool denylist. | | footer.enable | boolean | Enables bottom footer with preset periods. | | footer.components | ReactComponent[] | Extra footer right-side components. | | layout | React.CSSProperties | Applied to outer .chart-main container. |

controls.visible supported ids:

  • CHART_TYPE
  • TIME_FRAME
  • INDICATORS
  • DT_LINES
  • DT_FIBO
  • DT_POLY
  • DT_GEOMETRY
  • DT_TEXT_TOOLS
  • HR
  • ZOOM_IN
  • ZOOM_OUT
  • ZOOM_CENTER
  • SCREEN_SHOT

2) Render engine settings (all supported keys)

type ChartSettings = {
  // UI-level
  hideTooltips?: boolean;
  display?: {
    contextMenu?: boolean;
  };
  controls?: {
    enable?: boolean;
    visible?: string[];
    hidden?: string[];
  };
  indicators?: {
    visible?: string[];
    hidden?: string[];
    templates?: boolean;
  };
  drawingTools?: {
    visible?: string[];
    hidden?: string[];
  };
  footer?: {
    enable?: boolean;
    components?: Array<any>;
  };
  layout?: Record<string, any>;

  // Core render flags
  showVolume?: boolean;
  showStats?: boolean;
  showPriceAlerts?: boolean;
  autoScale?: boolean;
  animation?: boolean;
  showDeveloperLogo?: boolean;
  orderOffset?: number;

  currentPrice?: {
    visible?: {
      bid?: boolean;
      middle?: boolean;
      ask?: boolean;
    };
  };

  volume?: {
    enable?: boolean;
    colors?: { up?: string; down?: string };
  };

  candles?: {
    body?: { enable?: boolean; colors?: { up?: string; down?: string } };
    border?: { enable?: boolean; colors?: { up?: string; down?: string } };
    wick?: { enable?: boolean; colors?: { up?: string; down?: string } };
  };

  columns?: {
    body?: { enable?: boolean; colors?: { up?: string; down?: string } };
    border?: { enable?: boolean; colors?: { up?: string; down?: string } };
    wick?: { enable?: boolean; colors?: { up?: string; down?: string } };
  };

  heiken?: {
    body?: { enable?: boolean; colors?: { up?: string; down?: string } };
    border?: { enable?: boolean; colors?: { up?: string; down?: string } };
    wick?: { enable?: boolean; colors?: { up?: string; down?: string } };
  };

  line?: {
    stroke?: { enable?: boolean; color?: string; width?: number };
    area?: { enable?: boolean; color?: string; opacity?: number };
  };

  baseline?: {
    stroke?: {
      enable?: boolean;
      width?: number;
      colors?: { up?: string; down?: string };
    };
    base?: {
      color?: string;
      width?: number;
      opacity?: number;
    };
    area?: {
      enable?: boolean;
      opacity?: number;
      colors?: { up?: string; down?: string };
    };
  };

  bars?: {
    width?: number;
    openEnable?: boolean;
    colors?: { up?: string; down?: string };
  };

  steps_line?: {
    width?: number;
    color?: string;
    openEnable?: boolean; // supported in settings editor
  };

  high_low?: {
    body?: { enable?: boolean; color?: string };
    border?: { enable?: boolean; color?: string };
  };

  grid?: {
    line?: {
      enable?: boolean;
      color?: string;
      width?: number;
      opacity?: number;
    };
    text?: {
      enable?: boolean;
      color?: string;
    };
  };

  mainPaneMask?: {
    enable?: boolean;
    color?: string;
    opacity?: number; // 0..1
  };

  orders?: {
    line?: {
      enable?: boolean;
      color?: string;
      width?: number;
      opacity?: number;
    };
    text?: {
      enable?: boolean;
      color?: string;
    };
    badge?: {
      borderColor?: string;
      backgroundColor?: string;
    };
  };

  cursor?: {
    line?: {
      color?: string;
      width?: number;
      opacity?: number;
      dashed?: boolean;
      dashInterval?: number;
    };
    badge?: {
      borderColor?: string;
      backgroundColor?: string;
    };
  };

  offset?: {
    top?: number;
    bottom?: number;
  };

  assetLabel?: {
    fill?: string;
  };
};

Default Engine Settings (from source)

This is the default core settings object from src/Chart/core/Main.js before merging your props.settings:

{
  showVolume: false,
  showStats: false,
  showPriceAlerts: false,
  autoScale: false,
  animation: true,
  orderOffset: 0,
  currentPrice: { visible: { bid: true, middle: false, ask: false } },
  volume: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
  candles: {
    body: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
    border: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
    wick: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
  },
  columns: {
    body: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
    border: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
    wick: { enable: true, colors: { up: '#26b276', down: '#f73e4a' } },
  },
  heiken: {
    body: { enable: true, colors: { up: '#57a1d0', down: '#f73e4a' } },
    border: { enable: true, colors: { up: '#57a1d0', down: '#f73e4a' } },
    wick: { enable: true, colors: { up: '#57a1d0', down: '#f73e4a' } },
  },
  line: {
    stroke: { enable: true, color: '#2f3342', width: 2 },
    area: { enable: true, color: '#57a1d0', opacity: 0.1 },
  },
  baseline: {
    stroke: { enable: true, width: 2, colors: { up: '#26b276', down: '#f73e4a' } },
    base: { color: '#1f222c', width: 1, opacity: 0.5 },
    area: { enable: true, opacity: 0.12, colors: { up: '#26b276', down: '#f73e4a' } },
  },
  bars: { width: 4, openEnable: true, colors: { up: '#26b276', down: '#f73e4a' } },
  steps_line: { width: 4, color: '#2862ff' },
  high_low: {
    body: { enable: true, color: '#2862ff' },
    border: { enable: true, color: '#2862ff' },
  },
  grid: {
    line: { enable: true, color: '#1f222c', width: 1, opacity: 0.2 },
    text: { enable: true, color: '#2f3342' },
  },
  mainPaneMask: { enable: true, color: '#ffffff', opacity: 1 },
  orders: {
    line: { enable: true, color: '#1f222c', width: 1, opacity: 0.2 },
    text: { enable: true, color: '#2f3342' },
    badge: { borderColor: '#c9c9c9', backgroundColor: '#c9c9c9' },
  },
  cursor: {
    line: { color: '#1f222c', width: 1, opacity: 0.8, dashed: true, dashInterval: 8 },
    badge: { borderColor: '#c9c9c9', backgroundColor: '#c9c9c9' },
  },
  offset: { top: 10, bottom: 10 },
  assetLabel: { fill: 'rgba(0, 0, 0, 0.3)' },
}

Runtime API (chart.api)

const wrapper = chartRef.current;
const key = wrapper.state.activeChart;
const api = wrapper[`chart-${key}`].api;

Methods

  • setSettings(obj, event?)
  • getSettings(path)
  • setColors(obj)
  • setNewCandle({ frame, candle })
  • _setNewCandle({ frame, bid, volume?, time })
  • setNewQuote(q?)
  • changeType(value)
  • changeVerticalZoom(value)
  • panVerticalByPixels(deltaPx)
  • getIndicators()
  • getIndicatorByKey(key)
  • addIndicator(name, data)
  • removeIndicator(name)
  • removeIndicatorsAll()
  • hideIndicator(name)
  • initDrawingTools(data)
  • getDrawingTools()
  • addDrawingTools(data)
  • addText(data?)
  • updateText(key, patch)
  • removeText(key)
  • removeDrawingTools(data)
  • removeDrawingToolsAll()
  • setCount(count)
  • setTimeline(time, count?)
  • stopEvent()
  • startEvent()
  • addStopLoss()
  • addTakeProfit()
  • reloadChart(asset, digits, options?)
  • zoomChart(val)
  • goToTime({ time })
  • setCenter()
  • changeSymbol(asset)
  • addOpenPositions(positions)
  • switchChart(type='candle')
  • setTime(time)
  • drawArrow(type)
  • toggleCrossTarget()
  • panByCandles(delta)
  • panToHistory(step=1)
  • panToLatest(step=1)

Main onChange Events

  • chart:initial
  • chart:activeChange
  • chart:contextMenu
  • chart:openOrder
  • chart:priceAlerts:open
  • chart:priceAlerts:remove
  • change:timeFrame
  • change:count
  • change:type
  • change:settings
  • change:indicators
  • favorites:add
  • favorites:delete

Chart Type Values

  • candle
  • line
  • area
  • bars
  • heiken_ashi
  • high_low
  • columns
  • line_step
  • baseline

Local Development

npm run dev
npm run build
npm run build_package

Authors

  • Viktor Semenov
  • Vladislav Fisher

Copyright (c) 2017-2026 ScaleTrade & AlfaLabs Group LLC