Rafael Couto
Rafael Couto

Reputation: 35

Highcharts problem with xAxis using multiple series

I'm fairly new to Highcharts and everything went perfectly well using the examples provided in their website. This was true until I had the idea to add two more series of data to my plot :).

I'm trying to show a plot where there's a timeseries of some meteorological data from a specific meteo station and on top of that it would be nice if I could show info on when changes in the meteo station happened, namely change of the receiver and antenna of the station.

Everything is fine if there's only one change of receiver and/or one change of antenna, however, has shown in the example below, with multiple changes the xAxis stops showing normal dates and by inspecting the code it will render only one tick at 2025.0 which is incorrect since there's no data in that time period.

(function ($) {
    $(function () {
        Highcharts.dateFormats = {
        DOY: function (timestamp) {
            var date = new Date(timestamp);
            var d= new Date(date.getFullYear(), 0, 0);
            return ('00' + Math.floor((date-d)/8.64e+7)).slice(-3);
        },
        DEC: function (timestamp) {
            var date = new Date(timestamp);
            return ((1970 + date/(365*8.64e+7)).toFixed(1))
        },
        WEEK: function (timestamp) {
            var date = new Date(timestamp);
            var dgps = new Date(1980,0,6,0,0,0);
            return  Math.floor((date-dgps)/(7*8.64e+7));
        }
    };

    // Meteo chart
    Highcharts.chart('plot', {
        chart: {
            renderTo: 'plot',
            zoomType: 'x',
            panning: true,
            panKey: 'shift',
            borderWidth: 1,
            borderColor: 'grey',
            style: {
                fontFamily: 'arial'
            },
            height: 464
        },
        title: {
            text: 'DEM3',
            align: 'left',
            x: 10
        },
        legend: {
            enabled: true,
            layout: 'horizontal',
            align: 'right',
            verticalAlign: 'top',
            width: 300,
            itemWidth: 190,
            top:70
        },
        boost: {
            useGPUTranslations: true,
            usePreAllocated: true
        },
        xAxis:
            {  type: 'datetime',
                title: {
                    enabled: true,
                    text: 'Year',
                    style: {
                        color: '#c0aa7d',
                        fontWeight: 'bold',
                        fontSize: '12px'
                    }
                },
                labels: {
                    format: '{value: %DEC}'
                },
                lineWidth: 1,
                lineColor: '#c0aa7d',
                min:  1567023200000,
                max:  1578787200000,
            },
        yAxis:[
            {
                title: {
                    text: 'Zenith Total Delay (m)',
                    style: {
                        color: '#c0aa7d',
                        fontWeight: 'bold',
                        fontSize: '12px'
                    }
                },
                lineWidth:0.5,
                top: 100,
                startOnTick: false,
                endOnTick: false,
                tickInterval: 0.05,
                minorTickInterval: 0.05,
                minorTickLength: 0,
                min: 2.0687167703582,
                max: 2.492349020252,
            }],
        plotOptions: {
            series: {
                lineWidth: 0,
                marker: {
                    radius: 2,
                    symbol: 'circle'
                },
                turboThreshold: 10000
            }
        },
        series: [ {
            id:  'Antenna0',
            name: 'Antenna Change',
            type:'line',
            color: '#35a62a',
            dashStyle: 'Solid',
            data: [
                   [1574035200000,2.068716770358151],
                   [1574035200000,2.4923490202520044]
                  ],
            yAxis: 0,
            lineWidth: 2,
            enableMouseTracking: false,
            marker: {
                radius: 0
            }
        }, {
            id:  'Receiver0',
            name: 'Receiver Change',
            type:'line',
            color: '#AE0016',
            dashStyle: 'longdash',
            data:[
                  [1574035200000, 2.0687167703582],
                  [1574035200000, 2.492349020252],
                  [null, null],
                  [1575158400000, 2.0687167703582],
                  [1575158400000, 2.492349020252],
                  [null, null],
                  [1576713600000, 2.0687167703582],
                  [1576713600000, 2.492349020252],
                 ],
            yAxis: 0,
            lineWidth: 1.5,
            enableMouseTracking: false,
            marker: {
                radius: 0
            }
        },{
            type: 'scatter',
            name: 'Zenith Total Delay (m)',
            color: '#C0B5A9',
            marker: {
                enabled: true,
                symbol: 'circle',
                radius: 1.5,
                fillColor: '#c0aa7d'
            },
            data: [               
                                [1567123200000, 2.2877],
                                [1567209600000, 2.2824],
                                [1567296000000, 2.266],
                                ...
                                [1578614400000, 2.2127],
                                [1578700800000, 2.222],
                                [1578787200000, 2.2145],
                ],
            yAxis: 0,
        }]
    });
    });
})(jQuery);

Example: https://jsfiddle.net/rgcouto/9qv2ehp7/1/

Steps to reproduce:

1 - Open as it is, and the plot will not render correctly the xAxis;

2 - Remove the second and third event from the Receiver0 series and leave only one event [i.e. array with 3 positions: 1 start, 1 end, 1 null (null is to remove connecting line to a second event)] and the xAxis will render correctly with normal dates.

I've been scratching my head all day now and yet I can't figure out what might be wrong.

Thanks in advance for any help :)

EDIT: Solved by adding an additional hidden xAxis and referencing the other 2 series to this new xAxis.

Upvotes: 3

Views: 103

Answers (1)

Sebastian Wędzel
Sebastian Wędzel

Reputation: 11633

Notice that in your console the Highcharts error #15 occurs - https://www.highcharts.com/errors/15/, which is reasonable because null breaks the ascending ordering on the xAxis.

As a solution, you can paste the same data time for the points with the null value as the previous point has:

Demo: https://jsfiddle.net/BlackLabel/m8wnv9bf/

data:[
  [1574035200000, 2.0687167703582],
  [1574035200000, 2.492349020252],
  [1574035200000, null],
  [1575158400000, 2.0687167703582],
  [1575158400000, 2.492349020252],
  [1575158400000, null],
  [1576713600000, 2.0687167703582],
  [1576713600000, 2.492349020252],
 ],

Or consider to render those lines as a xAxis plotLines, but if you want to keep the toggle functionality you will need to create an custom legend for those line:

Demo: https://jsfiddle.net/BlackLabel/ozq23a46/

  render() {
    //create the custom legend for the plotLines
    let chart = this,
      xAxis = chart.xAxis[0];

    //check if legend exists after window resize
    if(chart.customLegend) {
        chart.customLegend.destroy();
    }
    chart.customLegend = chart.renderer.label('Receiver Change', 270, 50)
      .css({})
      .attr({
        fill: 'rgba(0, 0, 0, 0.75)',
        padding: 8,
        r: 5,
        zIndex: 6,
      })
      .add();
    //add hide/show func
    chart.customLegend.element.onclick = function() {
      xAxis.plotLinesAndBands.forEach(pl => {
        if (pl.id === "RC") {
          if (!pl.svgElem.visibility || pl.svgElem.visibility === 'visible') {
            pl.svgElem.hide();
          } else {
            pl.svgElem.show();
          }
        }
      })
    }
  }

API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label

API: https://api.highcharts.com/highcharts/chart.events.render

Upvotes: 1

Related Questions