Search code examples
javascripthighchartshighcharts-ng

How to start lines on columns in HighCharts


I have a combnined chart with groups of columns and lines. Each column corresponds to a line. I want each line to start on their respective column. Here is an example:

http://jsfiddle.net/aozdjab2/1/

Now, The number of columns is variable, so I want to calculate the pointPlacement for the lines dynamically.

What is the best way to do this? Is there a way to tell the lines to start at the columns? If not, how do I calculate the point placements? The number of lines and columns will vary, as well as the number of groups on the x-axis.

Thanks.


Because SO requires code:

    {
        type: 'line',
        name: 'Jane-line',
        data: [3, 2, 1, 3, 4],
        pointPlacement: -0.2
    },
    {
        type: 'line',
        name: 'john-line',
        data: [2, 3, 5, 7, 6],
        pointPlacement: 0 
    },
    {
        type: 'line',
        name: 'joe-line',
        data: [4, 3, 3, 9, 0],
        pointPlacement: 0.2 
    }

Solution

  • You can add new xAxis that will be related to you line series. This series will have more categories, so ticks will be thicker than in your normal axis.

    You can check, if line series has related visible column series in your chart and if yes, you can add this series to your chart.

    Here you can find custom function I wrote for this case:

    var positioningLineSeries = function(chart, event) {
        if (redraw) {
          var columnSeries = [],
            each = Highcharts.each,
            numberOfColumnSeries = 0,
            categoriesFor2Axis = [],
            i;
          each(chart.series, function(s) {
            if (s.type === 'column' && s.visible) {
              columnSeries.push(s);
            }
          });
          for (i = 0; i < chart.series.length; i++) {
            if (chart.series[i].type === 'line') {
              chart.series[i].remove(false);
              i--;
            }
          }
          numberOfColumnSeries = columnSeries.length;
          redraw = false;
          each(chart.xAxis[0].categories, function(c) {
            for (i = 0; i < numberOfColumnSeries + 2; i++) {
              categoriesFor2Axis.push(c);
            }
          });
          chart.xAxis[1].update({
            categories: categoriesFor2Axis,
            min: 0,
            max: categoriesFor2Axis.length - 1
          }, false);
    
          var newData, newLineSeries = $.extend(true, [], lineSeries);
    
          each(newLineSeries, function(s) {
            newData = [];
    
            each(columnSeries, function(cS, i) {
              if (cS.options.ID === s.columnID) {
    
                each(s.data, function(p, j) {
                  newData.push([p[0] + i + 1 + j * (numberOfColumnSeries + 1), p[1]]);
                });
                s.data = newData;
                chart.addSeries(s, false);
              }
    
            });
    
    
          });
          chart.redraw();
        } else {
          redraw = true;
        }
      };
    

    And here you can find an example how it can work: http://jsfiddle.net/aozdjab2/6/