score:3

it can be done using this approach:

  1. create a function which sort columns:
  • loop through points and group them by category (apples, oranges etc)
  • loop through each group of points and sort the group by y value
  • loop through points in each group and set a newly calculated y position using svgelement.attr method (point.graphic is an svgelement instance). do the same for point.datalabel and set a new position to point.tooltippos array (otherwise tooltip will be placed wrongly).
function sortcolumns() {
  var chart = this,
    pointsbycat = {},
    zeropixels,
    bottomypositive,
    bottomynegative,
    shapeargs;

  chart.series.foreach(function(serie) {
    serie.points.foreach(function(point, index) {

      if (pointsbycat[point.category] === undefined) {
        pointsbycat[point.category] = [];
      }

      pointsbycat[point.category].push(point);
    });
  });

  highcharts.objecteach(pointsbycat, function(points, key) {
    zeropixels = chart.yaxis[0].topixels(0) - chart.plottop;
    bottomypositive = bottomynegative = zeropixels;

    points.sort(function(a, b) {
      return b.y - a.y;
    });

    points.foreach(function(point) {
      if (point.series.visible) {
        if (point.shapeargs.y < zeropixels) {

          // positive values
          point.graphic.attr({
            y: bottomypositive - point.shapeargs.height
          });

          point.datalabel.attr({
            y: bottomypositive - point.shapeargs.height / 2 - point.datalabel.height / 2
          });

          point.tooltippos[1] = bottomypositive - point.shapeargs.height;
          bottomypositive = bottomypositive - point.shapeargs.height;
        } else {

          // negative values
          point.graphic.attr({
            y: bottomynegative
          });

          point.datalabel.attr({
            y: bottomynegative + point.shapeargs.height / 2 - point.datalabel.height / 2
          });

          point.tooltippos[1] = bottomynegative;
          bottomynegative = bottomynegative + point.shapeargs.height;
        }
      }
    });
  });
}



2) set above function as a callback to chart.events.load and chart.events.redraw events:

  chart: {
    type: 'column',
    events: {
      load: sortcolumns,
      redraw: sortcolumns
    }
  }

demo:

api reference:


Related Query

More Query from same tag