问题
annotations on the google charts stacked to each other. I want to separate them and put it to appropriate position based on where it's own bar/line. something like the image below. annotation.stem.length move but they move all together. I saw also saw solution here but it's not working/moving any texts. it's quiet advanced for me so it's hard for me to modify.
Chart i want to achieve
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawDSRPerformance);
function drawDSRPerformance() {
// Some raw data (not necessarily accurate)
var data = google.visualization.arrayToDataTable([
['Person', 'Booked Volume', 'Number of calls', 'Effective calls'],
['Almario', 8567, 213, 123],
['Anthony', 5489, 134, 75],
['Marvin', 1678, 256, 104],
['Jobert', 1890, 234, 156],
['Lysander', 2109, 167, 133]
]);
var view = new google.visualization.DataView(data);
view.setColumns(
[0,1,2,3,
{ calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation" },
{ calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation" },
{ calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation" }
]);
var options = {
animation:{
duration: 1000,
easing: 'out',
startup: true
},
annotations: {
textStyle: {
fontSize: 12,
color: 'black',
auraColor: 'none'
}
},
vAxes: {
0: {
viewWindowMode:'explicit',
viewWindow:{
max:9000,
min:0
},
gridlines: {
color: 'transparent',
count: 10
}
},
1: {
viewWindow:{
max:300,
min:0
},
gridlines: {
color: 'transparent',
count: 7
}
},
2: {
viewWindow:{
max:300,
min:0
},
gridlines: {
color: 'transparent',
count: 7
}
}
},
seriesType: 'bars',
series: {
0: {
targetAxisIndex: 0,
color: '#FFFF00'
},
1: {
type: 'line',
targetAxisIndex: 1,
color: '#4F81BD',
pointShape: 'square',
pointsVisible: true
},
2: {
type: 'line',
targetAxisIndex: 2,
color: '#C0504D',
pointShape: 'square',
pointsVisible: true
}
},
backgroundColor: '#B3A2C7',
chartArea: {
backgroundColor: '#E6E0EC'
},
legend: {
position: 'bottom',
alignment: 'center'
}
};
var container = document.getElementById('dsr_performance');
var chart = new google.visualization.ComboChart(container);
// move annotations
var observer = new MutationObserver(function () {
Array.prototype.forEach.call(container.getElementsByTagName('text'), function(annotation) {
if ((annotation.getAttribute('text-anchor') === 'middle') &&
(annotation.getAttribute('fill') === '#ffffff')) {
var chartLayout = chart.getChartLayoutInterface();
annotation.setAttribute('y',
chartLayout.getYLocation(0) - (parseInt(annotation.getAttribute('font-size')) / 2)
);
}
});
});
observer.observe(container, {
childList: true,
subtree: true
});
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dsr_performance_container">
<div id="dsr_performance" style="width: 100%; height: 300px;"></div>
</div>
回答1:
when adding annotations, each annotation role should follow the series column it represents,
this will place the annotation closer to its point...
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2, {
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3, {
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}]);
however, this will not always prevent overlap
to change the length of the stem for a specific set of annotations,
place the annotations
option inside the series
option...
series: {
0: {
targetAxisIndex: 0,
color: '#FFFF00',
},
1: {
annotations: {
stem: {
length: 8
}
},
type: 'line',
targetAxisIndex: 1,
color: '#4F81BD',
pointShape: 'square',
pointsVisible: true
},
2: {
annotations: {
stem: {
length: 4
}
},
type: 'line',
targetAxisIndex: 2,
color: '#C0504D',
pointShape: 'square',
pointsVisible: true
}
},
as for moving the annotations manually...
annotations are added as <text>
elements,
we have to identify the <text>
elements for the annotations from the other <text>
elements,
such as axis labels, titles, etc.
the code you found uses two attributes on the <text>
element to identify annotations'text-anchor'
- usually assigned a value of 'middle'
for annotations'fill'
- the color of the <text>
element
see following working snippet,
here, we're only going to move the bar annotations
we have to use a MutationObserver
,
or the chart will move them back to their original position on hover...
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawDSRPerformance);
function drawDSRPerformance() {
var data = google.visualization.arrayToDataTable([
['Person', 'Booked Volume', 'Number of calls', 'Effective calls'],
['Almario', 8567, 213, 123],
['Anthony', 5489, 134, 75],
['Marvin', 1678, 256, 104],
['Jobert', 1890, 234, 156],
['Lysander', 2109, 167, 133]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
}, 2, {
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}, 3, {
calc: "stringify",
sourceColumn: 3,
type: "string",
role: "annotation"
}]);
var options = {
animation:{
duration: 1000,
easing: 'out',
startup: true
},
annotations: {
textStyle: {
fontSize: 12,
auraColor: 'none'
}
},
vAxes: {
0: {
viewWindowMode:'explicit',
viewWindow:{
max:9000,
min:0
},
gridlines: {
color: 'transparent',
count: 10
}
},
1: {
viewWindow:{
max:300,
min:0
},
gridlines: {
color: 'transparent',
count: 7
}
},
2: {
viewWindow:{
max:300,
min:0
},
gridlines: {
color: 'transparent',
count: 7
}
}
},
seriesType: 'bars',
series: {
0: {
targetAxisIndex: 0,
color: '#FFFF00',
},
1: {
annotations: {
stem: {
length: 8
}
},
type: 'line',
targetAxisIndex: 1,
color: '#4F81BD',
pointShape: 'square',
pointsVisible: true
},
2: {
annotations: {
stem: {
length: 4
}
},
type: 'line',
targetAxisIndex: 2,
color: '#C0504D',
pointShape: 'square',
pointsVisible: true
}
},
backgroundColor: '#B3A2C7',
chartArea: {
backgroundColor: '#E6E0EC'
},
legend: {
position: 'bottom',
alignment: 'center'
}
};
var container = document.getElementById('dsr_performance');
var chart = new google.visualization.ComboChart(container);
// move annotations
var observer = new MutationObserver(function () {
Array.prototype.forEach.call(container.getElementsByTagName('text'), function(annotation) {
if ((annotation.getAttribute('text-anchor') === 'middle') &&
(annotation.getAttribute('fill') === '#404040')) {
var chartLayout = chart.getChartLayoutInterface();
annotation.setAttribute('y',
chartLayout.getYLocation(0) - (parseInt(annotation.getAttribute('font-size')) / 2)
);
}
});
});
observer.observe(container, {
childList: true,
subtree: true
});
chart.draw(view, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dsr_performance_container">
<div id="dsr_performance" style="width: 100%; height: 300px;"></div>
</div>
来源:https://stackoverflow.com/questions/51624193/how-to-change-the-annotations-position-on-bars-and-lines-with-google-charts