I have a non-AngularJS based page - basic.html which works fine as expected.
basic.html
<!doctype html>
<html>
<head>
</head>
<body>
<div class="tab-container" >
<div id="piechart" style="width:1000px;height:470px;"></div>
</div>
<script src="scripts/angular.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Device', 'Hits (in millions)'],
['A', 89],
['B', 13],
['C', 21],
]);
var options = { title: '' };
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
</body>
</html>
Then I tried to reorganize the code (a bit naively) to put into AngularJS framework as follows:
basic.html
<!doctype html>
<html ng-app = "Analytics-App" ng-controller="MainController">
<head>
</head>
<body>
<div class="tab-container" >
<div id="piechart" style="width:1000px;height:470px;"></div>
</div>
<script src="scripts/angular.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="scripts/base.js"></script>
</body>
</html>
base.js
var myApp = angular.module('Analytics-App', []);
myApp.controller('MainController', function($scope, $interval) {
var e = document.createElement("script");
e.src = "https://www.google.com/jsapi";
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Device', 'Hits (in millions)'],
['A', 89],
['B', 13],
['C', 21],
]);
var options = {
title: ''
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
});
Apparently, when loaded, the page DOM changes completely (when viewed using chrome debugger) as:
<html><head><script src="https://www.google.com/uds/?file=visualization&v=1&packages=corechart" type="text/javascript"></script><link href="https://www.google.com/uds/api/visualization/1.0/d90be93871e947a274f6a5157bd75fb0/ui+en.css" type="text/css" rel="stylesheet"><script src="https://www.google.com/uds/api/visualization/1.0/d90be93871e947a274f6a5157bd75fb0/format+en,default+en,ui+en,corechart+en.I.js" type="text/javascript"></script></head></html>
I am trying to understand why controller script failed to add elements into page DOM and why rest of the page elements are removed.
Please use this following.
google.setOnLoadCallback(function () {
angular.bootstrap(document.body, ['Analytics-App']);
});
google.load('visualization', '1', {packages: ['corechart']});
var googleChart = googleChart || angular.module("google-chart",[]);
var myApp = myApp || angular.module("Analytics-App",["google-chart"]);
googleChart.directive("googleChart",function(){
return{
restrict : "A",
link: function($scope, $elem, $attr){
var dt = $scope[$attr.ngModel].dataTable;
var options = {};
if($scope[$attr.ngModel].title)
options.title = $scope[$attr.ngModel].title;
var googleChart = new google.visualization[$attr.googleChart]($elem[0]);
googleChart.draw(dt,options)
}
}
});
myApp.controller("IndexCtrl",function($scope){
$scope.data1 = {};
$scope.data1.dataTable = new google.visualization.DataTable();
$scope.data1.dataTable.addColumn("string","Name")
$scope.data1.dataTable.addColumn("number","Qty")
$scope.data1.dataTable.addRow(["Test",89]);
$scope.data1.dataTable.addRow(["Test2",13]);
$scope.data1.dataTable.addRow(["Test3",21]);
$scope.data1.title="My Pie"
});
<!doctype html>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="script.js"></script>
<style type="text/css">
.bigGraph {width:500px;height:500px;float:left;}
.mediumGraph {width:400px;height:400px;float:left;}
.smallGraph {width:200px;height:200px;float:left;}
</style>
</head>
<body ng-controller="IndexCtrl">
<div google-chart="PieChart" ng-model="data1" class="bigGraph"></div>
</body>
</html>
Plunker URL http://plnkr.co/edit/5guBqC0upuCVgBtY6076?p=preview
Further help http://gavindraper.com/2013/07/30/google-charts-in-angularjs/
and http://jrrera.github.io/angularjs/2014/04/05/a-better-way-to-integrate-angularjs-and-google-charts/
Related
I have tried to make a table by using datatables with an array, but somehow it doesn't show the table on my html file.
The array is defined in my gs file as you can see in the code below.
It's a simple work but I'm still not sure what it went wrong.
var ssId = 'xxxxxxxxxxxxx';
var ss = SpreadsheetApp.openById(ssId);
var indexPage_sheetName = 'xxxxxxxx';
var valuesFromIndexPage = ss.getSheetByName(indexPage_sheetName).getDataRange().getValues();//array of 850rows×15cols
valuesFromIndexPage.shift();
function getData() {
$(document).ready(function(){
$("#foo-table").DataTable({
data: valuesFromIndexPage
});
});
}
<html>
<head>
<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css"/>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<body>
<table id="foo-table" class="display" width="100%"></table>
</body>
</head>
</html>
#ZektorH Here's the console log of running my code.
userCodeAppPanel:9 Uncaught TypeError: Cannot read property 'slice' of null
at initializeTable (userCodeAppPanel:9)
at af (4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:67)
at 4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:10
at ng.J (4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:94)
at Hd (4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:42)
at Dd (4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:43)
at Bd.b (4105580746-mae_html_user_bin_i18n_mae_html_user__ja.js:39)
I looked again at my data and I found out the data became null on console.log(but it has data when I see it on Logger.log).
I'm posting what I did and got below.
function getData() {
Logger.log(valuesFromIndexPage); //the array is in valuesFromIndexPage
return valuesFromIndexPage;
}
function initializeTable(data) {
console.log(data); //it returns null here...
var aDataSet = data.slice(1);
The log from Logger.log
[19-10-31 09:47:00:116 JST] [[ID, 案件名, .......
#ZektorH These're the whole codes without data.
code.gs
var ssId = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
var ss = SpreadsheetApp.openById(ssId);
var indexPage_sheetName = 'xxxxxxxxxxxxxx';
var valuesFromIndexPage = ss.getSheetByName(indexPage_sheetName).getDataRange().getValues();
function createSidebar() {
SpreadsheetApp.getUi().showSidebar(HtmlService.createHtmlOutputFromFile('index').setTitle('My custom sidebar').setWidth(300))
}
function getData() {
return valuesFromIndexPage;
}
function doGet(e) {
return HtmlService.createTemplateFromFile('index').evaluate().setTitle('title');
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
<script>
$(document).ready(function() {
console.log("ready!");
google.script.run.withSuccessHandler(initializeTable).getData(); //calls the getData funciton from Apps Script and returns the results to the initializeTable function
});
function initializeTable(data) {
console.log(data)
var aDataSet = data.slice(1); // all except header
var head = []; // headers
data[0].forEach(function(e) {
head.push({
'sTitle': e
});
});
$('#foo-table').dataTable({
"aaData": aDataSet,
"aoColumns": head
});
}
</script>
</head>
<body>
<table id="foo-table" class="display" width="100%"></table>
</body>
</html>
Chage with columns of of key in dataTable for table headers and chage $("#foo-table").DataTable at $("#foo-table").dataTable
var valuesFromIndexPage=[{"free-text-c1":"free-text-r1","c2":"r1","c3":"r1","c4":"r1","c5":"r1","c6":"r1","c7":"r1","c8":"r1","c9":"free-text-r1","c10":"free-text-r1"},{"free-text-c1":"free-text-r2","c2":"r2","c3":"r2","c4":"r2","c5":"r2","c6":"r2","c7":"r2","c8":"r2","c9":"free-text-r2","c10":"free-text-r2"}];
valuesFromIndexPage.shift();
function getData() {
$(document).ready(function(){
$("#foo-table").dataTable({
destroy: true,
scrollX: true,
data: valuesFromIndexPage,
columns: _.keys(valuesFromIndexPage[0]).map((key) => { return { "title": key, "data": key } })
});
});
}
getData()
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<html>
<head>
<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css"/>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<body>
<table id="foo-table" class="display" width="100%"></table>
</body>
</head>
</html>
Assuming you are using it on a sidebar, I was able to get it to work like this:
Apps Script
function createSidebar() {
SpreadsheetApp.getUi().showSidebar(HtmlService.createHtmlOutputFromFile('sidebar').setTitle('My custom sidebar').setWidth(300))
}
function getData() {
return SpreadsheetApp.getActiveSheet().getDataRange().getValues();
}
HTML Page
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.js"></script>
<script>
$(document).ready(function() {
console.log("ready!");
google.script.run.withSuccessHandler(initializeTable).getData(); //calls the getData funciton from Apps Script and returns the results to the initializeTable function
});
function initializeTable(data) {
var aDataSet = data.slice(1); // all except header
var head = []; // headers
data[0].forEach(function(e) {
head.push({
'sTitle': e
});
});
$('#foo-table').dataTable({
"aaData": aDataSet,
"aoColumns": head
});
}
</script>
</head>
<body>
<table id="foo-table" class="display" width="100%"></table>
</body>
</html>
Hope this helps!
**I want to write an event listener in the hmtl script for a function in the external javascript file **
/**
* Created by ramnath on 02-03-2016.
*/
/*chart.js*/
var merry;
merry=this;
var a=10;
function starlander(){
var name=['Year', 'Sales', 'Expenses'];
var data1=['2004', 1000, 400];
var data2=['2005', 1170, 460];
var data3=['2006', 660, 1120];
var data4=['2007', 1030, 540];
table=[name,data1,data2,data3,data4];
console.log("control came to me");
//drawChart(table);
return table;
}
function Alwayschanges(){
this.on('input',function(msg){
msg=msg.payload;
return msg;
})
}
> In this html page i want to monitor the function Alawyschanges and get msg every time there is a change in Alwayschanges funciton
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript" src="chart.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function updateChart(){
//event listener
}
function drawChart() {
var data = google.visualization.arrayToDataTable(starlander());
var options = {
title: "you got me pal",
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
updateChart();
}
</script>
</head>
<body>
<p id="demo"></p>
<div id="curve_chart" style="width: 900px; height: 500px"></div>
</body>
</html>
So I referred to this link http://demo.jankuri.com/ngGallery/ to make image gallery.
I did everything as directed but nothing shows up as in no images are shown.
Here is my Controller
var check123 = function() {
for (var i = 0; i < z; i++) {
var a = {thumb: '../images/offers/'+'123456789/thumbnails/' + objectidphoto[i], img: '../images/offers/'+'123456789/' + objectidphoto[i]};
arr.push(a);
}
console.log(arr);
console.log(arr[0]);
}
This is not my complete controller only the significant part.
This is my front end code
<body ng-app="fileUpload" ng-controller="MyCtrl">
<div>
<div class="content">
<ng-gallery images="MyCtrl.arr"></ng-gallery>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script src="controller14.js"></script>
<script src="ng-infinite-scroll.js"></script>
<script src="ng-infinite-scroll.min.js"></script>
<script type="text/javascript" src="src/js/ngGallery.js"></script>
</body>
The angular code executes without any errors and I am getting proper response in return for that console.log(arr).
What am I doing wrong?
Updated Segment
Controller
var app = angular.module('fileUpload', ['jkuri.gallery']).
controller('MyCtrl', function($scope, $document)
{
var self = this;
self.images = [
{thumb: 'images/offers/'+'123456789/thumbnails/' + '1445524452873_491676259.jpg', img: '../images/offers/'+'123456789/' + '1445524452873_491676259.jpg'},
{thumb: 'images/offers/'+'123456789/thumbnails/' + '1445524894340_7a668c73cddcd2050821f83be901832a_1426070017.jpg', img: '../images/offers/'+'123456789/' + '1445524894340_7a668c73cddcd2050821f83be901832a_1426070017.jpg'}
];
});
HTML
<body ng-app="fileUpload" ng-controller="MyCtrl">
<div>
<ng-gallery images="MyCtrl.images"></ng-gallery>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script src="controller14.js"></script>
<script src="ng-infinite-scroll.js"></script>
<script src="ng-infinite-scroll.min.js"></script>
<script type="text/javascript" src="src/js/ngGallery.js"></script>
</body>
Now I have exactly replicated what the module's demo looks like. Still the problem is there. There is no change on the front end.
You reference Myctrl.arr , you do not need to prefix the controller name. Just arr should work, that is, if you're correctly assigning arr to the scope. $scope.arr.push ...
I'm going to take a guess you're doing neither of the above.
UDATED:
Your controller:
var app = angular.module('fileUpload', ['jkuri.gallery']). controller('MyCtrl', function($scope, $document) { $scope.images = [ {thumb: 'images/offers/'+'123456789/thumbnails/' + '1445524452873_491676259.jpg', img: '../images/offers/'+'123456789/' + '1445524452873_491676259.jpg'}, {thumb: 'images/offers/'+'123456789/thumbnails/' + '1445524894340_7a668c73cddcd2050821f83be901832a_1426070017.jpg', img: '../images/offers/'+'123456789/' + '1445524894340_7a668c73cddcd2050821f83be901832a_1426070017.jpg'} ]; });
Your html
<body ng-app="fileUpload" ng-controller="MyCtrl"> <div> <ng-gallery images="images"></ng-gallery> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script> <script src="controller14.js"></script> <script src="ng-infinite-scroll.js"></script> <script src="ng-infinite-scroll.min.js"></script> <script type="text/javascript" src="src/js/ngGallery.js"></script> </body>
Note the $scope assignment and the lack of the controller name.
Below is my view. I have modified it to display how I would like it to work. I have a graph that is drawn when the page is loaded. My model contains the data it needs. I have to transform it to JSON (right?) and then pass it into the generateGraph, but the setOnLoadCallBack is my problem. I can't figure out how to create the JSON string before the setOnLoadCallBack is called.
#model IEnumerable<FHWebUserInterface.Models.Weight>
<div id="visualization" style="width: 600px; height: 400px;"></div>
<div id="linechart_material"></div>
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var weightsAsJsonString = serializer.Serialize(Enumerable.Select(Model, weight =>
new
{
date = weight.Date,
value = weight.Value
}));
}
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.1', { packages: ['corechart', 'imagelinechart'] });
</script>
<script type="text/javascript">
function drawVisualization(weightsAsJsonString) {
// Removed the body
chart.draw(data, options);
}
google.setOnLoadCallback(drawVisualization(weightsAsJsonString));
</script>
You just need to render your json somewhere in JavaScript block like this (i've added it before google.setOnLoadCallback call):
#model IEnumerable<FHWebUserInterface.Models.Weight>
<div id="visualization" style="width: 600px; height: 400px;"></div>
<div id="linechart_material"></div>
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var weightsAsJsonString = serializer.Serialize(Enumerable.Select(Model, weight =>
new
{
date = weight.Date,
value = weight.Value
}));
}
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.1', { packages: ['corechart', 'imagelinechart'] });
</script>
<script type="text/javascript">
function drawVisualization(weightsAsJsonString) {
// Removed the body
chart.draw(data, options);
}
// here is my change
var weightsAsJsonString = #weightsAsJsonString; // so it will render your C# object from server side here on client side
google.setOnLoadCallback(drawVisualization(weightsAsJsonString));
</script>
I am trying to implement JQPLOT Bar chart but it's displaying only few bars ( two bars against tick 'e' with combo value '2 null 2') . Below is my code. Could you please suggest whats wrong here. I have added alert statement to display values in array and result is mentioned as comment:
<%# page language="java" contentType="text/html; charset=utf-8"%>
<!DOCTYPE html>
<html>
<head>
<!--[if lt IE 9]><script type="text/javascript" src="js/excanvas.min.js"></script><![endif]-->
<meta http-equiv="X-UA-Compatible" content="IE=8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="css/style.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.9.1.js" type="text/javascript"></script>
<script type="text/javascript" src="js/jquery.jqplot.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.jqplot.min.css" />
<script type="text/javascript" src="js/jqplot.barRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot.categoryAxisRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot.pointLabels.min.js"></script>
<script type="text/javascript" src="js/jqplot.canvasTextRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot.canvasAxisLabelRenderer.min.js"></script>
<script type="text/javascript" src="js/jqplot.json2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var DelayFeed = [[]];
var DelayConfirmation = [[]];
var CorruptFeed = [[]];
var FeedName = [[]];
var feedData = $.ajax({
url: "FeedServlet",
dataType : 'json',
async: false
}).responseText;
var arrayData = JSON.parse(feedData);
for (var i = 0; i < arrayData.length; i++) {
DelayFeed[0].push([ arrayData[i].DelayFeed ]);
DelayConfirmation[0].push([ arrayData[i].DelayConfirmation ]);
CorruptFeed[0].push([ arrayData[i].CorruptFeed ]);
FeedName[0].push([ arrayData[i].FeedName ]);
}
alert(DelayFeed[0]); //8,7,4,3,3
alert(DelayConfirmation[0]); //4,4,4,2,2
alert(CorruptFeed[0]); //4,4,4,2,2
$.jqplot('chart_div', [ DelayConfirmation, DelayFeed, CorruptFeed ]
, { seriesDefaults:{
renderer:$.jqplot.BarRenderer,
rendererOptions: {
barDirection: 'vertical'
},
pointLabels: { show:true }
},
series:[
{label:'Delay - Confirmation'},
{label:'Delay - Feed'},
{label:'Corrupt Feed'}
],
legend: {
show: true,
placement: 'outsideGrid'
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ['a', 'b', 'c', 'd', 'e'];
},
}
});
});
</script>
</head>
<body>
<div class="work-area">
<div id="chart_div" style="width: 800px; height: 400px;"></div>
</div>
</body>
</html>
At a first look, it seems a problem with the format of data passed within $.jqplot() function.
In fact if you replace the three data arguments with these:
var DelayFeed = [8,7,4,3,3];
var DelayConfirmation = [4,4,4,2,2];
var CorruptFeed = [4,4,4,2,2];
$.jqplot('chart_div', [ DelayConfirmation, DelayFeed, CorruptFeed ]
you obtain the following (and correct) barchart
You need to use three simple arrays ( "[ ]" ) and not embedded arrays ( "[[ ]]" ).
Thus, i would try to use
$.jqplot('chart_div', [ DelayConfirmation[0], DelayFeed[0], CorruptFeed[0] ]