Google Visualization ChartWrapper set cell value programmatically - javascript

When I click on a line item a Google visualization ChartWrapper table, I want to programmatically update the product value in the row that was clicked.
I'm getting stuck here: dataTable.setValue(row, col, valNew);
According to the documentation I should be able to use setValue to update a value in the datable. I'm getting error "setValue is not a function".
Hoping that someone can point me in the right direction...
Here is my code so far. The problem is in the selectHandler_table_db function.
google.charts.load('current', {
packages: ['table', 'controls']
}).then(function() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('string', 'Product');
data.addColumn('number', 'Quantity');
var dt1 = new Date(moment().endOf('month').subtract(3, 'month'));
var dt2 = new Date(moment().endOf('month').subtract(2, 'month'));
var dt3 = new Date(moment().endOf('month').subtract(1, 'month'));
var dt4 = new Date(moment().startOf('month'));
var dt5 = new Date(moment().startOf('month').add(1, 'day'));
var dt6 = new Date(moment().startOf('month').add(2, 'day'));
data.addRows([
[dt1, 'a', 100],
[dt2, 'b', 200],
[dt3, 'a', 300],
[dt4, 'b', 400],
[dt5, 'a', 500],
[dt6, 'b', 600],
]);
var view = new google.visualization.DataView(data);
example_dashboard(view);
});
function example_dashboard(view) {
var dashboard = new google.visualization.Dashboard(document.getElementById('div_dashboard'));
var categoryPicker1 = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'div_categoryPicker1',
options: {
filterColumnIndex: view.getColumnIndex('Product'),
matchType: 'any',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false,
allowNone: true
}
}
});
var table_db = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'div_table',
options: {
width: '100%',
height: 'auto',
}
});
dashboard.bind(categoryPicker1, table_db);
dashboard.draw(view);
google.visualization.events.addListener(table_db, 'select', selectHandler_table_db);
function selectHandler_table_db() {
let chartWrapper = table_db.getChart();
let dataTable = table_db.getDataTable();
let row = chartWrapper.getSelection()[0].row;
let col = 1;
let valNew = "c";
//This errors dataTable.setValue is not a function
dataTable.setValue(row, col, valNew);
chartWrapper.draw();
} //END selectHandler_table
} //END example_dashboard(){
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id='div_dashboard'>
<div id='div_categoryPicker1'></div>
<div id="div_table"></div>
</div>

the error occurs because you are using a DataView to draw the Dashboard,
which is the object returned from the ChartWrapper, and not a DataTable.
you could resolve by passing the DataTable instead,
example_dashboard(data); // use data table here
it doesn't appear you are modifying the data using the view.
or if that code just isn't included here,
you can convert the DataView to a DataTable, before drawing the dashboard...
example_dashboard(view.toDataTable()); // convert view to DataTable

Related

Google Charts: Registering a click on a GeoChart

