How to change chart position in Google Sheets? - javascript

I currently have a script that takes data, formats it, and creates a chart below the data.
I know how to move the chart within the tab using setPosition, but can't figure out how to write the chart to a different tab (to create a 'dashboard' where you wouldn't have to see all of the source data). Any ideas on this?
I've tried changing what's in .setPosition, but that only moves the chart within the existing tab.
I've also had glitches with this where I've gotten the chart to move to the right of the data in some cases, but using the same code in a different sheet it doesn't write the chart at all.
Here's the code I'm working with:
var chartTitle = columnHeader;
if (typeof subtitle[columnHeader] != 'undefined') {
chartTitle = chartTitle + " - " + subtitle[columnHeader];
}
var chartBuilder = sheet.newChart()
.setChartType(Charts.ChartType.LINE)
.setOption('chartArea', {left:'10%',top:'15%',width:'80%',height:'70%'})
.setPosition(4 + output.length, 1, 0, 0)
.setOption('width', width)
.setOption('height', 500)
.setOption('title', chartTitle)
.setOption('legend', {position: 'top'});
var statFormat = {CPC: 'currency', CTR: 'percent', Impressions: 'decimal', Searches: 'decimal'};
if (statsInChart.length == 0) {
chartBuilder.setOption('vAxes', {
// Adds titles to the axis.
0: {title: columnHeader} });
} else if (statsInChart.length == 1) {
chartBuilder.setOption('vAxes', {
// Adds titles to both axes.
0: {title: columnHeader} ,
1: {title: statsInChart[0], format: statFormat[statsInChart[0]]}});
} else {
chartBuilder.setOption('vAxes', {
// Adds title to the first axis, blanks the others.
0: {title: columnHeader} ,
1: {format: statFormat[statsInChart[0]], textPosition: 'in'},
2: {format: statFormat[statsInChart[1]], textPosition: 'out'},
3: {textStyle: {color: 'white'}}
});
}

The code you provided does not cover when you actually build the chart, nor when you insert it into a sheet.
When you create the EmbeddedChartBuilder by calling the sheet.newChart() method, you have a sheet object that's associated with a particular sheet within the spreadsheet.
What you want to do is call the insertChart() method with a different sheet object, one that is associated with the sheet where you'd like the chart to appear.
Here's a small example:
function createChart() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheetByName('data');
var chartSheet = ss.getSheetByName('chart');
var dataRange = dataSheet.getDataRange();
var chart = chartSheet.newChart()
.addRange(dataRange)
.setPosition(1, 1, 0, 0)
.build();
chartSheet.insertChart(chart);
}
In my test spreadsheet, I have two sheets. One is named data and it contains a small table of data. The other is a blank sheet named chart.
When I execute the above function, a chart is placed in the chart sheet based on the data extracted from the data sheet.

Related

Chart.js can't push dataset to charts made dynamically

I am currently making a web application where users can add their own chart panels, and can then drag certain database tables into said panel to make it show in the chart. My problem is that I can't push datasets into the dynamically created charts, because the variable which holds the chart are not written directly in the document, so the function I made to push those datasets can't push to the variables like it would normally.
Here's the function to make new panels and charts:
function addnewchart(x) {
eval("ctx" + x + "= document.getElementById('linechart" + x + "').getContext('2d');");
eval("var lineChart" + x + " = new Chart(ctx" + x + ", {type: 'line',data: {labels: '',datasets: ''},options: {legend: {display: false},scales: {xAxes: [{gridLines: {display: false},scaleLabel: {display: true,labelString: ''}}],yAxes: [{ticks: {beginAtZero: true},scaleLabel: {display: true,labelString: ''}}]}}});");
};
And this is the function to push datasets to those charts:
function addData(chart, Datalabel, Tabledata) {
datasintable.push(Tabledata + "S");
var curColor = randomColor();
var newDataset =
{
label: Datalabel,
fill: false,
backgroundColor: curColor,
borderColor: curColor,
data: Tabledata
}
console.log(chart,Datalabel,Tabledata, newDataset);
chart.data.labels.push(['test1', 'test2', 'test3', 'test4', 'test5']);
chart.data.datasets.push(newDataset);
chart.update();
}
How should I approach this problem?
Apparently, the way to fix this was instead of using the variable chart in addData(), use window[chartname + index] when manipulating dynamically created charts. I found this out by trying to point to the chart by using both eval() and window[]. Eval didn't work at all, but Window did the trick.
Example:
var number = 1;
window['linechart' + number];
This will call chart linechart1.

