Reputation: 1033
Thanks to White Hat in this post ,I was able to make a custom annotation for the area chart. Somehow it doesn't work the stepped area chart.
The chart draws at first everything correctly but then sets the annotation in the stepped area chart back. With help of the MutationObserver
, the settings should be overridden when the chart is drawn but this applies just for the area chart.
How can I solve this ?
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data1 = new google.visualization.DataTable();
data1.addColumn('number', 'x');
data1.addColumn('number', 'green');
data1.addRows([
[0.005, 3],
[0.006, 6],
[0.007, 5],
[0.008, 8],
[0.009, 2],
[0.010, 5],
[0.011, 5],
[0.012, 4],
[0.013, 8]
]);
var data2 = new google.visualization.DataTable();
data2.addColumn('number', 'x');
data2.addColumn('number', 'red');
data2.addRows([
[0.016, 5],
[0.017, 1],
[0.018, 3],
[0.019, 9],
[0.020, 4],
[0.021, 5],
[0.022, 7],
[0.023, 7],
[0.024, 3]
]);
var joinedData = google.visualization.data.join(data1, data2, 'full',
[[0, 0]], [1], [1]);
var options = {
annotations: {
stem: {
length: 10
}
},
title: 'Playground',
colors: ['#007f01', '#fe0002'],
interpolateNulls: true,
hAxis: {
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "steppedArea"},
1: {type: "area"},
},
// legend: {position : 'left'},
animation: {
startup: true,
duration: 1000,
easing: 'out',
}
};
var view = new google.visualization.DataView(joinedData);
view.setColumns([0,
1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2,
{
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}
]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.ComboChart(container);
var observer = new MutationObserver(moveAnnotations);
observer.observe(container, {
childList: true,
subtree: true
});
function moveAnnotations() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var labels = container.getElementsByTagName('text');
var labelSize = 0;
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
if (options.colors.indexOf(label.getAttribute('fill')) > -1) {
labelSize = (parseFloat(label.getAttribute('font-size')) / 2);
label.setAttribute('y', chartBounds.top + labelSize);
}
}
});
var stems = container.getElementsByTagName('rect');
Array.prototype.forEach.call(stems, function(stem) {
if ((parseInt(stem.getAttribute('height')) === options.annotations.stem.length) && (stem.getAttribute('fill') === '#999999')) {
var height = parseFloat(stem.getAttribute('y')) - chartBounds.top;
stem.setAttribute('height', height);
stem.setAttribute('y', chartBounds.top + labelSize);
}
});
}
chart.draw(view.toDataTable(), options);
});
</script>
</head>
<body>
<div id="chart_div" style="width: 100%; height: 500px;"></div>
</body>
</html>
Upvotes: 2
Views: 639
Reputation: 61275
the default annotation settings for stepped area charts differ from normal area charts
for stepped, the annotations appear inside the area, which changes the color to white,
which is not a color used to find the labels and move them
an easy fix is to specify that the annotation always be outside the area...
annotations: {
alwaysOutside: true,
...
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data1 = new google.visualization.DataTable();
data1.addColumn('number', 'x');
data1.addColumn('number', 'green');
data1.addRows([
[0.005, 3],
[0.006, 6],
[0.007, 5],
[0.008, 8],
[0.009, 2],
[0.010, 5],
[0.011, 5],
[0.012, 4],
[0.013, 8]
]);
var data2 = new google.visualization.DataTable();
data2.addColumn('number', 'x');
data2.addColumn('number', 'red');
data2.addRows([
[0.016, 5],
[0.017, 1],
[0.018, 3],
[0.019, 9],
[0.020, 4],
[0.021, 5],
[0.022, 7],
[0.023, 7],
[0.024, 3]
]);
var joinedData = google.visualization.data.join(data1, data2, 'full',
[[0, 0]], [1], [1]);
var options = {
annotations: {
alwaysOutside: true,
stem: {
length: 10
}
},
title: 'Playground',
colors: ['#007f01', '#fe0002'],
interpolateNulls: true,
hAxis: {
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "steppedArea"},
1: {type: "area"},
},
// legend: {position : 'left'},
animation: {
startup: true,
duration: 1000,
easing: 'out',
}
};
var view = new google.visualization.DataView(joinedData);
view.setColumns([0,
1,
{
calc: "stringify",
sourceColumn: 1,
type: "string",
role: "annotation"
},
2,
{
calc: "stringify",
sourceColumn: 2,
type: "string",
role: "annotation"
}
]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.ComboChart(container);
var observer = new MutationObserver(moveAnnotations);
observer.observe(container, {
childList: true,
subtree: true
});
function moveAnnotations() {
var chartLayout = chart.getChartLayoutInterface();
var chartBounds = chartLayout.getChartAreaBoundingBox();
var labels = container.getElementsByTagName('text');
var labelSize = 0;
Array.prototype.forEach.call(labels, function(label) {
if (label.getAttribute('text-anchor') === 'middle') {
if (options.colors.indexOf(label.getAttribute('fill')) > -1) {
labelSize = (parseFloat(label.getAttribute('font-size')) / 2);
label.setAttribute('y', chartBounds.top + labelSize);
}
}
});
var stems = container.getElementsByTagName('rect');
Array.prototype.forEach.call(stems, function(stem) {
if ((parseInt(stem.getAttribute('height')) === options.annotations.stem.length) && (stem.getAttribute('fill') === '#999999')) {
var height = parseFloat(stem.getAttribute('y')) - chartBounds.top;
stem.setAttribute('height', height);
stem.setAttribute('y', chartBounds.top + labelSize);
}
});
}
chart.draw(view.toDataTable(), options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
Upvotes: 2