I've been working on a small project to make a map of, in this case The Netherlands, with a bunch of markers on it. The data is provided through a CSV and i've linked the chart and a slider through a dashboard.
It's worked perfectly so far, however i'm having issues on the next functionality: Registering a click on a marker and then referring the user to a different webpage depending on which marker was clicked.
I've tried many times to get it to work, but i believe it has something to do with the fact that i'm using chartWrappers instead of a normal chart.
Here is my current code:
google.charts.load('current', {
'packages':['geochart', 'controls'],
});
google.charts.setOnLoadCallback(drawMarkersMap);
function drawMarkersMap() {
$.get("output.csv", function(csvString) {
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
var data = google.visualization.arrayToDataTable(arrayData)
var dashboard = new google.visualization.Dashboard(document.getElementById('controls_div'));
var Slider = new google.visualization.ControlWrapper({
controlType: 'NumberRangeFilter',
containerId: 'controls_div',
options: {
filterColumnLabel: data.getColumnLabel(1)
}
});
var GeoChart = new google.visualization.ChartWrapper({
chartType: 'GeoChart',
containerId: 'chart_div',
options: {
region: 'NL',
displayMode: 'markers',
resolution: 'provinces',
colorAxis: {colors: ['green', 'blue']}
}
});
google.visualization.events.addListener(GeoChart, 'select', function() {
var selection = GeoChart.getChart().getSelection();
//Above line doesn't work. Console also returns that getSelection property is null.
});
dashboard.bind(Slider, GeoChart);
dashboard.draw(data);
})};
If anyone with experience could help me properly set up a working listener i'd be eternally grateful.
you were right about wrapper vs. regular
the chart wrapper does not have an event for 'select'
you have to wait until the wrapper is 'ready',
then listen for 'select' on the chart,
see following snippet...
google.visualization.events.addListener(GeoChart, 'ready', function() {
google.visualization.events.addListener(GeoChart.getChart(), 'select', function() {
var selection = GeoChart.getChart().getSelection();
});
});
see following working snippet...
google.charts.load('current', {
packages:['controls', 'geochart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Country', 'Popularity', 'Domain'],
['England', 400, 'www.example.com/England'],
['Wales', 300, 'www.example.com/Wales'],
['Scotland', 400, 'www.example.com/Scotland'],
['Ireland', 600, 'www.example.com/Ireland'],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1]);
var GeoChart = new google.visualization.ChartWrapper({
chartType: 'GeoChart',
containerId: 'chart_div',
dataTable: view,
options: {
region: 'GB',
displayMode: 'markers',
resolution: 'provinces',
colorAxis: {colors: ['green', 'blue']}
}
});
google.visualization.events.addListener(GeoChart, 'ready', function () {
google.visualization.events.addListener(GeoChart.getChart(), 'select', function () {
var selection = GeoChart.getChart().getSelection();
if (selection.length > 0) {
console.log(data.getValue(selection[0].row, 2));
//window.open('http://' + data.getValue(selection[0].row, 2), '_blank');
}
});
});
GeoChart.draw();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

1 Event Handler for 2 Google Charts

