Share this

Dynamically switch between linear and log axis scale using Stock Tools GUI

Karol Kołodziej Avatar

by

4 minutes read

Dynamically switch between linear and log axis scale using Stock Tools GUI

In this article, I will show you how to add a custom logarithmic/linear Stock Tools button and how to interact with it. The custom stock tool button allows you to change the axes type from linear to logarithmic and the other way around.
Switching from logarithmic to linear scale can be useful with a particular set of data such as stock charts, as it allows be easier to interpret the chart using one of the scales.
Let’s begin with a simple chart where you can see how the charts’ appearance changes with different axis types. To demonstrate, I created an HTML button and I added an event listener to it.
When the button is clicked, we can use the axis update method to switch between the linear and logarithmic axis types. To track the changes I added the logarithmic flag.

let isLogarithmic = false;
document.getElementById('linlog').addEventListener('click', () => {
  chart.yAxis[0].update({
    type: isLogarithmic ? 'linear' : 'logarithmic'
  });
  isLogarithmic = !isLogarithmic;
});

Now let’s convert that knowledge into the Stock Tools GUI. As a starting point, we can cover that demo

The first step is to choose what kind of button to add to the GUI from the existing stackTools GUI buttons collection. Once your choice is made, select a name for the new one (lin/long switch), for this project, I named that button linLogSwitch and conveniently separated it from the other buttons by the separator.

The second step is to create the definition. Remember, that the definition name has to be the same as the button name to specify which button to add given styles and functionalities. I add to that definition a className and symbol that can be found in our library. The symbol shows the axis type which will be visible after clicking on that button.
If desired, you could use different symbols.
So far, the options looks like this:

stockTools: {
  gui: {
    buttons: ['linLogSwitch', 'separator', 'indicators', 'separator', 'simpleShapes', 'lines', 'crookedLines', 'measure', 'advanced', 'toggleAnnotations', 'separator', 'verticalLabels', 'flags', 'separator', 'zoomChange', 'fullScreen', 'typeChange', 'separator', 'currentPriceIndicator', 'saveChart'],
    definitions: {
      linLogSwitch: {
        className: ‘highcharts - lin - log -
          switch’,
        ,
        symbol: 'logarithmic.svg'
      },
    }
  }
},

A callback function is required to handle the button click event. This function must be named ‘init’. It will be defined in navigation.bindings (more here: navigation.bindings). With more complex buttons and their annotation, in some cases you might need to add other functions called start, steps and end. However, this isn’t necessary in this basic example.
The name of the property has to be (once again) the same as the button name to associate the right button. Inside it, based on the current chart state, I update the axis type using the axis update method.

When you click on the button and the scale is changed, the button’s icon is no longer valid because it shows the wrong axis type symbol. That is why you also need to update the button background image. Lastly, remove the default selection on the button.

navigation: {
  bindings: {
    linLogSwitch: {
      className: ‘highcharts - lin - log -
        switch’,
      init: function(button) {
        const chart = this.chart,
          isLogarithmic = chart.yAxis[0].logarithmic,
          axisTypeIcon = isLogarithmic ? 'logarithmic.svg' : 'linear.svg',
          iconURL = 'https://code.highcharts.com/9.2.2/gfx/stock-icons/' + axisTypeIcon;

        // Change the axis type accordingly.
        chart.yAxis[0].update({
          type: isLogarithmic ? 'linear' : 'logarithmic',
          minorTickInterval: isLogarithmic ? null : 'auto'
        }, false)
        chart.yAxis[1].update({
          type: isLogarithmic ? 'linear' : 'logarithmic',
          minorTickInterval: isLogarithmic ? null : 'auto'
        })

        // Change the button icon.
        button.firstChild.style['background-image'] = `url(${iconURL})`;

        // Deselect button after click.
        button.classList.remove('highcharts-active')
      }
    }
  }
},

In the end, here is the final demo:

Let me know your thoughts about this project, and feel free to share your experience in the comment section below.

Stay in touch

No spam, just good stuff

We're on discord. Join us for challenges, fun and whatever else we can think of
XSo MeXSo Me Dark
Linkedin So MeLinkedin So Me Dark
Facebook So MeFacebook So Me Dark
Github So MeGithub So Me Dark
Youtube So MeYoutube So Me Dark
Instagram So MeInstagram So Me Dark
Stackoverflow So MeStackoverflow So Me Dark
Discord So MeDiscord So Me Dark

Comments

  1. Ben

    |

    This looks like a really useful function! Looking forward to trying it


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.