Turn model into JSON and pass it into JavaScript setOnLoadCallBack - javascript

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>

Related

How to add links to Google GeoChart maps?

I am trying to create a custom clickable map using GeoChart from Google for a website. I want countries to be clickable, where once users select different countries on the map, it would direct them to a separate web page. Also, I want the color to change when it's in a selected state.
Can someone help me with the JavaScript on how to add the select event? I would appreciate it.
Below is the code I have so far.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
</script>
<script type="text/javascript">
google.charts.load('current', {
'packages':['geochart'],
'mapsApiKey': 'AIzaSyD3MfRYHAynUsxWCZ8NDsA3cwvWlTkhT1s'
});
google.charts.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['Country'],
['Thailand' ],
['India'],
['Malaysia'],
['Sri Lanka'],
['Indonesia'],
['Vietnam'],
['Korea'],
['Taiwan'],
['China'],
]);
var options = {
region: '142', // Asia
colorAxis: {colors: ['#f5f5f5']},
datalessRegionColor: '#f5f5f5',
defaultColor: '#ff8040',
};
var chart = new google.visualization.GeoChart(document.getElementById('geochart-colors'));
chart.draw(data, options);
};
</script>
</head>
<body>
<div id="geochart-colors" style="width: 700px; height: 433px;"> </div>
</body>
</html>
As you can see in my code you need to add a listener which is the google.visualization.events.addListener. Then inside that listener, you can get the name of the selected country. I printed by console.log() function you can do whatever you like with that.
google.charts.load('current', {
'packages':['geochart'],
'mapsApiKey': 'AIzaSyD3MfRYHAynUsxWCZ8NDsA3cwvWlTkhT1s'
});
google.charts.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['Country'],
['Thailand' ],
['India'],
['Malaysia'],
['Sri Lanka'],
['Indonesia'],
['Vietnam'],
['Korea'],
['Taiwan'],
['China'],
]);
var options = {
region: '142', // Asia
colorAxis: {colors: ['#f5f5f5']},
datalessRegionColor: '#f5f5f5',
defaultColor: '#ff8040',
};
var chart = new google.visualization.GeoChart(document.getElementById('geochart-colors'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', function() {
var selectedItem = chart.getSelection()[0];
if (selectedItem) {
var country = data.getValue(selectedItem.row, 0);
console.log(country);
}
}); };
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
</script>
</head>
<body>
<div id="geochart-colors" style="width: 700px; height: 433px;"> </div>
</body>
</html>

Google chart doesnt load with javascript on Sharepoint

I am relatively new to google charts and was trying to run a basic chart for demo and further development.
Its a pretty basic script and was working well till yesterday and now it doesnt load anything.
I am loading this script in script editor webpart of Sharepoint and trying to load it. Not sure if its my case or just that Google Charts has a problem.
Pl help. Am I missing something conceptual here? Its a pretty basic code that I got from http://www.evoketechnologies.com/blog/visualizing-sharepoint-google-charts/ and modified it a bit for my use.
I have run window.alert and it is extracting all values in the enumerator correctly. I think then something happens and the chart doesnt load.
javascript alerts also pop up after the barChart.draw(data, options), and lineChart.draw(data, options) code part, so the code has execute fully.
Thank you
Niraj
*<html>
<head>
<script src="https://www.gstatic.com/charts/loader.js" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-3.0.0.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.02/jquery.SPServices.min.js" type="text/javascript"></script>
<script language="javascript">
var returnedItems = null;
function loadGoogleLibAndDraw(){
google.charts.load('current', {'packages':['bar','line']});
google.charts.setOnLoadCallback(visualizeData);
}
function visualizeData() {
var context = new SP.ClientContext();
var list = context.get_web().get_lists().getByTitle(document.getElementById('customListName').value);
var caml = new SP.CamlQuery();
caml.set_viewXml("<View></View>");
returnedItems = list.getItems(caml);
context.load(returnedItems);
context.executeQueryAsync(onSucceededCallback, onFailedCallback);
}
function onSucceededCallback(sender, args) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Part No');
data.addColumn('number', 'Volume');
var enumerator = returnedItems.getEnumerator();
var markup = '';
while (enumerator.moveNext()) {
var row = [];
var listItem = enumerator.get_current();
row.push(listItem.get_item('Part_x0020_No'));
row.push(listItem.get_item('Volume'));
data.addRow(row);
}
var options = {
chart: {
title: 'KPIs',
},
bars: 'vertical'
};
var barChart = new google.charts.Bar(document.getElementById('BarChart'));
barChart.draw(data, options);
var lineChart = new google.charts.Line(document.getElementById('LineChart'));
lineChart.draw(data, options);
}
function onFailedCallback(sender, args) {
var markup = '<p>The request failed: <br>';
markup += 'Message: ' + args.get_message() + '<br>';
displayDiv.innerHTML = markup;
}
</script>
</head>
<body onload="loadGoogleLibAndDraw()">
<form name="metricsform" id="metricsform">
<input id="customListName" name="customListName" value="Projects" type="hidden"/>
</form>
<div>
<div id="displayDiv"></div>
<div id="BarChart" style="width: 300px; height: 200px;"></div>
<div id="LineChart" style="width: 300px; height: 200px;"></div>
</div>
</body>
</html>*
recommend not using inline tag events --> <body onload="...
especially if there are multiple editor web parts / <body> tags
also, it isn't necessary since the loader...
will wait for the document to finish loading before calling the callback
to be absolute sure, place all <script> tags at the bottom, just before the </body> end tag
recommend following setup...
<html>
<body>
<form name="metricsform" id="metricsform">
<input id="customListName" name="customListName" value="Projects" type="hidden"/>
</form>
<div>
<div id="displayDiv"></div>
<div id="BarChart" style="width: 300px; height: 200px;"></div>
<div id="LineChart" style="width: 300px; height: 200px;"></div>
</div>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.02/jquery.SPServices.min.js"></script>
<script>
var returnedItems = null;
function visualizeData() {
var context = new SP.ClientContext();
var list = context.get_web().get_lists().getByTitle(document.getElementById('customListName').value);
var caml = new SP.CamlQuery();
caml.set_viewXml("<View></View>");
returnedItems = list.getItems(caml);
context.load(returnedItems);
context.executeQueryAsync(onSucceededCallback, onFailedCallback);
}
function onSucceededCallback(sender, args) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Part No');
data.addColumn('number', 'Volume');
var enumerator = returnedItems.getEnumerator();
var markup = '';
while (enumerator.moveNext()) {
var row = [];
var listItem = enumerator.get_current();
row.push(listItem.get_item('Part_x0020_No'));
row.push(listItem.get_item('Volume'));
data.addRow(row);
}
var options = {
chart: {
title: 'KPIs',
},
bars: 'vertical'
};
var barChart = new google.charts.Bar(document.getElementById('BarChart'));
barChart.draw(data, options);
var lineChart = new google.charts.Line(document.getElementById('LineChart'));
lineChart.draw(data, options);
}
function onFailedCallback(sender, args) {
var markup = '<p>The request failed: <br>';
markup += 'Message: ' + args.get_message() + '<br>';
displayDiv.innerHTML = markup;
}
google.charts.load('current', {
callback: visualizeData,
packages: ['bar', 'line']
});
</script>
</body>
</html>

