Google Treemap: want to put color of node in red, green and amber

左心房为你撑大大i 提交于 2021-02-16 14:28:33

问题


I am using Google Treemap to show department wise data. I am not being able to set the color of nodes in which I want. I don't know whether colors are decided by treemap itself.

google.load('visualization', '1', {packages: ['treemap'], callback: drawVisualization});
function drawVisualization() {
    // Create and populate the data table.
    var dataArray = [];
    dataArray.push(['Department Name', 'Parent', 'Number of Goals', 'color']);
    dataArray.push(['Goals by Team', null, 0, 0]);
    dataArray.push(['Sales', 'Goals by Team', 2, 'red']);
    dataArray.push(['Finance', 'Goals by Team', 6, 'green']);
    dataArray.push(['Pre-Sales', 'Goals by Team', 8, 'red']);
    dataArray.push(['Technology', 'Goals by Team', 4, 'amber']);
    dataArray.push(['Management', 'Goals by Team', 1, 'amber']);

    var data = google.visualization.arrayToDataTable(dataArray);
    // Create and draw the visualization.
    var treemap = new google.visualization.TreeMap(document.getElementById('visualization'));
    treemap.draw(data, {
    minColor: 'red',
    midColor: 'orange',
    maxColor: 'green',
    headerHeight: 0,
    fontColor: 'black',
    showScale: true});

    google.visualization.events.addListener(treemap, 'select', showGoalsByDepartment);
    google.visualization.events.trigger(treemap, 'select', null);
    function showGoalsByDepartment() {
    var selection = treemap.getSelection();
    if (selection && selection.length > 0) {
        var node_name = data.getValue(selection[0].row, 0);
        $location.path('departmentGoal/'+node_name);
        $scope.$apply();
    }
    }
}

But the colors of nodes are not being shown as assigned.

Any help appreciated.


回答1:


colors for the treemap are assigned on a gradient scale,
there are no standard options that will allow assignment of a specific color to each node.

however, the chart can be modified manually, after it has been drawn.


first, the last color column in the data table should be a number,
this is what the treemap uses to determine the value of the gradient color.
the treemap will throw an error if a string is used.

as such, we will use a data view to exclude this column when drawing the chart.

var data = google.visualization.arrayToDataTable(dataArray);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, 2]);

next, when the chart is drawn, <rect> elements are used to draw each node,
along with a <text> element for the label.
both elements will be stored in a <g> element, similar to the following.

<g style="cursor: default;">
  <rect x="5" y="0" width="480" height="195" stroke="#ffffff" stroke-width="1" fill="Red"></rect>
  <text text-anchor="middle" x="245" y="101.7" font-family="Arial" font-size="12" stroke="none" stroke-width="0" fill="#000000">Pre-Sales</text>
</g>

in order to assign our specific color, we loop through all the <rect> elements,
for each <rect> we find the associated <text> label,
then go back to the original data table and find the row with that label using getFilteredRows.
then we can pull the color from that row, and assign it to the <rect>.

Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(rect) {
  var textElements = rect.parentNode.getElementsByTagName('text');
  if (textElements.length > 0) {
    var dataRows = data.getFilteredRows([{
      column: 0,
      value: textElements[0].textContent
    }]);
    if (dataRows.length > 0) {
      rect.setAttribute('fill', data.getValue(dataRows[0], 3));
    }
  }
});

finally, the chart will change our color back to the default gradient anytime there is activity, such as 'select'.
to override, we can use a MutationObserver.

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

see following working snippet

google.charts.load('current', {packages:['treemap'], callback: drawVisualization});
function drawVisualization() {
  var dataArray = [];
  dataArray.push(['Department Name', 'Parent', 'Number of Goals', 'color']);
  dataArray.push(['Goals by Team', null, 0, null]);
  dataArray.push(['Sales', 'Goals by Team', 2, 'Red']);
  dataArray.push(['Finance', 'Goals by Team', 6, 'Green']);
  dataArray.push(['Pre-Sales', 'Goals by Team', 8, 'Red']);
  dataArray.push(['Technology', 'Goals by Team', 4, 'OrangeRed']);
  dataArray.push(['Management', 'Goals by Team', 1, 'OrangeRed']);

  var data = google.visualization.arrayToDataTable(dataArray);
  var view = new google.visualization.DataView(data);
  view.setColumns([0, 1, 2]);

  var container = document.getElementById('visualization');
  var treemap = new google.visualization.TreeMap(container);

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

  function addColors() {
    Array.prototype.forEach.call(container.getElementsByTagName('rect'), function(rect) {
      var textElements = rect.parentNode.getElementsByTagName('text');
      if (textElements.length > 0) {
        var dataRows = data.getFilteredRows([{
          column: 0,
          value: textElements[0].textContent
        }]);
        if (dataRows.length > 0) {
          rect.setAttribute('fill', data.getValue(dataRows[0], 3));
        }
      }
    });
  }

  google.visualization.events.addListener(treemap, 'select', showGoalsByDepartment);
  google.visualization.events.trigger(treemap, 'select', null);
  function showGoalsByDepartment() {
    var selection = treemap.getSelection();
    if (selection && selection.length > 0) {
      var node_name = data.getValue(selection[0].row, 0);
      //$location.path('departmentGoal/'+node_name);
      //$scope.$apply();
    }
  }

  treemap.draw(view, {
    showScale: false,
    headerHeight: 0,
    fontColor: 'black'
  });
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="visualization"></div>

notes

1) the script library jsapi should no longer be used.

<script src="https://www.google.com/jsapi"></script>

see the release notes...

The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. Please use the new gstatic loader.js from now on.

<script src="https://www.gstatic.com/charts/loader.js"></script>

this will only change the load statement, see snippet above.

2) event listeners, such as 'select', should be assigned before the chart is drawn.

3) Amber is not a valid html color name, OrangeRed was used above instead.

4) the color scale was removed in the above snippet, since it will not match our specific color assignment.

showScale: false


来源:https://stackoverflow.com/questions/51185929/google-treemap-want-to-put-color-of-node-in-red-green-and-amber

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!