Thanks to this community for all the great help. I have been successful adding new JS functionality to some webpages with Tampermonkey. Now I am trying to show a Google Chart injected on a webpage. Chrome browser. I have been trying on and off for several months, and no joy. I stripped everything down to the simplest TM script to show a pie chart, URL matching on Google home page. The DIV is visible but no chart is rendered. No related errors in JS console.
The chart renders fine if NOT using Tampermonkey.
https://jsfiddle.net/_pirateX/ue88hus0/
I have tried window.onload in various positions, and moved the Google chart loader in various places. I have tried to set the load callback just using the function name drawChart, but no change.
Can anyone please assist and tell me why this is not working. I would be eternally grateful.
// #name Chart Example1
// #namespace http://tampermonkey.net/
// #version 1.0.0
// #description try to take over the world!
// #author You
// #require https://www.gstatic.com/charts/loader.js
// #match https://www.google.com
// ==/UserScript==
/* global google */
'use strict';
google.charts.load("current", {packages:["corechart"]});
window.onload = function() {
var myWrapper = document.createElement('div');
myWrapper.style.position = 'fixed';
myWrapper.id = "myChart";
myWrapper.style.width = '600px';
myWrapper.style.height = '300px';;
myWrapper.style.right = '1em';
myWrapper.style.top= '10em';
myWrapper.style.background = 'rgba(255, 255, 255, 1)';
myWrapper.style.border = '2px solid grey';
document.body.append(myWrapper);
//put here code
google.charts.setOnLoadCallback(function() { drawChart()});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Group');
data.addColumn('number', 'Gender');
data.addRows([
['Males', 10],
['Females', 5]
]);
var options = {'title':'Gender distribution',
'width':300,
'height':300};
var chart = new google.visualization.PieChart(document.getElementById('myChart'));
chart.draw(data, options);
}
}
google's load statement will wait for the page to load by default,
so you can use the load statement, in place of window.onload
try placing the code inside the promise the load statement returns...
google.charts.load("current", {
packages:["corechart"]
}).then(function () {
var myWrapper = document.createElement('div');
myWrapper.style.position = 'fixed';
myWrapper.id = "myChart";
myWrapper.style.width = '600px';
myWrapper.style.height = '300px';;
myWrapper.style.right = '1em';
myWrapper.style.top= '10em';
myWrapper.style.background = 'rgba(255, 255, 255, 1)';
myWrapper.style.border = '2px solid grey';
document.body.append(myWrapper);
var data = new google.visualization.DataTable();
data.addColumn('string', 'Group');
data.addColumn('number', 'Gender');
data.addRows([
['Males', 10],
['Females', 5]
]);
var options = {'title':'Gender distribution',
'width':300,
'height':300};
var chart = new google.visualization.PieChart(document.getElementById('myChart'));
chart.draw(data, options);
});
Apparently there is some incompatibility in the way TM loads/uses Google loader.js. In Github repository, I got a reply from the developer of TM as follows:
The loader injects a script into the page, but the#require'd script "lives" inside the sandbox. Please use #unwrap to make it work.
#unwrap will be included in next release. In the meantime, testing revealed that loading Google loader.js via JS is also effective:
// ==UserScript==
// #name Histogram
// #namespace http://tampermonkey.net/
// #version 0.1
// #description Show histogram.
// #author Me.
// #match https://match.com*
// #icon https://www.google.com/s2/favicons?domain=mydomain
// #require file://D:\mycode.js
// ==/UserScript==
/* global google, injectChartDiv, drawChart */
'use strict';
// Set up onload callback.
window.onload = drawChart;
// Load the Google charts loader.js
var my_script = document.createElement('script');
my_script.setAttribute('src','https://www.gstatic.com/charts/loader.js');
document.head.appendChild(my_script);
I will update this answer as I learn more about #unwrap. For now, my chart is rendering yay! Thanks everyone.
Related
How can plot a Google Scatterchartfrom an uploaded csv file?
It is showing a blank page.
I tried the following code:
Loading the scripts:
<script src="https://www.google.com/jsapi"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
Then I got this part from an example:
<script> // wait till the DOM is loaded
$(function() {
// grab the CSV
$.get("https://www.batemo.de/wp-content/uploads/general/data_chart_gravimetric.csv", function(csvString) {
// display the contents of the CSV
$("#chart").html(csvString); }); });
// load the visualization library from Google and set a listener
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
// grab the CSV
$.get("https://www.batemo.de/wp-content/uploads/general/data_chart_gravimetric.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// this view can select a subset of the data at a time
var view = new google.visualization.DataView(data); view.setColumns([0,1]);
var options = {};
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(view, options);
}); }
</script>
the example has an error.
the brackets at the end of the following line...
$("#chart").html(csvString); }); }); <-- these two sets of brackets
need to move down below the rest of the code,
here is the full, corrected snippet...
$(function() {
// grab the CSV
$.get("https://www.batemo.de/wp-content/uploads/general/data_chart_gravimetric.csv", function(csvString) {
// display the contents of the CSV
$("#chart").html(csvString);
// load the visualization library from Google and set a listener
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
// grab the CSV
$.get("https://www.batemo.de/wp-content/uploads/general/data_chart_gravimetric.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
// this new DataTable object holds all the data
var data = new google.visualization.arrayToDataTable(arrayData);
// this view can select a subset of the data at a time
var view = new google.visualization.DataView(data); view.setColumns([0,1]);
var options = {};
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(view, options);
}); }
}); });
I tried to attach a google chart on the popup of a layer in Leaflet by followed this instruction. However, I keep getting this error:
"Uncaught (in promise) Error: Container is not defined"
Here is my javascript function that I use to bind the popup:
function layer_name(feature, layer) {
//...
var popupContent = L.popup().setContent('<div id="chart_div" align = "center">1</div>')
layer.bindPopup(popupContent, {maxHeight: 400});
}
When I tried setting
<div id="chart_div" align = "center">1</div>
as just an HTML element there is no error raised.
I have also define the chart to be drawn at the very beginning of the script as below:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Load Charts and the corechart package.
google.charts.load('current', {'packages':['corechart']});
// Draw the pie chart for follower chart when Charts is loaded.
google.charts.setOnLoadCallback(drawChart);
// Callback that draws the bar
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Title', 'Value'],
['A', 317],
['B', 148],
['C', 67],
['D', 27],
['E', 23]
]);
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data);
}
</script>
How can I fix this?
Your problem is that your HTML Element chart_div is not created until the popup is open. But you try to init the chart on the not created HTML Element.
Call drawChart() after the popup is opened.
Update your layer_name function and add the openpopup event to the layer. It will called when you open the popup.
function layer_name(feature, layer) {
//...
var popupContent = L.popup().setContent('<div id="chart_div" align="center">1</div>')
layer.bindPopup(popupContent, {maxHeight: 400});
layer.on('popupopen',function(e){
drawChart();
})
}
Using the tutorial from google on using a spreadsheet as data for a chart I have created the following.
Tutorial
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {packages: ['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawSheetName() {
var query = new google.visualization.Query('https://docs.google.com/spreadsheets/d/15l3ZK45hv2ByOfkUiAKoKp-Z9a1u1-Q_rsLS7SqC51E/editgid=0&headers=1');
query.send(handleQueryResponse);
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
var data = response.getDataTable();
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, { height: 400 });
}
}}
</script>
</head>
<body>
<!-- Identify where the chart should be drawn. -->
<div id="chart_div"/>
</body>
However no chart resolves, I have made the link public.
If I share the link it is https://docs.google.com/spreadsheets/d/15l3ZK45hv2ByOfkUiAKoKp-Z9a1u1-Q_rsLS7SqC51E/edit?usp=sharing
Following the docs and not sure where my error is.
This SO answer more about drive-sdk creates the key from a script from a new file, I don't really understand it and nuclear how you can obtain the correct URL for existing spreadsheets.
Would be great if there could be a consolidated answer obtaining correct sheets URL's.
Is this what you are trying to achieve?
If yes, you can check how it works here.
EDIT
Since I notice in the comments you want to query the spreadsheet and not use the entire spreadsheet, this is the logic to query with.
First, these are the basic components of the url to query:
var BASE_URL = "https://docs.google.com/a/google.com/spreadsheets/d/";
var SS_KEY = "stringSS_Key";
var BASE_QUERY = "/gviz/tq?tq=";
var partialUrl = BASE_URL + SS_KEY + BASE_QUERY;
Notice the BASE_QUERY variable
The first bit of the url is in the partialUrl variable.
Then, you need to use the Query Language that google provides. An example would be:
var queryToRun = 'select dept, sum(salary) group by dept';
You then need to call encodeURIComponent() on it, and add it to the partial URL. The final URL then becomes
var finalUrl = partialUrl + encodeURIComponent(queryToRun);
Only then you can run the google.visualiation.query as I suspect you intend.
var query = new google.visualization.Query(finalUrl);
I can't seem to understand why this isn't working. I have no errors.I have done this using oscillators and it works fine. FYI this is a continuation of this thread:
Using Web Audio API to assign two sounds to two Divs and play each independently via a click event with javascript
Code:
<div id="divElement"></div>
<style>
#divElement{
background-color: orange;
width:70px;
height:100px;
left:143px;
}
</style>
<script>
var context = new webkitAudioContext(),
savedBuffer;
var playAudioFile = function () {
var source = context.createBufferSource();
var gainNode = context.createGainNode();
source.buffer = savedBuffer;
// START OF PROBLEM AREA: Gain not working but file still plays with no errors.
source.connect(gainNode);
gainNode.connect(context.destination);
gainNode.gain = 0;
// END OF PROBLEM AREA
source.noteOn(0); // Play sound immediately
};
var request = new XMLHttpRequest();
request.open('get', 'audio/A.mp3', true);
request.responseType = 'arraybuffer';
request.onload = function () {
context.decodeAudioData(request.response,
function(incomingBuffer) {
savedBuffer = incomingBuffer;
var divElement = document.getElementById("divElement");
divElement.addEventListener("click", playAudioFile , false);
}
);
};
request.send();
</script>
Try gainNode.gain.value = 0 instead. gainNode.gain is an AudioGain object, which has the attribute value.
http://www.w3.org/TR/webaudio/#AudioGainNode
I am using GWT api for google charts and having some issues:
colums from the start and end values missing for the column chart
BarChart width is trimmed is half for first/last value
To solve this I tried viewWindowMode property
HorizontalAxisOptions opt = HorizontalAxisOptions.create();
opt.set("viewWindowMode","pretty");
but this does not work.
Any ideas on how to solve?
Code:
private Options createOptions(ChartDataProxy response) {
Options options = Options.create();
options.setWidth(chartPanel.getOffsetWidth() - 2 * chartBorderWidth);
options.setHeight(chartPanel.getOffsetHeight() - 2 * chartBorderWidth);
HorizontalAxisOptions opt = HorizontalAxisOptions.create();
opt.setTitle(response.getxAxisName());
opt.setSlantedText(true);
opt.set("viewWindowMode","pretty");
options.setHAxisOptions(opt);
AxisOptions vopt = AxisOptions.create();
vopt.setTitle( response.getyAxisName());
vopt.set("viewWindowMode","pretty");
options.setVAxisOptions(vopt);
options.setTitle(response.getCaption() + " " + response.getSubCaption());
options.setLegend( LegendPosition.BOTTOM );
options.setPointSize(4);
return options;
}
I'm having similar problem, although I was using javascript. Maybe, you can adapt it into GWT.
Basically DataView can fix it. You just need to handle the first column with DataView and return whatever you need to return when not using DataView -- however, as string. I (don't) know, it's weird.
Given I had two columns: date, number. I will use this kind of code:
var data = new google.visualization.DataTable();
data.addColumn('date', 'month');
data.addColumn('number', 'users');
// trick to prevent the bar chart from being cut in half at both edge of our graph
var dataView = new google.visualization.DataView(data);
dataView.setColumns([{calc: function(data, row) { return data.getFormattedValue(row, 0); }, type:'string'}, 1]);
var chart = new google.visualization.ColumnChart(document.getElementById('chart_monthly_users'));
chart.draw(dataView, options);
Hope it helps. I merely gather the scattered solutions.