You can use this jsfiddle for testing
Full Code:
google.load('visualization', '1.1', { 'packages': ['bar'] }); google.setOnLoadCallback(drawStuff); function drawStuff() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Nescafe Instant'); data.addColumn('number', 'Folgers Instant'); data.addColumn('number', 'Nescafe Beans'); data.addColumn('number', 'Folgers Beans'); data.addRows([ ['2001', 500, 1200, 816, 200], ['2002', 163, 231, 539, 594], ['2003', 125, 819, 200, 578], ['2004', 197, 536, 613, 500] ]); // Set chart options var options = { isStacked: true, width: 800, height: 600, legend: { position: "top", alignment: "", textStyle: { color: "#999" } }, chart: { title: 'Year-by-year coffee consumption', subtitle: 'This data is not real' }, series: { 2: { targetAxisIndex: 1 }, 3: { targetAxisIndex: 1 } } }; };
Question :
I want to display legend above of the chart. I have used legend position : top. But it is not working. I can move legend either left side or right side without a problem changing legend position value.
But I can't move legend top or bottom. Why is that? What was the my mistake?
1 Answers
Answers 1
First, you need to use the correct library, as jsapi
is out of date and should no longer be used,
according to 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 gstaticloader.js
from now on.
This will only change the load
statement:
old load statement...
google.load('visualization', '1.1', { packages: ['bar'] });
new load statement...
google.charts.load('current', { packages: ['corechart'] });
Next, as seen above, for classic charts, use --> packages: ['corechart']
instead of 'bar'
Google has provided a chart option, to style classic charts similar to material:
theme: 'material'
When creating a classic chart, use the following namespace:
google.visualization.ColumnChart
vs. material
google.charts.Bar
See the following working snippet:
google.charts.load('current', { packages: ['corechart'] }).then(function () { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Nescafe Instant'); data.addColumn('number', 'Folgers Instant'); data.addColumn('number', 'Nescafe Beans'); data.addColumn('number', 'Folgers Beans'); data.addRows([ ['2001', 500, 1200, 816, 200], ['2002', 163, 231, 539, 594], ['2003', 125, 819, 200, 578], ['2004', 197, 536, 613, 500] ]); var options = { chartArea: { height: '100%', width: '100%', top: 64, left: 64, right: 32, bottom: 32 }, height: '100%', width: '100%', isStacked: true, legend: { position: 'top', textStyle: { color: '#999' } }, title: 'Year-by-year coffee consumption' }; var container = document.getElementById('chart_div'); var chart = new google.visualization.ColumnChart(container); drawChart(); window.addEventListener('resize', drawChart, false); function drawChart() { chart.draw(data, options); } });
html, body { height: 100%; margin: 0px 0px 0px 0px; overflow: hidden; padding: 0px 0px 0px 0px; } .chart { height: 100%; }
<script src="https://www.gstatic.com/charts/loader.js"></script> <div class="chart" id="chart_div"></div>
Note: the only advantage to material is having multiple stacks,
in classic, you cannot group multiple stacks.
UPDATE
There are no options you can change to position the legend to top or bottom, it is simply not supported.
The only solution would be to manually build a custom legend; following is an example of how this could be done:
google.charts.load('current', { packages: ['bar'] }).then(function () { var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Nescafe Instant'); data.addColumn('number', 'Folgers Instant'); data.addColumn('number', 'Nescafe Beans'); data.addColumn('number', 'Folgers Beans'); data.addRows([ ['2001', 500, 1200, 816, 200], ['2002', 163, 231, 539, 594], ['2003', 125, 819, 200, 578], ['2004', 197, 536, 613, 500] ]); var options = { chart: { title: 'coffee consumption', subtitle: 'This data is not real' }, height: '100%', isStacked: true, legend: { position: 'none' }, series: { 2: { targetAxisIndex: 1 }, 3: { targetAxisIndex: 1 } }, width: '100%' }; var container = document.getElementById('chart_div'); var chart = new google.charts.Bar(container); drawChart(); window.addEventListener('resize', drawChart, false); function drawChart() { chart.draw(data, google.charts.Bar.convertOptions(options)); } // add legend marker function addLegendMarker(markerProps) { var legendMarker = document.getElementById('template-legend-marker').innerHTML; for (var handle in markerProps) { if (markerProps.hasOwnProperty(handle)) { legendMarker = legendMarker.replace('{{' + handle + '}}', markerProps[handle]); } } document.getElementById('legend_div').insertAdjacentHTML('beforeEnd', legendMarker); } // chart ready event google.visualization.events.addListener(chart, 'ready', function () { var legend = document.getElementById('legend_div'); // get colors from chart var colorPallette = []; var colorsBottom = []; var colorsTop = []; var stacks = container.getElementsByTagName('*'); Array.prototype.forEach.call(stacks, function(stack) { switch (stack.tagName) { case 'path': if ((stack.getAttribute('fill') !== null) && (stack.getAttribute('fill') !== '#ffffff')) { if (colorsTop.indexOf(stack.getAttribute('fill')) === -1) { colorsTop.push(stack.getAttribute('fill')); } } break; case 'rect': if ((stack.getAttribute('fill') !== null) && (stack.getAttribute('fill') !== '#ffffff')) { if (colorsBottom.indexOf(stack.getAttribute('fill')) === -1) { colorsBottom.push(stack.getAttribute('fill')); } } break; } }); for (var i = 0; i < colorsBottom.length; i++) { colorPallette.push(colorsBottom[i]); colorPallette.push(colorsTop[i]); } // clear previous legend legend.innerHTML = ''; // add legend marker for each Y axis column - skip X axis --> i = 1 for (var i = 1; i < data.getNumberOfColumns(); i++) { var markerProps = {}; markerProps.index = i; markerProps.color = colorPallette[i - 1]; markerProps.label = data.getColumnLabel(i); addLegendMarker(markerProps); } // add "hover" event to each legend marker var currentSelection; var markers = legend.getElementsByTagName('DIV'); Array.prototype.forEach.call(markers, function(marker) { marker.addEventListener('mouseover', function (e) { currentSelection = chart.getSelection(); var marker = e.target || e.srcElement; if (marker.tagName.toUpperCase() !== 'DIV') { marker = marker.parentNode; } var columnIndex = parseInt(marker.getAttribute('data-columnIndex')); chart.setSelection([{column: columnIndex}]); }, false); marker.addEventListener('mouseout', function (e) { chart.setSelection([]); }, false); }); }); });
html, body { height: 100%; margin: 0px 0px 0px 0px; overflow: hidden; padding: 0px 0px 0px 0px; } .chart { height: 100%; } #legend_div { color: #999; font-family: Roboto; position: absolute; right: 0px; text-align: right; top: 0px; width: 60%; z-index: 1000; } .legend-marker { display: inline-block; padding: 6px 6px 6px 6px; } .legend-marker-color { border-radius: 25%; display: inline-block; height: 12px; width: 12px; }
<script src="https://www.gstatic.com/charts/loader.js"></script> <div id="legend_div"></div> <div class="chart" id="chart_div"></div> <!-- template for building marker --> <script id="template-legend-marker" type="text/html"> <div class="legend-marker" data-columnIndex="{{index}}"> <div class="legend-marker-color" style="background-color: {{color}}"></div> <span>{{label}}</span> </div> </script>