问题
I'm a bit new with google charts, I was playing around to learn it but I got two problems with my chart:
1) I'm not sure why the second chart (red) displays without animation
2) How can I extend the annotation lines with the values to the top of my graph?
The best case would be that the values are shown under the chart title
<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']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
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 = {
title: 'Playground',
colors: ['#007F01', '#FE0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
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 chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(view, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 100%; height: 500px;"></div>
</body>
</html>
Here you can run it: jsfiddle
回答1:
there is bug within google charts when working with data views and animation.
an easy fix is to convert the view back to a data table when drawing the chart...
view.toDataTable()
e.g.
chart.draw(view.toDataTable(), options);
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 = {
title: 'Playground',
colors: ['#007F01', '#FE0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
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 chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(view.toDataTable(), options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 100%; height: 500px;"></div>
UPDATE
as for extending the annotation lines,
you can change the length,
but this will just increase the size of each,
and they still will not be aligned at the top
annotations: {
stem: {
length: 10
}
},
the only way would be to modify the chart manually, after it draws
you can move the labels and increase the height of the lines
but this will create two issues
1) the chart will move them back, anytime there is interactivity, such as hovering the labels or data points
to fix, you can use a MutationObserver
this will override the settings, every time the chart tries to move them back
2) if you use chart method getImageURI
to get an image of the chart, the changes will not appear
to fix this, use html2canvas to get the image instead of the chart method
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: {
stem: {
length: 10
}
},
title: 'Playground',
colors: ['#007f01', '#fe0002'],
interpolateNulls: true,
hAxis: {
title: 'Price',
titleTextStyle: {
color: '#333'
},
direction: 1,
format: 'decimal'
},
vAxis: {
direction: 1
},
orientation: 'horizontal',
// customize colum
series: {
0: {type: "area"},
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>
notes:
1) the move function (moveAnnotations
) uses colors
from the options
in order to identify the annotation labels from the rest of the chart labels
the chart changes all colors to lowercase, so had to change colors
in options
to lowercase
2) move function also uses option annotations.stem.length
to identify the annotation lines
来源:https://stackoverflow.com/questions/50801805/google-charts-animation-doesnt-work-for-one-chart-pointing-annotations-in-the