How to draw a pie-chart in Zul using JavaScript - javascript

As I am new to ZK framework and trying to implement javascript code inside zul.
My code is below :
<zk>
<window id="HomePage" border="none" width="100%" height="100%"
hflex="min" style="background-color:green">
<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 drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Automation', 11],
['Manual', 2],
['Report', 2],
['Payroll', 2],
['MISC', 7]
]);
var options = {
title: 'My Daily Work Activities',
is3D: true,
};
var chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
chart.draw(data, options);
}
</script>
When I am executing the above code I am getting a blank page. Can anyone please suggest me how I can modify this code to get a pie-chart.

You are lacking an element to draw the chart to:
document.getElementById('piechart_3d') does not find anything.
So you have to add it:
<zk xmlns:n="native">
<window>
...
<n:div id="piechart_3d"></n:div>
Here I used the native namespace of ZK to cause it to render an exact HTML-div instead of a zk widget. This then can be resolved by document.getElementById.
Another hint: hflex='min' of the window produced some issues with my tests, so I removed it in the working example below.
Working example:
http://zkfiddle.org/sample/3env602/1-google-pi-chart
UPDATE:
Another option would be to use ZK's javascript classes to find the element to draw to. This eliminates the use of the native namespace.
zk.Widget.$("$piechart_3d") get's you the zk Widget, on which you can call the $n() function to get the DOMElement it is bound to.
<zk>
<window>
...
<script>
...
var chart = new google.visualization.PieChart(zk.Widget.$("$piechart_3d").$n());
chart.draw(data, options);
</script>
<div id="piechart_3d"></div>
</window>
</zk>
Example:
http://zkfiddle.org/sample/gnt3cl/3-google-pi-chart-zk

Related

Using Google chart javascript library to create an illustration during a XSL-FO transformation

I would like to use Google chart javascript library to create illustrations during a XSL-FO transformation. I found some examples using the now deprecated Google static image chart API to display charts using <fo:instream-foreign-object>. Since the documentation says that the charts are displayed in SVG, I was wondering if it's possible to do the same with the javascript library using MSXML processor's element.
I wrote a test stylesheet using the sample below:
<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 corechart 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', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
In my stylesheet I first define the drawChart() function inside the gchart namespace:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:gchart="https://developers.google.com/chart/" exclude-result-prefixes="xs" version="2.0">
<msxsl:script language="JScript" implements-prefix="gchart">
import https://www.gstatic.com/charts/loader.js;
// Load the Visualization API and the corechart 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', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</msxsl:script>
Then I call gchart:drawChart() inside <fo:instream-foreign-object> hoping that it will return the SVG code.
<xsl:template match="/">
<fo:root font-size="12pt" font-family="Times, PmingLiu">
<fo:layout-master-set>
<fo:simple-page-master page-height="297mm" page-width="210mm"
margin="25mm 25mm 25mm 25mm" master-name="defaultMaster">
<fo:region-body margin="0mm 0mm 0mm 0mm"/>
<fo:region-before extent="0mm" />
<fo:region-after extent="0mm" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="defaultMaster">
<fo:flow flow-name="xsl-region-body">
<fo:instream-foreign-object>
<xsl:value-of select="gchart:drawChart()"/>
</fo:instream-foreign-object>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
The problem is that Microsoft JScript doesn't load the library: it issues an error when encountering the import https://www.gstatic.com/charts/loader.js. How should I do?
Besides, do you think the draw() function will return the SVG code?

Using Razor inside Javascript (not MVC)

I'd like to know if in my case I can use razor inside javascript!
<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 corechart 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', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
// Set chart options
var options = {'title':'How Much Pizza I Ate Last Night',
'width':400,
'height':300};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
This is just a basic code from Google that will show a pie chart with static values and I would like to add some variables to the numbers in the chart so that they can change based on data on my page.
data.addRows([
['Mushrooms', 3],
['Onions', 1],
['Olives', 1],
['Zucchini', 1],
['Pepperoni', 2]
]);
Basically this is the part that matters in that case, I would like to swap the numbers in this code to razor variables like for example #number or something, is this possible?
While searching around for some answers I found that adding in the javascript code would make it allow razor but I couldnt make it work, when I did that the chart didnt even show up, just by adding <text>, not even any razor code.
Or if you have experience with Google Charts API and know how to do this in a better way overall!
Yes you can use razor inside of the <script> tag.
<script type="text/javascript">
data.addRows([
['#someRazorString', #someRazorNumber]
]);
</script>
also, you can render any .net object using
#{
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
<text>
<script type="text/javascript">
var someJsObjectOrArray = #Html.Raw(JsonConvert.SerializeObject(Model.someDotNetObjectOrArray, jsonSerializerSettings)));
</script>
</text>
}

Draw bar graph using javascript

