4
votes

Possible duplicate of Unsolved highcharts datalabel dynamic rotation as column height

The Fiddle for a sample column chart : http://jsfiddle.net/Yrygy/266/

There are some very large columns, and one very small column. I want to show white labels vertically rotated to -90 degrees in the large columns, and for smaller columns, I want to display dark gray labels on the top of the column, with 0 degree rotation.

After some messing up, I have achieved this : http://jsfiddle.net/Yrygy/267/ I can change the color of the label based on the value in the formatter function, but using global variables to get the align and rotation right are not working.

Any help in this regard would be very helpful. I cannot use the solutions suggested in the duplicate question, as I need to keep the Y axis uniform and cannot set MinPointLength.

Final Code:

var GlobalRotation = -90;
var GlobalAlign = 'right';
var X;
var Y;
$(function () {
 $('#container').highcharts({
    chart: {
        type: 'column',
        height: 700
    },
    xAxis: {
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    },
    plotOptions: {
        column: {
            stacking: 'normal',
            pointPadding: 0,
            groupPadding: 0.2,
            dataLabels: {
                enabled: true,
                inside: false,
                style: {
                    fontWeight: 'bold'
                },
                formatter: function() {
                    var max = this.series.yAxis.max,
                        color =  this.y / max < 0.05 ? 'black' : 'white';
                        //GlobalRotation = this.y / max < 0.05 ? 0 : -90;
                        //GlobalAlign = this.y / max < 0.05 ? 'left' : 'right';
                        //X = this.y / max < 0.05 ? 4 : 4;
                        //Y = this.y / max < 0.05 ? 0 : 5;
                    return '<span style="color: ' + color + '">' + this.y + ' </span>';   
                },
                verticalAlign: "top",
                rotation : GlobalRotation,
                align: GlobalAlign
            }
        }
    },

    series: [{
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 2.33]
    }]
    });

});
1

1 Answers

5
votes

You can change Highcharts.Series.prototype.drawDataLabels, the function to draw the dataLabels:

Highcharts.Series.prototype.drawDataLabels = (function (func) {
    return function () {
        func.apply(this, arguments);
        if (this.options.dataLabels.enabled || this._hasPointLabels) realignLabels(this);
    };
}(Highcharts.Series.prototype.drawDataLabels));

realignLabels would be the function to check for the shorter columns, and in it change the rotation, x and y of that specific dataLabel:

function realignLabels(serie) {

    $.each(serie.points, function (j, point) {
        if (!point.dataLabel) return true;

        var max = serie.yAxis.max,
            labely = point.dataLabel.attr('y'),
            labelx = point.dataLabel.attr('x');

            if (point.y / max < 0.05) {
                point.dataLabel.attr({
                    y: labely - 20,
                    x: labelx + 5,
                    rotation: 0
                });
            }
    });
};

http://jsfiddle.net/Yrygy/270/