How to add color to horizontal bar graphs created by giving csv as an input using google charts?

I am a newbie to front end development. I am trying a demo example given on Google charts website. I am reading data from a csv file and able to generate a horizontal bar graph. Now i want to give colors to those bars but don't want to write those column names every time.
Below is the code i am referring to. How to read column names run time and color those bars?
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
$.get("name.csv", function(csvString) {
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
var data = new google.visualization.arrayToDataTable(arrayData);
var view = new google.visualization.DataView(data);
view.setColumns([0,1]);
var options = {
title: "Your data in bar format" ,
hAxis: {title: data.getColumnLabel(0), minValue: data.getColumnRange(0).min, maxValue: data.getColumnRange(0).max},
vAxis: {title: data.getColumnLabel(1), minValue: data.getColumnRange(1).min, maxValue: data.getColumnRange(1).max},
legend: 'none'
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(view, options);
} );
}
looking at the code, the bars are actually represented by rows, not columns.
there are only two columns in the DataView --> view.setColumns([0, 1]);
first column is the name, second the value...
when using rows for the bars, the only way to provide a specific color,
is to use a 'style' column,
you can add using a calculated column in the DataView.
the style column should follow the series column
i'm not sure how you want to assign each color,
but here is an example of adding the calculated 'style' column.
you can read the name using --> dt.getValue(row, 0)
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
role: 'style',
type: 'string',
calc: function (dt, row) {
var color;
switch (dt.getValue(row, 0)) {
case 'A':
color = 'red';
break;
case 'B':
color = 'blue';
break;
default:
color = 'green';
}
return color;
}
}]);

Add custom parameter to info.contentsFunction

