Pranay Binju
Pranay Binju

Reputation: 621

Disable dataLabel if its width is more than height of its bar in highCharts

I have created a chart using HighCharts and I want to disable any dataLabel if its width is more than height of its bar(bar cannot accomodate the dataLabel). I set the property 'enabled : false' of dataLabel of particular points but the effect is not being reflected in the chart.Here is the image of properties where 'enabled' is false for one of the points

Here is the image of chart where points with y :- 10700 , 20300 and 20000 should have been disabled

<html>

<body>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script>

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="min-width: 100px; max-width: 400px; height: 400px; margin: 0 auto"></div>


<script language="javascript">
         
var pointSelected = {};
var pointHovered = {};
//Highcharts.chart('container', 

 var chartObject = {
    chart: {
        type: 'bar',

        events : {

                    render : function(){

                                var ch = this;
                                var series = this.series;

                                ch.series.forEach(function(s){

                                        s.points.forEach(function(point){

                                                 var barHeight = point.graphic.element.height.animVal.value;
                                                 var dataLabelWidth = point.dataLabel.width;
                                                 var plotBoxWidth = ch.plotBox.width;
                                                console.log(plotBoxWidth);
                                                  if(barHeight + dataLabelWidth < plotBoxWidth)  {

                                                      //  console.log(barHeight + dataLabelWidth);
                                                       // console.log("point will lie inside");

                                                  }
                                                  //else{

                                                  if(dataLabelWidth > barHeight){

                                                       //USING JQUERY IT CAN BE DONE BUT I WANT TO AVOID JQUERY AS MUCH AS POSSIBLE $(point.dataLabel.element).fadeOut("fast");
                                                             point.dataLabel.alignOptions.enabled = false; //THIS IS WHERE I'M DISABLING POINT
                                                                console.log(point)
                                                               // point.update({dataLabels : {enabled : false}});
                                                        //ch.options.plotOptions.series.dataLabels.enabled = false;
        

                                                  }
                                               
                                               
                                                if(barHeight + dataLabelWidth > plotBoxWidth){

                                                    //   console.log(barHeight + dataLabelWidth);
                                                        var diff = barHeight + dataLabelWidth - plotBoxWidth;
                                                      //  console.log(diff);
                                                       //  var x = point.dataLabel.translateX;
                                                       // var y = point.dataLabel.translateY;
                                                     //   console.log(x);
                                                     //   console.log(point);
                                                    //// diff +=15;
                                                         var diff2 = barHeight - dataLabelWidth;
                                                        // console.log("diff2" + diff2);
                                                        point.dataLabel.translate(  diff2 , point.dataLabel.alignAttr.y );
                                                     //    console.log(   point.dataLabel.text);
                                                     //point.dataLabel.stork("black");
                                                        // point.dataLabel.text.styles.fill = "black";
                                                       var elem =   $(point.dataLabel.element).children();
                                                       $(elem).eq(0).css("fill" , "black");
                                                 
                                                       // console.log(elem);
                                                         // $(textElem).attr("style" , "fill : black");
                                                         // console.log(textElem);
                                                      //   $(point.dataLabel.element.innerHTML).eq(0).children().eq(0).text();
                                                          //  console.log("point will lie outside");
                                                        }
                                                        
                                             //     }




                                        })

                                })
                                console.log(this);


                    }



        }
        
    },
    title: {
        text: 'Historic World Population by Region'
    },
    subtitle: {
        text: 'Source: <a href="https://en.wikipedia.org/wiki/World_population">Wikipedia.org</a>'
    },
    xAxis: {
        categories: ['Africa', 'America', 'Asia', 'Europe', 'Oceania'],
        title: {
            text: null
        }
    },
    yAxis: {
        min: 0,
        title: {
            text: 'Population (millions)',
            align: 'high'
        }
    },
    tooltip: {
       
       formatter : function(){
       
           return '<b>' +this.series.name + '<br/>' +this.x + '<br/>' + this.y+ '000000</b>'
       
       }
       
       },
    plotOptions: {
              series : {

                    allowPointSelect : true,
                    dataLabels: {
                                    enabled : true,
                                    color : "blue",
                                    crop : true,
                                    overflow:  "none"
                                    

                                    },
                                  
            point:{

                    events : {
                                select :function() {

                                        //get the selected object
                                        pointSelected.categories = this.category;
                                        pointSelected.y = this.y;
                                       console.log(this);
                                        
                                      
                                       
                                        changeOpacity(pointSelected);
                                    
                                },
                                mouseOver : function(){

                                        //get the hovered object
                                        pointHovered.categories = this.category;
                                          pointHovered.y = this.y;

                                       
                                         changeOpacityOnHover(pointHovered);


                                }, 
                                mouseOut : function(){

                                        //event handler when mouse moves out
                                        changeOpacityOnOut(pointHovered);


                                }

                    }

            }
                    

            

            
           

             }
       
    },
    legend: {
        align: 'right',
        verticalAlign: 'top',
        layout: 'vertical',
        x: -150,
        y: 100,
        },
    credits: {
        enabled: false
    },
    series: [{
        name: 'Year 1800',
        data: [10700, 45000, 45000, 20300, 20000],
        zones : [{value : 100  , color : 'orange'} , {value : 500  , color : 'black'} , { color : 'blue'}]
    }]
}


