This is driving me nuts. I can't get the legend to move at all. This produces a chart with the legend in it's default location on the right.
I clearly have legend position declared as "bottom" but it's not working. Yet this is exactly what the docs say.
google.charts.load('current',{'packages':['bar']});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff(){
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Count');
data.addColumn('number', 'Variance');
data.addRows([
['Smith', 35, {v: -.1126, f: '-11.26%'} ],
['Chalk', 53, {v: -.0126, f: '-1.26%'} ],
['Hank', 84, {v: -.0252, f: '-2.52%'} ],
['Jordan', 46, {v: .0688, f: '6.88%'} ],
['Bernie', 1, {v: 0, f: '-'} ],
['Ralph', 105, {v: -.0548, f: '-5.48%'} ]
]);
var options = {
series: {
0: {axis: 'Quotes'},
1: {axis: 'Percent'}
},
axes: {
y: {
Quotes: {label: 'Subdmission Count'},
Percent: {label: '% Percent'}
}
},
legend: {
position : 'bottom'
}
};
var table = new google.charts.Bar(document.getElementById('table1'));
table.draw(data, options);
}
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
</head>
<body>
<div id='table1'></div>
</body>
</html>
legend.position: ['top', 'bottom'] -- are just a couple of the many options that don't work on material charts
see Tracking Issue for Material Chart Feature Parity #2143 for an extensive list
however, these options will work on a core chart...
core --> google.visualization.ColumnChart -- using --> packages: ['corechart']
material --> google.charts.Bar -- using --> packages: ['bar']
there is also an option to get a core chart close to the look & feel of material
theme: 'material'
see following working snippet using core chart instead...
google.charts.load('current',{'packages':['corechart']});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff(){
var data = new google.visualization.DataTable();
data.addColumn('string', 'Name');
data.addColumn('number', 'Count');
data.addColumn('number', 'Variance');
data.addRows([
['Smith', 35, {v: -.1126, f: '-11.26%'} ],
['Chalk', 53, {v: -.0126, f: '-1.26%'} ],
['Hank', 84, {v: -.0252, f: '-2.52%'} ],
['Jordan', 46, {v: .0688, f: '6.88%'} ],
['Bernie', 1, {v: 0, f: '-'} ],
['Ralph', 105, {v: -.0548, f: '-5.48%'} ]
]);
var options = {
chartArea: {
height: '56%'
},
series: {
1: {
targetAxisIndex: 1
}
},
hAxis: {
title: 'Name'
},
vAxes: {
0: {
title: 'Submission Count'
},
1: {
title: '% Percent'
}
},
theme: 'material',
legend: {
position : 'bottom'
}
};
var table = new google.visualization.ColumnChart(document.getElementById('table1'));
table.draw(data, options);
}
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
</head>
<body>
<div id='table1'></div>
</body>
</html>
{position: 'left'} works fine in your example, so the only option left is that 'bottom' this is not supported.
Similar discussion on guthub mentions that it is not supported for another chart type and not planned to be implemented: https://github.com/google/google-visualization-issues/issues/1964
Related
I want to display the results of students using a single chart.
There are 4 exam phases in a year and 5 activities in each phase and each activity has grades ranging from A to G.
I'm using google line chart for this purpose.
Code for Generating the graph
[<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['line']});
google.charts.setOnLoadCallback(drawLineChart);
function drawLineChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Phase');
data.addColumn('string', 'Activity 1');
data.addColumn('string', 'Activity 2');
data.addColumn('string', 'Activity 3');
data.addColumn('string', 'Activity 4');
data.addColumn('string', 'Activity 5');
data.addRows([
['1', 'A','B','C','D','E'],
['2', 'E','D','C','B','A'],
['3', 'A','B','C','D','E'],
['4', 'E','D','C','B','A'],
]);
var options = {
title: 'Student Result',
width: 600,
height: 550,
legend: { position: 'bottom' },
vAxis: { ticks: ['A','B','C','D','E','F','G']}
};
var chart = new google.charts.Line(document.getElementById('line_top_x'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
</script>
</head>
<body>
<div id="line_top_x"></div>
</body>
</html>
Link to the Output of this code
The axis is null. It is not generating the chart as per data.
if you check the data format for a line chart,
only the first column in the data table may be of type 'string',
the rest should be 'number'
in this case, you could convert each grade to a number.
then use object notation to show the grade instead of the number.
using object notation allows you to provide the value (v:) and the formatted value (f:)
{v: 0, f: 'A'}
the formatted value is displayed by default.
next, if you want to customize the vertical axis, by using ticks,
you won't be able to use a material chart --> google.charts.Line
you will need to use a classic chart instead --> google.visualization.LineChart
there are several options that are not supported by material charts, including ticks
see Tracking Issue for Material Chart Feature Parity for more info.
see following working snippet for an example...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var scale = {
'A': 0,
'B': 1,
'C': 2,
'D': 3,
'E': 4,
'F': 5,
'G': 6
};
var grades = [
['1','A','B','C','D','E'],
['2','E','D','C','B','A'],
['3','A','B','C','D','E'],
['4','E','D','C','B','A']
];
var data = new google.visualization.DataTable();
data.addColumn('string', 'Phase');
data.addColumn('number', 'Activity 1');
data.addColumn('number', 'Activity 2');
data.addColumn('number', 'Activity 3');
data.addColumn('number', 'Activity 4');
data.addColumn('number', 'Activity 5');
grades.forEach(function (activities) {
var row = [];
activities.forEach(function (grade, indexGrade) {
if (indexGrade === 0) {
row.push(grade);
} else {
row.push({
v: scale[grade],
f: grade
});
}
});
data.addRow(row);
});
var options = {
title: 'Student Result',
width: 600,
height: 550,
legend: {
position: 'bottom'
},
vAxis: {
ticks: [
{v: 0, f: 'A'},
{v: 1, f: 'B'},
{v: 2, f: 'C'},
{v: 3, f: 'D'},
{v: 4, f: 'E'},
{v: 5, f: 'F'},
{v: 6, f: 'G'}
]
}
};
var chart = new google.visualization.LineChart(document.getElementById('line_top_x'));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="line_top_x"></div>
Full code
You can use jsfiddle too testing.
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,
chart: {
title: 'Year-by-year coffee consumption',
subtitle: 'This data is not real'
},
series: {
2: {
targetAxisIndex: 1
},
3: {
targetAxisIndex: 1
}
}
};
// Instantiate and draw our chart, passing in some options.
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
};
The Output
The Question
I use Google Visualization to generate above chart.
If you see the above screenshot you can see that Y- axis of above chart has two values in left side and right side. Seems like it happens because graphs use two date range for left side and right side bar.
I wanted to remove right side Y axis or print the same values for both right and left Y axis. I mean all data should be under the Y - axis which is on left side. What can I do to do it?
the options for series.n.targetAxisIndex create the second axis
removing these options will allow all series to default to the first axis
however, in Material bar charts, moving a series to a different axis,
separates the series into multiple stacks, resulting in blue and red bars
removing the options mentioned above will combine all series into one blue stack
in order to keep the stacks separated in two colors,
series.n.targetAxisIndex must be used and dual axis' will be displayed
to keep the two axis' in sync, use option --> vAxis.viewWindow
this will set an identical range for both axis'
vAxis: {
viewWindow: {
min: 0,
max: 1800
}
}
see following working snippet...
google.charts.load('current', {
packages: ['bar']
}).then(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]
]);
var options = {
isStacked: true,
width: 800,
height: 600,
chart: {
title: 'Year-by-year coffee consumption',
subtitle: 'This data is not real'
},
series: {
2: {
targetAxisIndex: 1
},
3: {
targetAxisIndex: 1
}
},
vAxis: {
viewWindow: {
min: 0,
max: 1800
}
}
};
var chart = new google.charts.Bar(document.getElementById('chart_div'));
chart.draw(data, google.charts.Bar.convertOptions(options));
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
note: jsapi should no longer be used to load the charts library,
according to the release notes...
The version of Google Charts that remains available via the jsapi loader is no longer being updated consistently. The last update, for security purposes, was with a pre-release of v45. Please use the new gstatic loader.js from now on.
this will only change the load statement, see above snippet...
I am trying to set ticks for a double y-axis line graph but either the graph wont load, it it loads exactly the same. Any help will be greatly appreciated
Goal is to set Price ticks: [0.002, 0.004. 0.006. 0.008], and Volume increment by lets say 1000
Also having issues with prices for instance being: 0.00242, 0.00521 all showing up as 0.1
<?php
$sql = "SELECT Timestamp, LastPrice, Volume FROM vol";
$result = $dbconnect->query($sql);
?>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
google.charts.load('current', {'packages':['line', 'corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var button = document.getElementById('change-chart');
var chartDiv = document.getElementById('chart_div');
var data = google.visualization.arrayToDataTable([
['Timestamp','LastPrice','Volume'],
<?php
while($row = mysqli_fetch_assoc($result)){
echo "[ '".$row["Timestamp"]."', ".$row["LastPrice"].", ".$row["Volume"].", ],";
}
echo $row["LastPrice"];
?>
]);
var materialOptions = {
chart: {
},
width: 600,
height: 300,
series: {
// Gives each series an axis name that matches the Y-axis below.
0: {axis: 'LastPrice' },
1: {axis: 'BaseVolume'}
},
vAxis: {1: {ticks:[0, 0.002, 0.004, 0.006]} },
axes: {
// Adds labels to each axis; they don't have to match the axis names.
y: {
LastPrice: {label: 'Price'},
BaseVolume: {label: 'Volume'}
}
}
};
function drawMaterialChart() {
var materialChart = new google.charts.Line(chartDiv);
materialChart.draw(data, materialOptions);
button.innerText = 'Classic';
button.onclick = drawClassicChart;
}
drawMaterialChart();
}
</script>
there are several configuration options that aren't supported by Material charts, including...
{hAxis,vAxis,hAxes.*,vAxes.*}.ticks
see --> Tracking Issue for Material Chart Feature Parity
instead, recommend using a Classic chart with the following option...
theme: 'material'
for dual y-axis charts, use the series option to specify the target axis
series: {
1: {
targetAxisIndex: 1,
}
},
use option vAxes, with an e, to specify ticks for each y-axis
vAxes: {
0: {
ticks:[0, 1000, 2000, 3000],
title: 'Last Price'
},
1: {
ticks:[0, 0.002, 0.004, 0.006],
title: 'Base Volume'
}
}
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = new google.visualization.DataTable({
cols: [
{label: 'x', type: 'string'},
{label: 'y0', type: 'number'},
{label: 'y1', type: 'number'}
],
rows: [
{c:[{v: 'row 0'}, {v: 1800}, {v: 0.00242}]},
{c:[{v: 'row 1'}, {v: 2200}, {v: 0.00521}]},
{c:[{v: 'row 2'}, {v: 2800}, {v: 0.00343}]},
{c:[{v: 'row 3'}, {v: 2800}, {v: 0.00441}]},
{c:[{v: 'row 4'}, {v: 2300}, {v: 0.00532}]}
]
});
var container = document.getElementById('chart');
var chart = new google.visualization.LineChart(container);
chart.draw(data, {
width: 600,
height: 300,
series: {
1: {
targetAxisIndex: 1,
}
},
theme: 'material',
vAxes: {
0: {
ticks:[0, 1000, 2000, 3000],
title: 'Last Price'
},
1: {
ticks:[0, 0.002, 0.004, 0.006],
title: 'Base Volume'
}
}
});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
I am trying to rename the labels on the axes to levels like low|medium| high instead of percentages in my bar chart. Could anyone suggest me a way of accomplishing it?
<script type="text/javascript">
google.charts.load('current', {'packages':['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Programming Languages', 'Expertise Level %'],
['Java', 100],
['C', 80],
['Python', 100],
['Web UX', 100],
['Matlab', 70]
]);
var options = {
bars: 'vertical' // Required for Material Bar Charts.
};
var chart = new google.charts.Bar(document.getElementById('barchart_material'));
unfortunately, no option available for Material charts...
many options are not supported, see --> Tracking Issue for Material Chart Feature Parity
however, using a Classic chart, the vAxis.ticks option can be used to customize the axis labels...
use the formatted value of each tick to display --> Low, Medium, High
vAxis: {
ticks: [
{v: 33.33, f: 'Low'},
{v: 66.67, f: 'Medium'},
{v: 100, f: 'High'}
]
}
see following working snippet,
which also uses option --> theme: 'material'
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Programming Languages', 'Expertise Level %'],
['Java', 100],
['C', 80],
['Python', 100],
['Web UX', 100],
['Matlab', 70]
]);
var options = {
theme: 'material',
vAxis: {
ticks: [
{v: 33.33, f: 'Low'},
{v: 66.67, f: 'Medium'},
{v: 100, f: 'High'}
]
}
};
var chart = new google.visualization.ColumnChart(document.getElementById('barchart'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="barchart"></div>
note:
Material --> google.charts.Bar
Classic --> google.visualization.ColumnChart
So I have made a google visualization table that shows the store name , sales and speed of service info.
I have made two tables mystore ( the first table) and allStores(the second table). So the myStore is the owners store info and
the allStore is the genral info of that franchise.
So when you click on the sales header on the allStore table it will order from the highest or lowest and What i want to do is to reflect that on the
owners store's rank in the myStore table, so eg: If greerton is one of the owners store and the if the sales info is ranked third for it
it should show that up in myStore. I have tried to find related info but they were all using html table.
Please Help =)
<div id="table_div2"></div>
<div id="table_div4"></div>
google.setOnLoadCallback(myStore);
google.setOnLoadCallback(allStores);
function myStore() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Store Name');
data.addColumn('number', ' Sales');
data.addColumn('number','SOS');
data.addRows([
['Bayfair',{ v: 4895, f: '$4895' },{v: 68, f: '$68'}],
['Greerton',{ v: 3158, f: '$3158' },{v: 126, f: '$126'}]
]);
var Table = new google.visualization.Table(document.getElementById('table_div2'));
Table.draw(data, { showRowNumber: true, width: '100%', height: '100%' });
}
function allStores() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Store Name');
data.addColumn('number', ' Sales');
data.addColumn('number','SOS');
data.addRows([
['Bayfair',{ v: 4895, f: '$4895' },{v: 68, f: '68'}],
['Greerton',{ v: 3158, f: '$3158' },{v: 126, f: '126'}],
['Frankton',{ v: 3689, f: '$3689' },{v: 79, f: '79'}],
['Mt Manganui',{ v: 3069, f: '$3069' },{v: 72, f: '72'}],
['Tauranga',{ v: 2689, f: '$2689' },{v: 68, f: '68'}],
['Te Rapa',{ v: 2269, f: '$2269' },{v: 143, f: '143'}],
['The Base',{ v: 1895, f: '$1895' },{v: 125, f: '125'}],
]);
var Table = new google.visualization.Table(document.getElementById('table_div4'));
Table.draw(data, { showRowNumber: true, width: '100%', height: '100%' });
}
var stores= ["Bayfair","Greerton"];
function Take (){
}
https://jsfiddle.net/1gm96gqy/
OK, here's something to get you started. See:
https://jsfiddle.net/1gm96gqy/4/
Added is a function that highlights stores in the second list if they appear in the first list. It uses jQuery. It is tied to both the initial draw event and any time the data is sorted.
google.setOnLoadCallback(myStore);
google.setOnLoadCallback(allStores);
function highlightStores(){
// make a list of all the stores in the first table
var storerows = $('#table_div2').find('tr');
// make a list of all the stores in second table
var allstorerows = $('#table_div4').find('tr');
allstorerows.each(function(i,hstore){
var thestore = $(hstore).children()[1];
var hstorename = $($(hstore).children()[1]).text();
storerows.each(function(j,store){
if(store.children[1].nodeName != 'TH'){
var storename = $($(store).children()[1]).text();
if (storename == hstorename){
$(hstore).attr('style','background-color:yellow');
}
}
})
})
}
function myStore() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Store Name');
data.addColumn('number', ' Sales');
data.addColumn('number','SOS');
data.addRows([
['Bayfair',{ v: 4895, f: '$4895' },{v: 68, f: '$68'}],
['Greerton',{ v: 3158, f: '$3158' },{v: 126, f: '$126'}]
]);
var Table = new google.visualization.Table(document.getElementById('table_div2'));
Table.draw(data, { showRowNumber: true, width: '100%', height: '100%' });
}
function allStores() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Store Name');
data.addColumn('number', ' Sales');
data.addColumn('number','SOS');
data.addRows([
['Bayfair',{ v: 4895, f: '$4895' },{v: 68, f: '68'}],
['Greerton',{ v: 3158, f: '$3158' },{v: 126, f: '126'}],
['Frankton',{ v: 3689, f: '$3689' },{v: 79, f: '79'}],
['Mt Manganui',{ v: 3069, f: '$3069' },{v: 72, f: '72'}],
['Tauranga',{ v: 2689, f: '$2689' },{v: 68, f: '68'}],
['Te Rapa',{ v: 2269, f: '$2269' },{v: 143, f: '143'}],
['The Base',{ v: 1895, f: '$1895' },{v: 125, f: '125'}],
]);
var Table = new google.visualization.Table(document.getElementById('table_div4'));
google.visualization.events.addListener(Table, 'ready', highlightStores);
google.visualization.events.addListener(Table, 'sort', highlightStores);
Table.draw(data, { showRowNumber: true, width: '100%', height: '100%' });
}
The result is: