absessive
absessive

Reputation: 1171

How to position the dataLabel for highcharts on the same side of the x-axis?

I have a column chart with positive and negative values. Using the default dataLabels, keeps the label at the end of the column, which isn't ideal for negative values, as it goes below the x axis.

$(function () {
$('#container').highcharts({

    chart: {
        type: 'column',
        height: 200,
        borderColor: '#ddd'
    },

    title: {
        text: ''
    },
    legend: {
        padding: 0,
        margin: 5
    },
    credits: {
        enabled: true
    },
    tooltip: {
        enabled: false
    },
    plotOptions: {
        column: {
            dataLabels: {
                enabled: true,
                crop: false,
                overflow: 'none'
            }
        }
    },
    colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE', '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92'],
    loading: {
        labelStyle: {
            top: '35%',
            fontSize: "2em"
        }
    },
    xAxis: {
        categories: ["7/12", "7/13", "7/14", "7/15", "7/16"]
    },
    series: [{
        "name": "Odometer",
        "data": [{
            "y": 94.98
        }, {
            "y": 182.96
        }, {
            "y": -160.97
        }, {
            "y": -18.00
        }, {
            "y": 117.97
        }]
    }]
});});

Example: http://jsfiddle.net/absessive/NKXRk/54/

Upvotes: 0

Views: 2098

Answers (2)

Grzegorz Blachliński
Grzegorz Blachliński

Reputation: 5222

You can change a little bit Highcharts.seriesTypes.column.prototype.alignDataLabel function, so it will not have functionality of aligning the dataLabel below your column if its value is smaller than 0.

Here you can find code that may help you:

      H.seriesTypes.column.prototype.alignDataLabel = function(point, dataLabel, options, alignTo, isNew) {
    var inverted = this.chart.inverted,
      pick = H.pick,
      Series = H.Series,
      series = point.series,
      merge = H.merge,
      dlBox = point.dlBox || point.shapeArgs, // data label box for alignment
      below = false,
      inside = pick(options.inside, !!this.options.stacking), // draw it inside the box?
      overshoot;

    // Align to the column itself, or the top of it
    if (dlBox) { // Area range uses this method but not alignTo
      alignTo = merge(dlBox);

      if (alignTo.y < 0) {
        alignTo.height += alignTo.y;
        alignTo.y = 0;
      }
      overshoot = alignTo.y + alignTo.height - series.yAxis.len;
      if (overshoot > 0) {
        alignTo.height -= overshoot;
      }

      if (inverted) {
        alignTo = {
          x: series.yAxis.len - alignTo.y - alignTo.height,
          y: series.xAxis.len - alignTo.x - alignTo.width,
          width: alignTo.height,
          height: alignTo.width
        };
      }

      // Compute the alignment box
      if (!inside) {
        if (inverted) {
          alignTo.x += below ? 0 : alignTo.width;
          alignTo.width = 0;
        } else {
          alignTo.y += below ? alignTo.height : 0;
          alignTo.height = 0;
        }
      }
    }
    // When alignment is undefined (typically columns and bars), display the individual
    // point below or above the point depending on the threshold
    options.align = pick(
      options.align, !inverted || inside ? 'center' : below ? 'right' : 'left'
    );
    options.verticalAlign = pick(
      options.verticalAlign,
      inverted || inside ? 'middle' : below ? 'top' : 'bottom'
    );
    // Call the parent method
    Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
  };

The only change I have made is that I have changed below parameter to false.

Here you can find an example how it can work: http://jsfiddle.net/NKXRk/59/

Best regards,

Upvotes: 0

Wilts C
Wilts C

Reputation: 1750

Add plotOptions.column.stacking as normal like this and it will work.

Upvotes: 2

Related Questions