how to listen to a function in external js from the script in html page?

**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>

creating google chart from csv using js/jquery

Here is my code to create google chart from csv data. code look fine but still there is some error.
Code looks fine but error is may be due to some jquery syntext. I appreciate if someone can help me
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="http://jquery-csv.googlecode.com/files/jquery.csv-0.71.js"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
// grab the CSV
$.get("Chart1-data.csv", function(csvString) {
// transform the CSV string into a 2-dimensional array
var arrayData = $.csv.toArrays(csvString, {onParseValue: $.csv.hooks.castToScalar});
alert(arrayData);
// 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]);
// set chart options
var options = {
title: "A Chart from a CSV!",
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.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
});
}
</script>
</head>
<body>
<div id="piechart" style="width: 900px; height: 500px;"></div>
</body>
</html>
Chart1-data.csv
Category,
A,34
B,23
C,14
D,57
E,18
Other,5
Error:
SyntaxError: missing ) after argument list
i.e. line where script ends
UPDATE: there was }); missing. Now no error but chart does not appear
Your closing brackets for $.get( should be }); not just };
$.get({
// code
});
And you're also missing a closing curly bracket to close your function.
Demo

How do you write clean code using Javascript and Razor

I'm programming an ASP.Net MVC page and I'm using data from the server to create a Google chart. The x-axis is the date. The y-axis is the value. There are 2 lines of data being plotted to compare. Here is the relevant code:
#model IEnumerable<Tuple<DateTime,int,int>>
<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var arr = [['Year', 'Sales', 'Expenses']];
//Using the Razor Model to create a Javascript array.
var arr2 = [
#foreach(var row in Model)
{
#:["#row.Item1.ToString("MMM d")", #row.Item2, #row.Item3],
}
];
for (var i = 0; i < arr2.length; i++)
{
arr.push(arr2[i]);
}
var data = google.visualization.arrayToDataTable(arr);
var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
chart.draw(data);
}
</script>
First of all, this code does actually work. Creating arr2 this way does turn a Razor model into something that I can use. However, my nose says code smell. It says that throwing together two languages razor and Javascript, which have somewhat similar C-based programming flow syntax could be confusing to the next person that comes along and tries to read it.
Is there a better way to write this?
However, my nose says code smell.
Oh yeah it stinks, I can feel it.
Is there a better way to write this?
Of course. Never build JSON manually as you did by mixing the 2 languages and writing loops and stuff. Use a JSON serializer:
#model IEnumerable<Tuple<DateTime,int,int>>
<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var arr = #Html.Raw(
Json.Encode(
new object[] { new[] { "Year", "Sales", "Expenses" } }
.Concat(
Model.Select(x => new object[]
{
x.Item1.ToString("MMM d"),
x.Item2,
x.Item3
})
)
)
);
var data = google.visualization.arrayToDataTable(arr);
var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
chart.draw(data);
}
</script>
This will generate an equivalent code markup as yours but the whole model manipulation and encoding is done on the server. You could also write a custom HTML helper in order to simplify your code to this:
public static class ChartExtensions
{
public static IHtmlString ToChartData(
this IEnumerable<Tuple<DateTime, int, int>> model,
params string[] titles
)
{
return new HtmlString(
Json.Encode(
new object[] { titles }
.Concat(
model.Select(x => new object[]
{
x.Item1.ToString("MMM d"),
x.Item2,
x.Item3
})
)
)
);
}
}
and then in your view:
#model IEnumerable<Tuple<DateTime,int,int>>
<div id="chart_div_2" style="width: 900px; height: 500px;"></div>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(drawChart);
function drawChart() {
var arr = #Model.ToChartData("Year", "Sales", "Expenses");
var data = google.visualization.arrayToDataTable(arr);
var chart = new google.visualization.LineChart(document.getElementById('chart_div_2'));
chart.draw(data);
}
</script>

Categories