So, I have two Google bar charts displayed on the same page.I tried creating one event handler for both of them and passing in the chart and data into the selectHandler. Can someone tell me what I'm doing wrong?
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data1 = google.visualization.arrayToDataTable([
['Condition', 'Frequency'],
['Dementia', 6081],
['Hypertension', 6055],
['Hypercholesterolemia', 6035],
]);
var data2 = google.visualization.arrayToDataTable([
['Medication', 'Frequency'],
['Naproxen', 7632],
['Plavix', 7486]
]);
var options1 = {
title: 'Medical Conditions',
};
var options2 = {
title: 'Medications',
};
var conditionbarchart = new google.charts.Bar(
document.getElementById('conditions_chart'));
conditionbarchart.draw(data1, options1);
var medchart = new google.visualization.ColumnChart(
document.getElementById('medications_chart'));
medchart.draw(data2, options2);
google.visualization.events.addListener(conditionbarchart, 'select', selectHandler(conditionbarchart, data1));
google.visualization.events.addListener(medchart, 'select', selectHandler());
}
function selectHandler(mychart, mydata){
var selectedItem = mychart.getSelection()[0];
if(selectedItem){
var selection = mydata.getValue(selectedItem.row, 0);
alert('The user selected' + selection);
}
}
Here's the complete solution to answer my question:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Load the Visualization API and the piechart package.
google.charts.load('current', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Condition');
data.addColumn('number', 'Frequency');
data.addRows([
['Dementia', 3],
['Hypertension', 1],
['Hypercholesterolemia', 1],
['Coronary artery disease', 1],
['Heaches', 2]
]);
// Create the data table.
var data2 = new google.visualization.DataTable();
data2.addColumn('string', 'Medication');
data2.addColumn('number', 'Frequency');
data2.addRows([
['Naproxen', 3],
['Plavix', 1],
['Lasix', 1],
['Insulin', 1],
['Neurontin', 2]
]);
// Set chart options
var options = {
bars: 'vertical', // Required for Material Bar Charts.
hAxis: {
slantedText:true,
slantedTextAngle:90
},
height: 400,
backgroundColor: {fill: 'transparent'},
legend: {position: 'none'},
colors: ['#1b9e77']
};
// Set chart options
var options2 = {
bars: 'vertical', // Required for Material Bar Charts.
hAxis: {
slantedText:true,
slantedTextAngle:90
},
height: 400,
backgroundColor: {fill: 'transparent'},
legend: {position: 'none'},
colors: ['#1b9e77']
};
// Instantiate and draw our chart, passing in some options.
var conditionsbarchart = new google.visualization.ColumnChart(document.getElementById('conditions_chart'));
var medchart = new google.visualization.ColumnChart(document.getElementById('medications_chart'));
function selectHandler(mychart, mydata) {
var selectedItem = mychart.getSelection()[0];
if (selectedItem) {
var topping = mydata.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
}
google.visualization.events.addListener(conditionsbarchart, 'select', function(){
selectHandler(conditionsbarchart, data);
});
conditionsbarchart.draw(data, options);
google.visualization.events.addListener(medchart, 'select', function(){
selectHandler(medchart, data2);
});
medchart.draw(data2, options2);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="conditions_chart" style="width:400; height:300"></div>
<div id="medications_chart" style="width: 400; height: 300"></div>
</body>
</html>

Getting Type of Google Chart

I was looking through the API and couldn't find anything about getting the type of chart.
I have this code:
<script type="text/javascript">
var chart;
function drawTest( dataTable ) {
google.load("visualization", "1", {packages:["corechart"]});
var options = {
title: 'test chart',
hAxis: {title: 'Day', titleTextStyle: {color: 'black'},
animation: {
duration: 1000,
easing: 'out',
}}
};
var data = new google.visualization.DataTable();
data.addColumn('string', 'String');
data.addColumn('number', 'Number1');
data.addColumn('number', 'Number2');
dataTable.forEach( function(row) {
data.addRow( row );
} );
chart = new google.visualization.ColumnChart( document.getElementById( 'chart' ) );
chart.draw( data, options );
}
What I want to do is instead of setting chart to a new chart in the bottom I want to check if it's already set. I'm not sure if this is in the API.
if( chart.getType() == "ColumnChart" ){
chart.draw( data, options );
}
However, I have multiple charts so I can't just check if chart is initialized.
Any help about completing this task is appreciated.
If you use a chartWrapper instead, there is a getChartType method that returns the class name of the wrapped chart. You can view more info about chartWrapper class here:
https://developers.google.com/chart/interactive/docs/reference#chartwrapperobject
Here is an example using google visualization playground:
function drawVisualization() {
// Create and populate the data table.
var wrapper = new google.visualization.ChartWrapper({
chartType: 'ColumnChart',
dataTable: [['', 'Germany', 'USA', 'Brazil', 'Canada', 'France', 'RU'],
['', 700, 300, 400, 500, 600, 800]],
options: {'title': 'Countries'},
containerId: 'visualization'
});
wrapper.draw();
console.log(wrapper.getChartType()) // ColumnChart
}

Table chart giving link button

<script type="text/javascript">
function drawVisualization2(dataValues, chartTitle, columnNames, categoryCaption) {
if (dataValues.length < 1)
return;
var data = new google.visualization.DataTable();
data.addColumn('string', columnNames.split(',')[0]);
data.addColumn('string', columnNames.split(',')[1]);
data.addColumn('string', columnNames.split(',')[2]);
data.addColumn('number', columnNames.split(',')[3]);
data.addColumn('number', columnNames.split(',')[4]);
data.addColumn('number', columnNames.split(',')[5]);
data.addColumn('string', 'Email');
for (var i = 0; i < dataValues.length; i++) {
data.addRow([dataValues[i].Value1, dataValues[i].Value2, dataValues[i].Value3, dataValues[i].Value4, dataValues[i].Value5, dataValues[i].Value6, 'www.google.in']);
}
var formatter = new google.visualization.NumberFormat({ pattern: '####%' });
formatter.format(data, 5);
var formatter = new google.visualization.PatternFormat('{4}');
formatter.format(data, [4, 6]);
var view = new google.visualization.DataView(data);
view.setColumns([0,1,2,3,4,5]);
var categoryPicker2 = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'containerId': 'Container1',
'options': {
'filterColumnLabel': columnNames.split(',')[1],
'ui': {
'labelStacking': 'horizontal',
'allowTyping': false,
'allowMultiple': false,
'caption': categoryCaption,
'label': columnNames.split(',')[2]
}
}
});
var table2 = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'TableContainer2',
'options': {
'width': '895px',
'page': 'enable',
'pageSize': 5
}
});
new google.visualization.Dashboard(document.getElementById('PieChartExample2')).bind([categoryPicker2], [table2]).draw(view, { allowHtml: true, showRowNumber: true });
//visualization.draw(view, { allowHtml: true, showRowNumber: true });
}
</script>
I am facing a problem on table chart adding link button ;here is my code.And column 7 need to go google;First tried with simple table,it works fine;but in case of controls and dashboard ;its not i tried bur could can anyone help me to resolve.Thank you..
That looks mostly fine. Just set the Table's allowHtml option to true:
var table2 = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'TableContainer2',
'options': {
'width': '895px',
'page': 'enable',
'pageSize': 5,
allowHtml: true
}
});
Also, trying to set options in the Dashboard's draw call will not do anything, so remove the second argument:
new google.visualization.Dashboard(document.getElementById('PieChartExample2')).bind([categoryPicker2], [table2]).draw(view);