//debugger
var barChart = new Highcharts.chart('container', chartObject); 


//function on mouseOver
function changeOpacityOnHover(pointHovered){

    //get the current chart object
    var chart = $("#container").highcharts();
    //get the points and check each point whether it is the hovered one    
    chart.series.forEach(function(obj){

        obj.data.forEach(function(datum){

                    //if hovered one then get its graphic element(rect) and change its opacity to 1
                   if(datum.category == pointHovered.categories && datum.y == pointHovered.y ){

//                            console.log(datum)   ; 

  //                          console.log(datum.graphic.element);

                            var tag = datum.graphic.element;
                            var x = $(tag).attr("x");
//                            console.log(x);
                            $(tag).css("opacity" , "1");
                           
                   }
        });

    })



}

function changeOpacityOnOut(pointHovered){

    //get the current chart object
     var chart = $("#container").highcharts();

     //get the points and check each point whether it is the hovered one from which mouse is over   
    chart.series.forEach(function(obj){
        obj.data.forEach(function(datum){
                    //get its graphic element(rect) 
                   if(datum.category == pointHovered.categories && datum.y == pointHovered.y ){

                         //   console.log(datum)   ; 

                           // console.log(datum.graphic.element);

                            var tag = datum.graphic.element;
                            var x = $(tag).attr("x");
                           // console.log(x);
                            
                            //if the current point(hovered) is selected one OR no point is yet selected , opacity will be 1
                            if((pointHovered.categories == pointSelected.categories && pointHovered.y== pointSelected.y) || Object.keys(pointSelected).length == 0 )
                            {

                                    $(tag).css("opacity" , "1");
                     
                            }
                            //else change opacity to 0.1
                            else{

                                    $(tag).css("opacity" , "0.1");
                     
                            }
                            

                   }
                 
        });

    })






}


// if point is selected
function changeOpacity(pointSelected){

    //get the current chart object
    var chart = $("#container").highcharts();
    
    //get the selected point by comparing each point to pointSelected
    chart.series.forEach(function(obj){

        obj.data.forEach(function(datum){

                    // if current point is selected point then change opacity to 1 and its color to the color of its rect tag fill attribute
                   if(datum.category == pointSelected.categories && datum.y == pointSelected.y){

                           console.log(datum)   ; 

                           // console.log(datum.graphic.element);

                            var tag = datum.graphic.element;
                            //var xVal =   datum.graphic.element.x.animVal.value;
                            //var yVal =   datum.graphic.element.y.animVal.value
                            //console.log(xVal);
                            //console.log(yVal);
                                
                       
                            var x = $(tag).attr("x");
                           //console.log(x);
                          // var x2 = xVal -1;
                           // console.log(datum.dataLabel.translate(xVal , yVal - 1));
                            //console.log("after");
                      // console.log(x2);
                            //console.log(yVal-1);
                            
                                       
                            $(tag).css("opacity" , "1");
                            var color = $(tag).attr("fill");
                            $(tag).css("fill" , color);
                           // console.log(color + "when clicked");
                            

                   }
                   //else let its opacity be 0.1
                   else{

                        var tag = datum.graphic.element;
                        $(tag).css("opacity" , "0.1");

                       

                         }

            
        });

    })


}
</script>






</body>

    
</html>

I have solved the problem using jQuery but if it can be done simply by setting property that will be great. Also , why the effect is not being reflected if the property is set??

Thanks.

Upvotes: 0

Views: 848

Answers (1)

Paweł Fus
Paweł Fus

Reputation: 45079

It should work with your configuration, this is how dataLabels should be configured:

plotOptions: {
    bar: {
    dataLabels: {
      enabled: true,
      crop: true,
      overflow: 'none',
      // inside: true // by default it's outside the bar
    }
  }
},

Demo: http://jsfiddle.net/pbjpr47t/

Upvotes: 1

Related Questions