I need to be able to add some custom info to the pie.info.contentsFunction in Zoomcharts. I have multiple charts on the page, each one created like so...
var pc = new PieChart({
pie: {
innerRadius: 0.5,
},
container: chartContainer1,
area: { height: 500 },
data:chartData,
toolbar: {
"fullscreen": true,
"enabled": true
},
info: {
contentsFunction: boomChartTT
}
});
In the "boomChartTT" function I need to know what chart is being hovered upon. I'd like to be able to do something like this...
info: {
contentsFunction: boomChartTT(i)
}
...where 'i' is the index of the chart.
The reason I need to know the chart index is because I have some other data saved in an indexed array for each chart. The index of the chart matches the index of the data.
EXAMPLE: if user hovers on a slice in chart2 I'd want to pass '2' to the boomChartTT function so I can access the totals data for that chart (say, totalsData[2]).
I've done this in the past with other chart libraries by simply adding a data attribute to the chart container to give me the index like so...
<div id="chartContainer1" data-index="1"></div>
...and then I'm able to access the chartContainer from the hover function (contentsFunction) and then get that index.
I don't want to add the totals data to the actual chart data because I'd have to add it to each slice which is redundant.
Is there a way to do this?
Please let me know if my post is unclear.
EDITED TO ADD:
I don't think it matters but here is the boomChartTT function:
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
//var thisData=dataSearch(totalsData[i],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
The commented line is where I would need the index (i) to to get the correct totalsData.
SOLVED. I simply added "chartIndex" to the data like so...
for(var i=0;i<r.length;i++){
var thisDataObj ={
id:r[i].REFERRINGSITE,
value:r[i].PCTOFSALES,
name:r[i].REFERRINGSITE,
chartIndex: arguments[1],//<----- arguments[1] is the chart index
style: { expandable: false, fillColor: dataSearch(dataRSList,"REFERRINGSITE",r[i].REFERRINGSITE)[0].COLOR }
};
chartData.preloaded.subvalues.push(thisDataObj);
}
Then in the boomChartTT function...
function boomChartTT(data,slice){
var tt="<div class=\"charttooltip\">";
if(data.name==="Others" || data.name==="Previous"){return tt+=data.name+"</div>";}
var thisData=dataSearch(totalsData[data.chartIndex-1],"REFERRINGSITE",data.id);
tt+="<h5 class=\"strong\">"+data.id+"</h5>"+oHoverTable.render(thisData)+"</div>";
return tt;
}
I feared that adding custom fields to the chart data would break the chart (which I believe I've experienced with other libraries). So, there you go.

How to color Google Column Chart's every bar differently and keep them as it is

Though I have successfully colored the bars of google chart individually but not able to keep them when we hover mouse over it. It is getting reset back to blue(which is default).
Here is the jsfiddle of what I have done jsfiddle.
I tried to control the hover behaviour with multiple ways like below.
This I am keeping outside (document.ready) but inside script tag.
1)
$('#chart_div').hover(
function() {
$('#chart_client').hide(); // chart_client is another google chart div.
}, function() { // just for testing I was doing hide/show of that.
$('#chart_client').show();
}
);
2)
$("#chart_div").on({
mouseenter: function () {
$('#chart_client').hide();
},
mouseleave:function () {
$('#chart_client').show();
}
},'rect');
3)
google.visualization.events.addListener('#chart_div', 'ready', function () {
$('#chart_div rect').mouseover(function (e) {
alert('hello');
});
});
I must be doing something wrong, could you please tell me what and where.
I solved it using below code. Earlier I was trying to create charts using dynamically adding rows into chart(please visit my jsfiddle) but with this below approach I am first preparing data(converting dynamic to static) and adding that static data in to chart's 'arrayToDataTable' method.
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawUserKeywordChart);
function drawUserKeywordChart() {
var val = 'Tax:47;Finance:95;Awards:126;Bank:137;Debt:145;';
var length = val.length;
var array = [];
//preparing data
while(length>0){
var sepAt = val.indexOf(";");
var value = parseInt(val.substring(val.indexOf(":")+1, sepAt));
array.push(val.substring(0, val.indexOf(":")));
array.push(value);
val = val.substring(val.indexOf(";")+1, length);
length = val.length;
}
var data = google.visualization.arrayToDataTable([
['Keyword', 'Occurences', { role: 'style' }],
[array[0], array[1], '#8AA3B3'],
[array[2], array[3], '#A9B089'],
[array[4], array[5], '#848C49'],
[array[6], array[7], '#44464A'],
[array[8], array[9], '#704610'],
]);
var options = {
title: 'Keyword Matches',
width: 660,
height: 450,
titleTextStyle:{bold:true,fontSize:20},
legend:{position:'none'}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_keyword1'));
chart.draw(data, options);
}
Please advice if you find anything wrong here or you have better approach than this.

Google Charts Threshold?

Is it possible to develop a threshold with Google Charts?
I have a Google combo chart with 5 columns. In theory, I wanted to use the addRange formatter function to change the color of the 2nd column if it was under 50. (Basically it's a motivation tool. Your daily goal is to make atleast 50 calls. If you do not, the chart shows up as red, if you do, then it is the default color)
This is my current code that creates the chart, just not the formatting. Thanks.
// Load the Visualization API and the piechart package.
google.load('visualization', '1.0', {'packages':['corechart']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawChart);
// Callback that creates and populates a data table,
// instantiates the pie chart, passes in the data and
// draws it.
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Rep');
data.addColumn('number', 'Yesterday');
data.addColumn('number', 'Last 7');
data.addColumn('number', 'Last 30');
data.addColumn('number', 'The Bar');
$("#data-table thead th").each(function(){
var initials = $(this).text();
var yesterday = parseInt($("." + initials + ".Yesterday").text());
var seven = parseInt($("." + initials + ".seven").text());
var thirty = parseInt($("." + initials + ".thirty").text());
data.addRow([initials, yesterday, seven, thirty, 50]);
});
// Set chart options
var title = $("#data-table caption").text();
var options = {'title':title,
seriesType: 'bars',
series: {3: {type: "line"}},
hAxis: {title: 'Rep'},
vAxis: {title: 'Outbound Calls'}
};
var formatter = new google.visualization.TableColorFormat();
formatter.addRange(50,0, 'red', '#000');
formatter.format(data, 1);
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.ComboChart(document.getElementById('call-log'));
chart.draw(data, options);
}
The easiest way to do this is to do a quick check on your data, and set a variable for the color of series two based on what the value of that column is.
So currently you have the following options code:
var options = {'title':title,
seriesType: 'bars',
series: {3: {type: "line"}},
hAxis: {title: 'Rep'},
vAxis: {title: 'Outbound Calls'}
};
If you change this slightly, you can make series 2 colored based on a variable:
var options = {'title':title,
seriesType: 'bars',
series: {
3: {type: "line"}
// set the color of column 2 (series #1) via variable
1: {color: colorvar}
},
hAxis: {title: 'Rep'},
vAxis: {title: 'Outbound Calls'}
};
Then you can just create a javascript function to determine what the value for column 2 is, and color appropriately:
var colorvar = "#FF0000";
if (data.getValue(0,1) >= 50)
colorvar = "#000000";
This way, if the value is under 50, it will be read. Otherwise it will change to black. Then when you create the options, it will use whatever color is dictated by this function. That way you can color based on the value in column 2.

Categories