Stock tools#

Stock Tools is a Highcharts Stock module for building a GUI that enables user interaction with the chart, such as adding annotations, technical indicators or just for zooming in or out. The module is released with Highcharts Stock 7 and won't work with previous versions.

Building the GUI is facilitated by the Stock Tools module, where your HTML elements for user interaction are automatically bound to predefined events in this module. Full list of the available bindings can be found in the API navigation.bindings.

Quick start#

To get started quickly it's recommended to use the default toolbar of the Stock Tools module. We need to load the JavaScript files in the following order.

  1. First load Highcharts Stock and the bundle with all the technical indicators for convenience.

    <script src="https://code.highcharts.com/indicators/indicators-all.js"></script>

    See the example below when you only need some specific indicators for your project. Load first the indicator.js base module and specific indicators successively. Technical indicators require the indicators/indicators.js base module. The base module includes SMA (Simple Moving Average). Find here a list of available technical indicators.

    See example below for loading specific indicators.

    <script src="https://code.highcharts.com/indicators/indicators.js"></script>
    <script src="https://code.highcharts.com/indicators/rsi.js"></script>
    <script src="https://code.highcharts.com/indicators/ema.js"></script>
    <script src="https://code.highcharts.com/indicators/macd.js"></script>
    <script src="/ .... other technical indicators ... "
  2. Load also the other modules needed by the default toolbar: Resizable panes, Annotations, Full screen, and Current Price.

    <script src="https://code.highcharts.com/modules/drag-panes.js"></script>
    <script src="https://code.highcharts.com/modules/annotations-advanced.js"></script>
    <script src="https://code.highcharts.com/modules/price-indicator.js"></script>
    <script src="https://code.highcharts.com/modules/full-screen.js"></script>
  3. It is necessary to load the Stock Tools module last, so it will pick up on all available plugins above:

    <script src="https://code.highcharts.com/modules/stock-tools.js">
  4. The build-in toolbar, needs the following CSS files:

    <link rel="stylesheet" type="text/css" href="https://code.highcharts.com/css/stocktools/gui.css">
    <link rel="stylesheet" type="text/css" href="https://code.highcharts.com/css/annotations/popup.css">
  5. Now you have loaded all required files, create a stock chart as you normally would, see the below example.

    Highcharts.stockChart('container', {
    series: [{
    type: 'ohlc',
    data: [ ... ]
    }]
    });

    And Stock Tools toolbar will show up on the left side of the chart, see the demo below.

Note: The buttons graphics of the Stock Toolbar buttons are by default loaded from the Highcharts CDN. If you want to load Stock Tools from your local package, you might also want to set the symbol properties for each of the stockTools.gui.definitions. The icons are available in the Highcharts NPM package or clone the highcharts-dist GitHub repository.

Find the icons in the /gfx/stocktools folder of this package.

Build a custom UI#

The built-in Stock Toolbar will cover most use cases and get you quickly started. The API of this module supports additionally building a custom defined user interface. Automatic binding and built-in actions for your custom HTML elements come out of the box and require minimal programming.

Binding an event to a HTML element#

HTML elements are bound to stock tools events through reverse lookup of HTML elements with a classname in the form of: highcharts-BINDINGNAME. For example a HTML button with highcharts-circle-annotation will bind the navigation.bindings.circleAnnotation events. Class name can be changed by setting navigation.bindings.circleAnnotation.className. The actual binding takes place on chart initialization, but only for HTML elements that are wrapped within another HTML element with the classname correlating the chart configuration for navigation.bindingsClassName. The wrapping classname defaults to highcharts-bindings-wrapper. Wrapping the GUI elements is made required for specifying which GUI elements need to be bound and events are delegated to the correct chart.

The code snippet below demonstrates how to disable the default toolbar, and triggers lookup of a custom GUI with the navigation.bindingsClassName.

Highcharts.stockChart('container', {
navigation: {
bindingsClassName: ‘tools-container’ // informs Stock Tools where to look for HTML elements for adding technical indicators, annotations etc.
},
stockTools: {
gui: {
enabled: false // disable the built-in toolbar
}
},
series: [{
....
}]
});

The button below is now bound to the circleAnnotation events, after it's found through the above specified classname tools-container.

<div class="tools-container">
<button class="highcharts-circle-annotation">Add Circle</button>
</div>

See this demo for binding a button to the circleAnnotation.

Dialog windows#

In applications with more advanced user interaction, additional dialog windows are likely needed. Support for building custom dialog windows is facilitated by hooking up functions to the navigation.bindings.

How to implement a custom dialog window, is best explained with an example where we change the background color of a circle annotation.

  1. First we define a dialog window in HTML. Notice the classname highcharts-popup-annotations of the outer div element. We need this classname in the navigation.events.showPopup event later on.

    Example of a dialog window with a color input field

    <div class="highcharts-popup highcharts-popup-annotations">
    <div class="highcharts-popup-wrapper">
    <label for="stroke">Color</label>
    <input type="color" name="stroke" value="rgba(0, 0, 0, 0.75)"/>
    </div>
    <button class="button">Save</button>
    </div>
  2. Hook up the functions for the events for navigation.bindings.

    navigation: {
    // Informs Stock Tools where to look for HTML elements for adding
    // technical indicators, annotations etc.
    bindingsClassName: 'tools-container',
    events: {
    // On selecting the annotation the showPopup event is fired
    showPopup: function(event) {
    var chart = this.chart;
    if (!chart.annotationsPopupContainer) {
    // Get and store the popup annotations container
    chart.annotationsPopupContainer = document
    .getElementsByClassName('highcharts-popup-annotations')[0];
    }
    // Show the popup container, but not when we add the annotation.
    if (
    event.formType === 'annotation-toolbar' &&
    !chart.activeButton
    ) {
    chart.currentAnnotation = event.annotation;
    chart.annotationsPopupContainer.style.display = 'block';
    }
    },
    closePopup: function() {
    // Hide the popup container, and reset currentAnnotation
    this.chart.annotationsPopupContainer.style.display = 'none';
    this.chart.currentAnnotation = null;
    },
    selectButton: function(event) {
    // Select button
    event.button.classList.add('active');
    // Register this is current button to indicate we're adding
    // an annotation.
    this.chart.activeButton = event.button;
    },
    deselectButton: function(event) {
    // Unselect the button
    event.button.classList.remove('active');
    // Remove info about active button:
    this.chart.activeButton = null;
    }
    }
    },
  3. Add an event listener to the "Save" button of the dialog window for saving the color to the fill of the circle annotation.

    Highcharts.stockChart('container', {
    chart: {
    events: {
    load: function() {
    // Function which saves the new background color.
    var chart = this;
    // Select the save button of the popup and assign a click event
    document.querySelectorAll('.highcharts-popup-annotations button')[0].addEventListener(
    'click',
    function() {
    var color = document.querySelectorAll(
    '.highcharts-popup-annotations input[name="stroke"]'
    )[0].value;
    // Update the circle
    chart.currentAnnotation.update({
    shapes: [{
    fill: color
    }]
    });
    // Close the container
    chart.annotationsPopupContainer.style.display = 'none';
    }
    )
    }
    }
    },
    navigation: { ... },
    ...
    });

    The above code is put together in the below demo