问题
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