I am trying to draw a bar graph using the values returned from server using jQuery. I use the following code,
I try to draw graph using the values in the variable data_list, the issue is the graph draws first with empty values the I got values from server.
I am a newbie to Javascript and jQuery. Thanks in advance.
<html>
<head>
<title>the title</title>
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script>
$(function() {
$( "#datepicker1" ).datepicker();
$( "#datepicker2" ).datepicker();
});
</script>
<script type="text/javascript" language="javascript">
var data_list
$(document).ready(function() {
$.get('/api/', function(data) {
data_list = data;
alert(data_list); // alert work second
});
});
alert('test') // first this alert work
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable(data_list);
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<form>
<p>Date1: <input type="text" id="datepicker1"></p>
<p>Date2: <input type="text" id="datepicker2"></p>
</form>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
There are two parts in yout JS code. The first is loading the chart data from your API with an AJAX request. The second starts the chart library and attach the data in this line:
var data = google.visualization.arrayToDataTable(data_list);
The problem is the ajax request is asynchronous and the data is not loaded yet when you attach that data. The data_list var will be avaliable when the AJAX request finishes and not when the page is loaded. In other words, you must separated the initialization of the chart and the data attach to it, or simply: init the graph, load the data and set it to the chart when the AJAX request is done. A simple example with your code (not tested) could be:
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
$(document).ready(function() {
$.get('/api/', function(data) {
data_list = data;
var data = google.visualization.arrayToDataTable(data_list);
var options = {
title: 'Company Performance',
hAxis: {title: 'Year', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
});
});
}
Remember this code is not tested, it ilustrates the idea of the correct initialization:
- Load Google Chart Library
- Load the data
- When the data is loaded, init the concrete chart
The asynchronous load adds some complexity to the code, but are the base of programming in JavaScript with AJAX and DOM events. Another option, more readable and simple, is to use jquery deferred objects and promises. More on deferred and promises:
- http://api.jquery.com/category/deferred-object/
- http://www.html5rocks.com/en/tutorials/es6/promises/?redirect_from_locale=es

Calling my Model in JavaScript in html.erb

I have this code in my view in index.html.erb
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// 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() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
ActiveRecord.connect()
var accounts = Account.find({
all: true,
order: 'id DESC'
});
for (var i=0;i<accounts.length;i++)
{
document.write(accounts.a_name);
data.addRow([accounts.a_name, accounts.a_amount]);
}
// Set chart options
var options = {'title':'Accounts balance distribution',
'width':600,
'height':500};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div"></div>
</body>
</html>
The Account model is not returning any value, do you know how to change the code to make it returns values
Thank you and looking forward for your feedback
/Mohamed sami
Since ERB stands for Embedded Ruby, you have to embed it :
So when you write var accounts = value, you have to embed 'value' into <%= and %> and make sure that value is some ruby that returns the appropriate string for your Javascript (the same that you would have hard-written if it wasn't dynamic).

How to embed JSTL forEach in javascript

I'm trying to loop through a list of objects (some measurements data) using JSTL forEach tag in javascript and display the data by using Google Charts API. The code is showing as following. But looks something wrong. As I double checked, the data in the list of measurements objects works fine to pass to html in ${listOfMeasurements}, ${measurements.measTime}, ${measurements.measS1raw} and ${measurements.measS2raw}. But in the javascript block, the forEach code is not working to execute data.addRow() as expected. My guess is, I'm not using forEach correctly in my javascript code, so data.addRow() was not executed as expected. How can I fix it?
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Date');
data.addColumn('number', 'measurement1');
data.addColumn('number', 'measurement2');
<c:forEach items="${listOfMeasurements}" var="measurements">
"data.addRow("
+"${measurements.measTime}"+","
+"${measurements.measS1raw}"+","
+"${measurements.measS2raw}"+");"
;
</c:forEach>
var options = {
title: 'Measurements'
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
Try it like this
<c:forEach items="${listOfMeasurements}" var="measurements">
data.addRow(${measurements.measTime},${measurements.measS1raw},${measurements.measS2raw});
</c:forEach>
Otherwise you will obtain wrong code in your script, for example:
"data.addRow("+"measTimeValue-1"+","+"measS1raw-1"+","+"measS2raw-1"");";
"data.addRow("+"measTimeValue-2"+","+"measS1raw-2"+","+"measS2raw-2"");";
"data.addRow("+"measTimeValue-3"+","+"measS1raw-3"+","+"measS2raw-3"");";
...and that's incorrect javascript.
The problem with mixing JSP tags and Javascript is that they occur in two differents phases.
JSP Rendering comes first, so all html, css and javascript code is just another string. So after the JSP Rendering finishes, you have just HTML.
You may want to read this blog entry from BalusC about this topic.
This could be alternate solution....
function drawBasic() {
var data = google.visualization.arrayToDataTable([
['Date', 'measurement1','measurement2']
<c:forEach var="measurements" items="${listOfMeasurements}">
,[${measurements.measTime},${measurements.measS1raw},${measurements.measS2raw}]
</c:forEach>
]);
var options = {
title: 'Change title Acoordingly',
chartArea: {width: '50%'},
hAxis: {
title: 'Change title Acoordingly',
minValue: 0
},
vAxis: {
title: 'Change title Acoordingly'
}
};
var chart = new google.visualization.BarChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
<body><div id="chart_div"></div></body>

Categories