How to get selectedRow data properly from table after change the state of ControlWrapper?

How to get selectedRow data properly from table after change the state of ControlWrapper? Here In my table select on first row(after change state using controlWrapper dropdown) returns 0,but I need 3,then only I get proper row data.
var myControlWrapper = new google.visualization.ControlWrapper({
'controlType': 'CategoryFilter',
'view': {
'columns': [1, 2, 3, 4, 7, 8]
},
'containerId': 'details_category_filter_container',
'options': {
'filterColumnLabel': 'P',
'ui': {
'matchType': 'any',
'label': '',
'caption': 'All',
'labelStacking': 'horizontal',
'allowTyping': false,
'allowMultiple': false,
}
},
'state': {
'selectedValues': ['A']
}
});
var table = new google.visualization.ChartWrapper({
'chartType': 'Table',
'containerId': 'my_details_table',
'options': {
'allowHtml': true,
'alternatingRowStyle': true,
'width': '100%',
'max-height': '600px'
}
});
// Create the dashboard.
var details_Table_DashBoard = new google.visualization.Dashboard(document.getElementById('my_details_table')).bind(myControlWrapper, table).draw(view);
google.visualization.events.addListener(table, 'ready', function () {
google.visualization.events.addListener(table.getChart(), 'select', function () {
var visualizationTable = table.getChart();
if (visualizationTable.getSelection()[0] !== undefined) {
var currentRow = visualizationTable.getSelection()[0].row;
// Here currentRow returns 0,if I select first row after filtered,but it is third row in view(before filtered)
var name = dataTable.getFormattedValue(currentRow, 2);
var time = dataTable.getFormattedValue(currentRow, 3);
}
});
});
You can reference the data used by the Table by calling the ChartWrapper
s getDataTable method:
[edit - added row translation to the underlying DataTable, assumes there are no other DataViews used]
google.visualization.events.addListener(table, 'ready', function () {
google.visualization.events.addListener(table.getChart(), 'select', function () {
var visualizationTable = table.getChart();
if (visualizationTable.getSelection()[0] !== undefined) {
var currentRow = visualizationTable.getSelection()[0].row;
var dt = table.getDataTable();
// get the row index in the underlying DataTable/DataView
// you will need to do this for each DataView that sits between your ChartWrapper and the base DataTable
rowIndex = dt.getTableRowIndex(currentRow);
var name = dataTable.getFormattedValue(rowIndex, 2);
var time = dataTable.getFormattedValue(rowIndex, 3);
}
});
});

Categories