I would like to know if anyone was able or know's any way I can hide/show a line from a AreaChart from google visualization API after it was loaded.
In a little more detail, say we have 8 lines in a area chart, but because they are so many, that makes the graph almost unreadable and confuse. So I want a piece of JavaScript code that can turn on or off theses lines after the chart is already built and available to the user in the browser.
When I say on/off anything goes, changing the opacity, removing the line, or anything that just makes it disappear from the graph.
I am using CSS styling when building the charts (on the JavaScript that builds it, using options (series) on the chart.draw(data, options).
I can't change the arrays of data I have. So I'm not looking for a dynamic data, CSS and JavaScript solution.
Any help would be highly appreciated.
Found this code, I was able to adapt it to a AreaChart. Hope it helps others..
http://jsfiddle.net/asgallant/6gz2Q/
<div id="chart_div"></div>
<div id="creativeCommons" style="text-align: center; width: 400px;">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/InteractiveResource" property="dct:title" rel="dct:type">Code to turn on or off data series by clicking on legend entries</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Andrew Gallant</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License</a>.
</div>
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Y 1');
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn('number', 'Y 2');
data.addColumn({type: 'string', role: 'annotation'});
data.addColumn({type: 'boolean', role: 'certainty'});
data.addColumn('number', 'Y 3');
data.addColumn({type: 'boolean', role: 'certainty'});
// add random data
var y1 = 50, y2 = 50, y3 = 50;
for (var i = 0; i < 30; i++) {
y1 += ~~(Math.random() * 5) * Math.pow(-1, ~~(Math.random() * 2));
y2 += ~~(Math.random() * 5) * Math.pow(-1, ~~(Math.random() * 2));
y3 += ~~(Math.random() * 5) * Math.pow(-1, ~~(Math.random() * 2));
data.addRow([i, y1, (~~(Math.random() * 2) == 1), y2, y2.toString(), (~~(Math.random() * 2) == 1), y3, (~~(Math.random() * 2) == 1)]);
}
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
dataTable: data,
options: {
width: 600,
height: 400
}
});
// create columns array
var columns = [0];
/* the series map is an array of data series
* "column" is the index of the data column to use for the series
* "roleColumns" is an array of column indices corresponding to columns with roles that are associated with this data series
* "display" is a boolean, set to true to make the series visible on the initial draw
*/
var seriesMap = [{
column: 1,
roleColumns: [2],
display: true
}, {
column: 3,
roleColumns: [4, 5],
display: true
}, {
column: 6,
roleColumns: [7],
display: false
}];
var columnsMap = {};
var series = [];
for (var i = 0; i < seriesMap.length; i++) {
var col = seriesMap[i].column;
columnsMap[col] = i;
// set the default series option
series[i] = {};
if (seriesMap[i].display) {
// if the column is the domain column or in the default list, display the series
columns.push(col);
}
else {
// otherwise, hide it
columns.push({
label: data.getColumnLabel(col),
type: data.getColumnType(col),
sourceColumn: col,
calc: function () {
return null;
}
});
// backup the default color (if set)
if (typeof(series[i].color) !== 'undefined') {
series[i].backupColor = series[i].color;
}
series[i].color = '#CCCCCC';
}
for (var j = 0; j < seriesMap[i].roleColumns.length; j++) {
columns.push(seriesMap[i].roleColumns[j]);
}
}
chart.setOption('series', series);
function showHideSeries () {
var sel = chart.getChart().getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (typeof(columns[col]) == 'number') {
var src = columns[col];
// hide the data series
columns[col] = {
label: data.getColumnLabel(src),
type: data.getColumnType(src),
sourceColumn: src,
calc: function () {
return null;
}
};
// grey out the legend entry
series[columnsMap[src]].color = '#CCCCCC';
}
else {
var src = columns[col].sourceColumn;
// show the data series
columns[col] = src;
series[columnsMap[src]].color = null;
}
var view = chart.getView() || {};
view.columns = columns;
chart.setView(view);
chart.draw();
}
}
}
google.visualization.events.addListener(chart, 'select', showHideSeries);
// create a view with the default columns
var view = {
columns: columns
};
chart.draw();
}
google.load('visualization', '1', {packages: ['corechart'], callback: drawChart});
Related
Google charts' line chart
So, at the moment, I'm just getting used to google charts. But in future, I'm looking to plot a function. Once that line is drawn, I'd like to add a dynamic indicator circle that will travel along the path of the line as I adjust the values that plotted the line.
So to summarise:
Plot a permanent line from a function*
Have a circle that travels the path of the line as I adjust the values of the function. (main question)
New to google charts and not sure how easily you can do something like this.
To maybe clarify: I will be using a slider to control a value, as I move the slider the line will not change, but an "indicator" circle will change position to fit the new values; i.e. plotting a circle dynamically as the value changes.
Not sure if it helps, but my current graph looks simply like this:
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
drawChart();
function drawChart() {
var data = google.visualization.arrayToDataTable([
['somVar1', 'someVar2'],
['0.001' , 0.02],
['0.003' , 0.07],
['0.01' , 0.2],
['0.03' , 0.6 ],
['0.1' , 1.8],
['0.3' , 4.8],
['1' , 10],
['3' , 15.2 ],
['10' , 18.2 ],
['30' , 19.4],
['100' , 19.8],
['300' , 19.93],
['1000' , 19.98],
]);
//Graph styling and legend
var options = {
title: 'sumVar2 (%)',
curveType: 'function',
legend: { position: 'bottom' },
vAxis: { title: 'someVar2 %'},
hAxis: { title: 'someVar1'}
};
var chart = new google.visualization.LineChart(document.getElementById('lineGraph'));
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="lineGraph" style="width: 900px; height: 500px"></div>
*(unfortunately with google charts, it looks like I have to do this by finding the range of values and spitting them out into an array - rather than being able to plot straight from a mathematical function)
the DataView Class can be used to provide a function as the value for a series
use the setColumns method to set the function
you can pass a column index for an existing DataTable column or
a custom object with the calculation function
here, a DataView is created from a DataTable,
it uses the first column from the DataTable,
the next column is a function
var dataView = new google.visualization.DataView(dataTable);
dataView.setColumns([0, {
calc: function (data, row) {
return (2 * data.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
}]);
you can set multiple column functions,
but you cannot use the values from one function in another,
in the same DataView
to get around, reference the previous DataView in the current function
otherwise, you would have to dump the values to a new table,
then use the new table in another view to set the next function
you can modify the series options to create points rather than a line, i.e.
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
the following working snippet demonstrates how to save a reference to the first function, and use it later, such as when the chart's 'ready' event fires
google.charts.load('current', {
callback: function () {
// DataTable X only
var dataTable = google.visualization.arrayToDataTable([
['X'],
[0.001],
[0.003],
[0.01],
[0.03],
[0.1],
[0.3],
[1],
[3],
[10],
[30],
[100],
[300],
[1000],
]);
// use DataView to provide function for Y
var dataView = new google.visualization.DataView(dataTable);
// y1=2x+7
var yCol1 = {
calc: function (data, row) {
return (2 * data.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
};
// use above object as Y1
dataView.setColumns([0, yCol1]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
// draw Y2 when chart finishes drawing
google.visualization.events.addOneTimeListener(chart, 'ready', function () {
// add Y2 column
dataView.setColumns([0, yCol1, {
// y2=y1+(2x-1)
calc: function (data, row) {
//use reference to previous dataView
return dataView.getValue(row, 1) + ((2 * data.getValue(row, 0)) - 1);
},
type: 'number',
label: 'Y2'
}]);
chart.draw(dataView, {
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
});
});
chart.draw(dataView);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
the same concept can be used to avoid having an array for the X values as well
just need to set an initial number of rows on a DataTable
see following working snippet...
google.charts.load('current', {
callback: function () {
// create blank table for the view
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('number', 'X');
dataTable.addRows(20);
// use DataView to provide function for X
var dataView = new google.visualization.DataView(dataTable);
var xCol = {
calc: function (data, row) {
return (row + 1) * 0.3;
},
type: 'number',
label: 'X'
};
dataView.setColumns([xCol]);
// function for Y --> y1=2x+7
var yCol1 = {
calc: function (data, row) {
return (2 * dataView.getValue(row, 0)) + 7;
},
type: 'number',
label: 'Y1'
};
dataView.setColumns([xCol, yCol1]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.LineChart(container);
// draw Y2 when chart finishes drawing
google.visualization.events.addOneTimeListener(chart, 'ready', function () {
// add Y2 column
dataView.setColumns([xCol, yCol1, {
// y2=y1+(2x-1)
calc: function (data, row) {
//use reference to previous dataView
return dataView.getValue(row, 1) + ((2 * data.getValue(row, 0)) - 1);
},
type: 'number',
label: 'Y2'
}]);
chart.draw(dataView, {
series: {
1: {
lineWidth: 0,
pointSize: 8
}
}
});
});
chart.draw(dataView);
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have an line/area chart, I want to set a minimum range on the y-axis.
Let's say my points are [0,300],[1,270],[2,230],[3,260] (those are retrieved through ajax, so they're not static).
I want the y-axis range to be at least 100, but by default google will set maximum as maximum value (300 in this case), and minimum at minimum value (230 in this case), so range in this case would be (and it is actually) 70, I want it to be at least 100, so the chart maximum should be (300+230)/2+50 and minimum (300+230)/2-50, so that I have a 100 range and the chart i vertically center aligned.
I want the range to have a minimum but not a maximum, if my points are [0,100],[1,240],[5,160] then range should match the data range (140 in this case) also if the optimum is smaller (100).
Basically I don't want the chart to show a big difference when the actual difference in data is small. I know how to set fixed maximum and minimum on axis, but that doesn't solve my problem.
This is my actual code:
$.fn.createChart = function(url,options){
var obj = $(this);
console.log('CREATING CHART: '+url);
// Load the Visualization API and the linechart package.
if(!$.canAccessGoogleVisualization()){
google.charts.load('current', {packages: ['corechart', 'line']});
}
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var jsonData = $.ajax({
url: url ,
dataType: "json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server.
var data = new google.visualization.DataTable(jsonData);
//Default options
var def = {
width: obj.width(),
height: obj.height(),
curveType: 'function',
legend: { position: 'bottom' },
hAxis: {
format: 'dd/MM'
},
animation:{
"startup": true,
duration: 1000,
easing: 'out',
}
};
//Overwrite default options with passed options
var options = typeof options !== 'undefined' ? $.mergeObjects(def,options) : def;
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.AreaChart(obj.get(0));
chart.draw(data, options);
}
}
$.mergeObjects = function(obj1,obj2){
for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }
return obj1;
}
$.canAccessGoogleVisualization = function()
{
if ((typeof google === 'undefined') || (typeof google.visualization === 'undefined')) {
return false;
}
else{
return true;
}
}
you can use the getColumnRange method on the DataTable to find the min and max
then apply you're logic to set the viewWindow on the vAxis
see following working snippet...
google.charts.load('current', {
callback: function () {
var data = google.visualization.arrayToDataTable([
['X', 'Y'],
[0, 300],
[1, 270],
[2, 230],
[3, 260]
]);
var yMin;
var yMax;
var columnRange = data.getColumnRange(1);
if ((columnRange.max - columnRange.min) < 100) {
yMin = ((columnRange.max + columnRange.min) / 2) - 50;
yMax = ((columnRange.max + columnRange.min) / 2) + 50;
} else {
yMin = columnRange.min;
yMax = columnRange.max;
}
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, {
vAxis: {
viewWindow: {
min: yMin,
max: yMax
}
}
});
},
packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I am using Google Visualisation to create line charts for my application. I have following requirements in that :
Manipulating events on legends (like doubleClick, which I have
solved somehow)
Wrapping the legends in two rows avoiding pagination (Most imp and required)
I have gone through the following questions to get solution for my answers:
1) Issue with legend pagination (Google Interactive chart API)
Issue : I would avoid playing with font-size because the number of legends may increase over time
2)How the legends on Google charts can be wrapped
Issue: I do not want legends to be anywhere else than at the position:bottom. And maxLines solution does not work on position : bottom
3) Is there any way I can avoid pagination in legends of a google visualisation chart and show all the lines in two lines in a single page?
Issue: This is another link, which mentions my problem, but no useful answers found on it.
4) Google Documentation :
Heading : Chart Legend Text and Style chdl, chdlp, chdls [All charts]
https://developers.google.com/chart/image/docs/chart_params#axis-label-styles-chxs
Heading : Setting Chart Margines
https://developers.google.com/chart/image/docs/chart_params#chart-margins-chma-all----charts
Heading : Tooltips
https://developers.google.com/chart/interactive/docs/customizing_tooltip_content#tooltips-an-introduction
Comment : These are few google documentation links where few legend manipulating properties are mentioned, but still they does not solve my problem.
5)https://github.com/google/google-visualization-issues/issues/1286
Comment : This is the link where I can see that, google has not provided many properties to manipulate legends, and no much useful information to solve my issue
6) Google charts legend manipulation
Comment : This is the only link, where I got a hint about how to solve my issue i.e. writing own legends. But there is no more links provided for documentation, no jsFiddle or no ref links apart from one link which is not useful for me.
While gone through all these, I can see only solution to solve my problem is to write my own custom legends. But I have no idea about how to write a complete element adding to google API.
Please guide me to go through this, any suggestions/links/refs/hints are welcome.
Thank you.
Example: Build custom legend, which syncs with data and chart...
google.charts.load('44', {
callback: drawChart,
packages: ['controls', 'corechart']
});
function drawChart() {
// adapted from a previous example
var colorPallette = ['#273746','#707B7C','#dc7633','#f1c40f','#1e8449','#2874a6','#6c3483','#922b21'];
var data = new google.visualization.DataTable();
data.addColumn('date', 'X');
data.addColumn('number', 'Y1');
data.addColumn('number', 'Y2');
data.addRow([new Date(2016, 0, 1), 1, 123]);
data.addRow([new Date(2016, 1, 1), 6, 42]);
data.addRow([new Date(2016, 2, 1), 4, 49]);
data.addRow([new Date(2016, 3, 1), 23, 486]);
data.addRow([new Date(2016, 4, 1), 89, 476]);
data.addRow([new Date(2016, 5, 1), 46, 444]);
data.addRow([new Date(2016, 6, 1), 178, 442]);
data.addRow([new Date(2016, 7, 1), 12, 274]);
data.addRow([new Date(2016, 8, 1), 123, 934]);
data.addRow([new Date(2016, 9, 1), 144, 145]);
data.addRow([new Date(2016, 10, 1), 135, 946]);
data.addRow([new Date(2016, 11, 1), 178, 747]);
// use view to add various columns for example purposes
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, 2,
{
calc: function (data, row) {
return data.getValue(row, 1) + data.getValue(row, 2);
},
type: 'number',
label: 'Y3'
},
{
calc: function (data, row) {
return data.getValue(row, 2) - data.getValue(row, 1);
},
type: 'number',
label: 'Y4'
},
{
calc: function (data, row) {
return data.getValue(row, 1) * 2;
},
type: 'number',
label: 'Y5'
},
{
calc: function (data, row) {
return data.getValue(row, 2) * 3;
},
type: 'number',
label: 'Y6'
},
{
calc: function (data, row) {
return data.getValue(row, 1) * 1.5;
},
type: 'number',
label: 'Y7'
},
{
calc: function (data, row) {
return data.getValue(row, 1) * 1.5;
},
type: 'number',
label: 'Y8'
}
]);
var control = new google.visualization.ControlWrapper({
controlType: 'DateRangeFilter',
containerId: 'control_div',
options: {
filterColumnIndex: 0
}
});
var chart = new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart_div',
options: {
chartArea: {
width: '80%'
},
// add colors for legend mapping
colors: colorPallette,
hAxis: {
format: 'MMM',
slantedText: false,
maxAlternation: 1
},
legend: 'none',
width: 320
}
});
// 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');
// colors from chart
var colorPallette = chart.getOption('colors');
// clear previous legend
legend.innerHTML = '';
// add legend marker for each Y axis column - skip X axis --> i = 1
for (var i = 1; i < chart.getDataTable().getNumberOfColumns(); i++) {
var markerProps = {};
markerProps.index = i;
markerProps.color = colorPallette[i - 1];
markerProps.label = chart.getDataTable().getColumnLabel(i);
addLegendMarker(markerProps);
}
// add click event to each legend marker
var markers = legend.getElementsByTagName('DIV');
Array.prototype.forEach.call(markers, function(marker) {
marker.addEventListener('click', function (e) {
var marker = e.target || e.srcElement;
if (marker.tagName.toUpperCase() !== 'DIV') {
marker = marker.parentNode;
}
var columnIndex = parseInt(marker.getAttribute('data-columnIndex'));
document.getElementById('message_div').innerHTML = 'legend marker clicked = ' + chart.getDataTable().getColumnLabel(columnIndex);
}, false);
});
});
var dash = new google.visualization.Dashboard(document.getElementById('dashboard'));
dash.bind([control], [chart]);
dash.draw(view);
}
#legend_div {
text-align: center;
width: 320px;
}
.legend-marker {
display: inline-block;
padding: 16px 4px 8px 4px;
}
.legend-marker-color {
display: inline-block;
height: 12px;
width: 12px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="chart_div"></div>
<div id="legend_div"></div>
<br/>
<div id="control_div"></div>
<br/>
<div id="message_div"></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>
if ($("#source svg text[text-anchor='end']").length > 0){
var n = $("#source svg text[text-anchor='end']").length;
$("#source svg text[text-anchor='end']")[n-5].innerHTML = "";
$("#source svg text[text-anchor='end']")[n-4].innerHTML = "Create your own legend";
$("#source svg text[text-anchor='end']")[n-3].innerHTML = "Create your own legend";
$("#source svg text[text-anchor='end']")[n-2].innerHTML = "Create your own legend";
$("#source svg text[text-anchor='end']")[n-1].innerHTML = "";
}
i need to highlight y value example 20 to -10 and -30 to -45 in y axis. permanently with some color with opacity 50%, how to do.,
in this example how to add external csv file to this following code. Pls Guide me
var orig_range;
window.onload = function(){ var r = [];
var arr = ["7/13/2015 0:15:45",45,"7/13/2015 0:30",5,"7/13/2015 0:45",100,"7/13/2015 1:00",95,"7/13/2015 1:15",88,"7/13/2015 1:30",78];
for (var i = 0; i < arr.length; i++) {
r.push([ new Date(arr[i]),arr[i+1]
]);
i++;
}
orig_range = [ r[0][0].valueOf(), r[r.length - 1][0].valueOf() ];
g2 = new Dygraph(
document.getElementById("div_g"),
r, {
rollPeriod: 7,
animatedZooms: true,
// errorBars: true,
width: 1000,
height: 500,
xlabel: 'date',
ylabel: 'Pressure',
}
);
var desired_range = null;};
function approach_range() {
if (!desired_range) return;
// go halfway there
var range = g2.xAxisRange();
if (Math.abs(desired_range[0] - range[0]) < 60 &&
Math.abs(desired_range[1] - range[1]) < 60) {
g2.updateOptions({dateWindow: desired_range});
// (do not set another timeout.)
} else {
var new_range;
new_range = [0.5 * (desired_range[0] + range[0]),
0.5 * (desired_range[1] + range[1])];
g2.updateOptions({dateWindow: new_range});
animate();
}
}
function animate() {
setTimeout(approach_range, 50);
}
function zoom(res) {
var w = g2.xAxisRange();
desired_range = [ w[0], w[0] + res * 1000 ];
animate();
}
function reset() {
desired_range = orig_range;
animate();
}
function pan(dir) {
var w = g2.xAxisRange();
var scale = w[1] - w[0];
var amount = scale * 0.25 * dir;
desired_range = [ w[0] + amount, w[1] + amount ];
animate();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.0/dygraph-combined-dev.js"></script>
<div id="div_g"></div>
<div id="output"></div>
<b>Zoom:</b>
hour
day
week
month
full
<b>Pan:</b>
left
right
i'm trying to convert graph to dynamic graph data from csv file
var data = ["te1.csv"];
g2 = new Dygraph(document.getElementById("div_g"), data,
{
drawPoints: true,
showRoller: true,
labels:['date','depth'],
});
setInterval(function() {
data.push([data]);
g2.updateOptions( { 'file': data } );
}, 1000);
i have seen example but i dont know how to link my csv file with dynamic dygraph pls guide me
This example does something extremely similar to what you want: it highlights a specific range on the x-axis. To adapt it, you'd do something like this:
new Dygraph(data, div, {
underlayCallback: function (canvas, area, g) {
var bottom = g.toDomYCoord(highlight_start);
var top = g.toDomYCoord(highlight_end);
canvas.fillStyle = "rgba(255, 255, 102, 1.0)";
canvas.fillRect(area.x, top, area.w, bottom - top);
}
})
Just starting with Angular. I need to incorporate Google Charts into an Angular app.
Found this plunk (code posted in snippet below), illustrating how to use Google Charts within a directive:
<html xmlns="http://www.w3.org/1999/html">
<head>
<title>
Google Chart Tools AngularJS Directive Example
</title>
</head>
<body ng-app="google-chart-example" ng-controller="MainCtrl">
<h1>Google Chart Tools AngularJS Directive Example</h1>
<p>This is probably the most simple example you can get. It
just shows you what you need to get the Google Chart Tools AngularJS Directive to work.
</p>
<div>
<div google-chart chart="chart" style="{{chart.cssStyle}}"/>
</div>
<p>
Here are the steps:
<ol>
<li>Download ng-google-chart.js from github and add a script tag to your html.</li>
<li>Create a div like: <b><pre ng-non-bindable> <div google-chart chart="chart" style="{{chart.cssStyle}}"/></pre></b></li>
<li>Add 'googlechart' to your module like this: <b><pre>angular.module('myApp',[ 'googlechart', ...</pre></b></li>
<li>Populate the <b>$scope.chart</b> like this:</li>
</ol>
<pre>{{chart | json}}</pre>
</p>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<script src="http://bouil.github.io/angular-google-chart/ng-google-chart.js"></script>
<script src="example.js"></script>
</body>
</html>
One of my requirements is to enable users to toggle visibility of an individual chart series on and off, either by clicking on the corresponding legend, or in some similar way.
I also found this JSFiddle example of toggling visibility on and off outside of Angular:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'x');
data.addColumn('number', 'y1');
data.addColumn('number', 'y2');
data.addColumn('number', 'y3');
// add random data
var y1 = 50, y2 = 50, y3 = 50;
for (var i = 0; i < 100; i++) {
y1 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y2 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
y3 += Math.floor(Math.random() * 5) * Math.pow(-1, Math.floor(Math.random() * 2));
data.addRow([i, y1, y2, y3]);
}
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
// create columns array
var columns = [];
// display these data series by default
var defaultSeries = [1, 3];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
if (i == 0 || defaultSeries.indexOf(i) > -1) {
// if the column is the domain column or in the default list, display the series
columns.push(i);
}
else {
// otherwise, hide it
columns.push({
label: data.getColumnLabel(i),
type: data.getColumnType(i),
sourceColumn: i,
calc: function () {
return null;
}
});
}
if (i > 0) {
columns.push({
calc: 'stringify',
sourceColumn: i,
type: 'string',
role: 'annotation'
});
// set the default series option
series[i - 1] = {};
if (defaultSeries.indexOf(i) == -1) {
// backup the default color (if set)
if (typeof(series[i - 1].color) !== 'undefined') {
series[i - 1].backupColor = series[i - 1].color;
}
series[i - 1].color = '#CCCCCC';
}
}
}
var options = {
width: 600,
height: 400,
series: series
}
function showHideSeries () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (typeof(columns[col]) == 'number') {
var src = columns[col];
// hide the data series
columns[col] = {
label: data.getColumnLabel(src),
type: data.getColumnType(src),
sourceColumn: src,
calc: function () {
return null;
}
};
// grey out the legend entry
series[src - 1].color = '#CCCCCC';
}
else {
var src = columns[col].sourceColumn;
// show the data series
columns[col] = src;
series[src - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
}
google.visualization.events.addListener(chart, 'select', showHideSeries);
// create a view with the default columns
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
google.load('visualization', '1', {packages: ['corechart']});
google.setOnLoadCallback(drawChart);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="chart_div"></div>
<div id="creativeCommons" style="text-align: center; width: 400px;">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/InteractiveResource" property="dct:title" rel="dct:type">Code to turn on or off data series by clicking on legend entries</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Andrew Gallant</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License</a>.
</div>
I'm so terribly inexperienced with JavaScript, I do not know how to combine the two, to end up with a directive, which would include this visibility toggle feature.
If anyone knows how this is done, I would really be grateful.