Search code examples
javascriptjqueryhighchartstreemap

HighCharts: Treemap dataLabels inconsistent on drilldown/drillup


Assume there is a treemap with 3 levels, in this case "Continent -> Country -> Causes". I want the dataLabels stay consistent when drilling down so that:

  • The label of the current level is centered and has a larger font size
  • The label of the next level is in the top left
  • The label of the level after the next is not displayed

For instance, in the beginning the current level is the Continent. There "Africa" and "Europe" etc. should be displayed in the center with a large font. The countries should be displayed in the top left each. The causes should be invisible.

When drilling down one level to the countries, "Hungary" and "France" should be displayed in the center with a large font. The causes should be displayed in the top left. The continents should be invisible. When drilling down another level to the causes, the causes should be displayed in the center, the rest should be invisible.

I am using this code to do this. See http://jsfiddle.net/h7tq7oo2/

    series: [{
        type: 'treemap',
        layoutAlgorithm: 'squarified',
        allowDrillToNode: true,
        levelIsConstant: false,
        dataLabels: {
            enabled: false
        },
        levels: [{
            level: 1,
            dataLabels: {
                enabled: true,
                style: {
                    fontSize: '20px'
                }
            },
            borderWidth: 3
        },{
            level: 2,
            dataLabels: {
                align: "left",
                verticalAlign: "top",
                enabled: true
            },
            borderWidth: 3
        }],
        data: points
    }]

Initially, everything looks ok. The labels of the first visible level (continents) are centered and big, the labels of the next level (countries) are in the top left. However, when drilling down a level to the countries the labels of the countries are centered, but small (should be big). The causes are in the top-left and small as expected. Drilling down another level to the causes looks similar: The labels are centered, but small (should be big).

This is where it gets strange: Drilling up a level to the countries again I get the result I want, but only for the one country I was looking at previously. The country I was looking at earlier is now centered and big, but all others are still small. Drilling down to another country and back up changes the font size of that one as well, the rest remains small. Drilling back up a level to the continents results in the country labels (which should be small in the top-left) being in the top-left but large, but again only for those countries I drilled down to. The rest are small and in the top-left as expected.

This looks pretty inconsistent to me, but I am not entirely sure this is a bug. What am I doing wrong?


Solution

  • Solved it like this: http://jsfiddle.net/tL3u3215/2/

      var current_level = 1;
    
      function get_current_level() {
        var rootNode = this.series[0].rootNode;
    
        if (rootNode === '') {
          current_level = 1;
        } else {
          if (rootNode.split('_').length == 2) {
            current_level = 2;
          } else if (rootNode.split('_').length >= 2) {
            current_level = 3;
          }
        }
      }
    
      var chart = $('#container').highcharts({
        chart: {
          events: {
            redraw: get_current_level
          }
        },
        xAxis: {
          events: {
            setExtremes: get_current_level
          }
        },
        yAxis: {
          events: {
            setExtremes: get_current_level
          }
        },
        series: [{
          type: 'treemap',
          layoutAlgorithm: 'squarified',
          allowDrillToNode: true,
          dataLabels: {
            enabled: false,
            formatter: function () {
              var point = this.point;
              if (current_level == point.level && current_level != 3) {
                return '<span style="font-size:20px">' + point.name + "<span>";
              } else if (current_level == point.level - 1 || current_level == 3) {
                return '<span>' + point.name + "<span>";
              } else {
                return null;
              }
            }
          },
          levelIsConstant: false,
          levels: [{
            level: 1,
            dataLabels: {
              enabled: true,
            },
            borderWidth: 3
          }, {
            level: 2,
            dataLabels: {
              align: "left",
              verticalAlign: "top",
              enabled: true
            },
            borderWidth: 3
          }],
          data: points
        }],
        subtitle: {
          text: 'Click points to drill down. Source: <a href="http://apps.who.int/gho/data/node.main.12?lang=en">WHO</a>.'
        },
        title: {
          text: 'Global Mortality Rate 2012, per 100 000 population'
        }
      });