0

I have this chart

<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 300px"></div>

var seriesOptions = [],
    seriesCounter = 0,
    names = ['MSFT', 'AAPL', 'GOOG'];

/**
 * Create the chart when all data is loaded
 * @returns {undefined}
 */
function createChart() {

    Highcharts.stockChart('container', {

       plotOptions: {
            series: {
                gapSize: 5 * 24 * 3600 * 1000,
                gapUnit: 'relative'
            }
        },

        rangeSelector: {
            selected: 5
        },

        yAxis: {
            labels: {
                formatter: function () {
                    return (this.value > 0 ? ' + ' : '') + this.value + '%';
                }
            },
            plotLines: [{
                value: 0,
                width: 2,
                color: 'silver'
            }]
        },

        plotOptions: {
            series: {
                compare: 'percent',
                showInNavigator: true
            }
        },

        tooltip: {
            pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
            valueDecimals: 2,
            split: true
        },

        series: seriesOptions
    });
}

$.each(names, function (i, name) {

    $.getJSON('https://www.highcharts.com/samples/data/' + name.toLowerCase() + '-c.json',    function (data) {

        if (i==0) {
            var first = [], last = [];
            first.push.apply(first, data.slice(0,1)[0]);
            last.push.apply(first, data.slice(0,1)[0]);
            first[0] = first[0] - 1900 * 24 * 3600 * 1000;
            last[0] =   last[0] - 130 * 24 * 3600 * 1000;
            data = [];
            data.push(first);
            data.push(last);
        }
        seriesOptions[i] = {
            name: name,
            data: data
        };

        // As we're loading the data asynchronously, we don't know what order it will arrive. So
        // we keep a counter and create the chart when all the data is loaded.
        seriesCounter += 1;

        if (seriesCounter === names.length) {
            createChart();
        }
    });
});

and as you can see there are three stocks shown. If you hover the chart with the mouse and go to the beginning you'll notice MSFT stock which has only 2 points and that's intentional. After MSFT there should be about 6 year gap, however on the chart it's shown in a few pixels.

How can I configure stockChart to show real gaps? In other words, I want to see the gap of 6 years so from 2005 till 2011 there will be empty space proportional to the whole chart?

valk
  • 9,363
  • 12
  • 59
  • 79

2 Answers2

1

What you are after is ordinal.

In an ordinal axis, the points are equally spaced in the chart regardless of the actual time or x distance between them. This means that missing data for nights or weekends will not take up space in the chart.

Setting ordinal to false, like this, will give you the gap you are after:

xAxis: {
  type: 'datetime',
  ordinal: false,
},

There are some other issues with your code, if you look in console, you are getting error 15 which states that highcharts requires data to be sorted. You get this because of how you add the series data to your MSFT series. You add both the x and the y to a single 1D array, which means highcharts tries to plot both your x and y values on the x axis.

I did a workaround that gives it the right format in this fiddle: http://jsfiddle.net/2cps91ka/91/

ewolden
  • 5,722
  • 4
  • 19
  • 29
  • the problem with ordinal is that it will show holidays and non-trading hours as a line that connects market Closes and Opens. The chart would look like a saw. Do you know maybe there's an option to combine those two? Thanks! – valk Feb 28 '18 at 12:16
  • I don't really know. If you want to both show "empty space proportional", and at the same time not show empty space proportional because you ignore holidays and weekends you will need to do some more configuring. If you are referring to that your fiddle is smoother than the one I gave, it is purely because of the scaling. You can see your fiddle is scaled from "1970-01-01" which makes the graph group per month. Whereas if you change scaling to the same date, say: "2011-02-23", they will look identical. You can easily see this by hovering over the graphs. – ewolden Feb 28 '18 at 12:37
1

The discussion in the comment section of the first answer reveals that OP wants to hide no-data periods only in some cases.

The solution here might be to set ordinal to false (as @ewolden) suggested and use breaks instead:

  xAxis: {
      breaks: [{
      breakSize: 24 * 3600 * 1000,
      from: Date.UTC(2017, 0, 6),
      to: Date.UTC(2017, 0, 9)
    }],
    ordinal: false
  },

  series: [{
    data: [
      [Date.UTC(2017, 0, 2), 6],
      [Date.UTC(2017, 0, 3), 7],
      [Date.UTC(2017, 0, 4), 3],
      [Date.UTC(2017, 0, 5), 4],
      [Date.UTC(2017, 0, 6), 1],
      [Date.UTC(2017, 0, 9), 8],
      [Date.UTC(2017, 0, 10), 9],
      [Date.UTC(2017, 6, 1), 4],
      [Date.UTC(2017, 6, 2), 5]
    ]

Example: http://jsfiddle.net/BlackLabel/ocg0dujg/

In the above demo I was able to hide the weekend (7 and 8 Jan) and maintain the space between January and July.

API reference: https://api.highcharts.com/highstock/xAxis.breaks

Kamil Kulig
  • 5,756
  • 1
  • 8
  • 12