格式化Google图表TreeMap节点

时间:2018-06-28 08:39:05

标签: google-visualization

我已经为数据创建了一个漂亮的Treemap,它已经可以正常工作了,而且我设法将值附加到名称中,但是效果可能会好得多。

Google Analytics(分析)中可用的树图具有格式非常不同的节点,包括值和子值。有没有一种方法可以利用我们可用的图表来格式化为每个节点渲染的html块?

enter image description here

1 个答案:

答案 0 :(得分:2)

使用标准配置选项您无能为力,
更改标签的文字样式

但是,您可以手动更改现有的图表或向图表添加自己的元素,
一旦'ready'事件触发...

但是如果您要移动/更改原始标签,
它将在悬停或其他活动时恢复为原始样式/位置
必须使用MutationObserver覆盖

有关添加其他标签的示例,请参见以下工作片段...

添加了每个位置的子级数,以及一个静态标签->'Children'
并将标签移到左上角,如提供的图片

google.charts.load('current', {
  packages: ['treemap']
}).then(function () {
  var data = google.visualization.arrayToDataTable([
    ['Location', 'Parent', 'Market trade volume (size)', 'Market increase/decrease (color)'],
    ['Global', null, 0, 0],
    ['America', 'Global', 0, 0],
    ['Europe', 'Global', 30, 0],
    ['Asia', 'Global', 10, 0],
    ['Australia', 'Global', 40, 0],
    ['Africa', 'Global', 30, 0],
    [{ v: 'USA', f: 'United States of America' }, 'America', 20, 0],
    ['Mexico', 'America', 24, 12],
    ['Canada', 'America', 16, -23],
    ['Ontario', 'Canada', 12, -9],
    ['Alberta', 'Canada', 24, 13],
    ['UK', 'Europe', 21, -5],
    [{ v: '123', f: 'London' }, 'UK', 21, -5],
    [{ v: '456', f: 'London' }, 'Ontario', 21, -5],
    ['Ohio', 'USA', 12, 3],
    ['Rhode Island', 'USA', 24, 4]
  ]);

  var container = document.getElementById('chart_div');
  var tree = new google.visualization.TreeMap(container);
  var newLabelCoords = {x: 8, y: 16};

  google.visualization.events.addListener(tree, 'ready', addChildLabels);
  google.visualization.events.addListener(tree, 'select', addChildLabels);

  var observer = new MutationObserver(moveOriginalLabels);
  observer.observe(container, {
    childList: true,
    subtree: true
  });

  // find / move original labels
  function moveOriginalLabels() {
    Array.prototype.forEach.call(container.getElementsByTagName('text'), function(text) {
      var bounds = text.getBBox();
      var rect = text.parentNode.getElementsByTagName('rect')[0];
      if ((rect.getAttribute('fill') !== '#cccccc') && (text.getAttribute('text-anchor') === 'middle')) {
        text.setAttribute('fill', '#424242');
        text.setAttribute('font-weight', 'bold');
        text.setAttribute('x', parseFloat(rect.getAttribute('x')) + newLabelCoords.x + (bounds.width / 2));
        text.setAttribute('y', parseFloat(rect.getAttribute('y')) + newLabelCoords.y);
      }
    });
  }

  function addChildLabels() {
    // hold new labels
    var childCount = [];
    var childLabels = [];

    // svg namespace
    var svgNS = container.getElementsByTagName('svg')[0].namespaceURI;

    // find existing / build new labels
    Array.prototype.forEach.call(container.getElementsByTagName('text'), function(text) {
      if (text.getAttribute('text-anchor') === 'middle') {
        var rect = text.parentNode.getElementsByTagName('rect')[0];

        // exclude top node
        if (rect.getAttribute('fill') !== '#cccccc') {
          moveOriginalLabels();

          // find node value
          var nodeValue;
          for (var i = 0; i < data.getNumberOfRows(); i++) {
            if ((data.getValue(i, 0) === text.textContent) ||
                (data.getFormattedValue(i, 0) === text.textContent)) {
              nodeValue = data.getValue(i, 0);
            }
          }

          // find # of children
          var children = data.getFilteredRows([{
            column: 1,
            value: nodeValue
          }]);

          // add child count
          var textCount = document.createElementNS(svgNS, 'text');
          textCount.setAttribute('fill', '#000000');
          textCount.setAttribute('font-family', 'Arial');
          textCount.setAttribute('font-size', '24');
          textCount.setAttribute('font-weight', 'bold');
          textCount.setAttribute('x', parseFloat(rect.getAttribute('x')) + newLabelCoords.x);
          textCount.setAttribute('y', parseFloat(text.getAttribute('y')) + parseFloat(textCount.getAttribute('font-size')));
          textCount.textContent = children.length;
          childCount.push([text, textCount]);

          // add 'Children' label
          var textLabel = document.createElementNS(svgNS, 'text');
          textLabel.setAttribute('fill', '#000000');
          textLabel.setAttribute('font-family', 'Arial');
          textLabel.setAttribute('font-size', text.getAttribute('font-size'));
          textLabel.setAttribute('font-weight', 'bold');
          textLabel.setAttribute('x', parseFloat(rect.getAttribute('x')) + newLabelCoords.x);
          textLabel.setAttribute('y', parseFloat(textCount.getAttribute('y')) + parseFloat(textLabel.getAttribute('font-size')) + 2);
          textLabel.textContent = 'Children';
          childLabels.push([text, textLabel]);
        }
      }
    });

    // append new labels
    childCount.forEach(function (text) {
      text[0].parentNode.appendChild(text[1]);
    });
    childLabels.forEach(function (text) {
      text[0].parentNode.appendChild(text[1]);
    });
  }

  drawTree();
  window.addEventListener('resize', drawTree);
  function drawTree() {
    tree.draw(data, {
      minColor: '#f00',
      midColor: '#ddd',
      maxColor: '#0d0',
      headerHeight: 15,
      fontColor: 'black'
    });
  }
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>