With all the different ways to write a Json file, I wanted to learn more about how to write them and how to use them in a Google Chart.
First I started with making and using the following Json:
[
{
"Voetballer" : "Christiano Ronaldo",
"Jaar_2010" : 79000000.00,
"Jaar_2011" : 79700000.00,
"Jaar_2012" : 80000000.00,
"Jaar_2013" : 79500000.00,
"Jaar_2014" : 80000000.00,
"Jaar_2015" : 81000000.00
},
{
"Voetballer" : "Lionel Messi",
"Jaar_2010" : 55500000.00,
"Jaar_2011" : 60000000.00,
"Jaar_2012" : 61500000.00,
"Jaar_2013" : 62000000.00,
"Jaar_2014" : 63000000.00,
"Jaar_2015" : 64700000.00
}
(just a part of the Json)
And I made a chart with the help of Google's chart API and the following code:
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart()
{
$.getJSON('voetbal.json', function(data)
{
var dataTable = new google.visualization.DataTable();
dataTable.addColumn('string', 'jaar');
$.each(data, function(key, value)
{
dataTable.addColumn('number', value.Voetballer);
});
count=0;
$.each(data[0], function(key, value)
{
if (key != "Voetballer")
{
dataTable.addRows(1);
var Year = key.split("_");
dataTable.setValue(count, 0, Year[1]);
count++;
}
});
count=1;
$.each(data, function(i, object)
{
teller=0;
$.each(data[i], function(key, value)
{
if (key != "Voetballer")
{
dataTable.setValue(teller, count, value);
teller++;
}
});
count++;
});
var options =
{
colors : ['#8bbe24','#344d59','#d1ceb2','#c95338','#fcc800','#00a0e9','#601986','#e4ebe5'],
title : " Top earnings ",
seriesType: 'bars',
legend: {position: 'right'},
series: {11: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('visualization'));
chart.draw(dataTable, options);
});
}
</script>
</head>
<body>
<div id="visualization"></div>
</body>
This chart works great!
So I wanted to move on to a different Json file, create a correct file at first which became this one:
[
{
"round1": [
{
"playerA": 62,
"playerB": 98,
"playerC": 97,
"playerD": 94,
"playerE": 96
}
]
},
{
"round2": [
{
"playerA": 77,
"playerB": 40,
"playerC": 41,
"playerD": 99,
"playerE": 76
}
]
}
(it goes on until round 10)
How ever I can't get this Json file to work using the code from my previous chart so I changed the Json a bit to this:
[
{
"round": 1 [
{
"playerA": 62,
"playerB": 98,
"playerC": 97,
"playerD": 94,
"playerE": 96
}
]
},
In hope that it would make it easier but all I seem to manage is a empty screen, without errors.
Hopefully there's someone out there that can either point me in the right direction or show me what I'm doing wrong, my knowledge is very slim about Json files in general. I just figured I could use the working previous code and mainly change some names and be able to use pretty much the same code.
So my question in short: How can I use the second Json file I made with Google charts? And is it easier to use the code I've already once made, or go from scratch because of the different Json file? And if so, please tell me how/point me in the right way. All this Json stuff is confusing =)
The issue is that you changed the data structure of the JSON file. The first JSON file was an Array of objects [{obj1}, {obj2}...] and the second JSON file is an ARRAY of objects that have a key with an array as a value [{obj1:[array1]},{obj2:[array2]}...]. Both are completely valid JSON formats, but the API can only render the data under the first format. Please see this documentation to understand how you should be preparing the data for a google chart.
https://developers.google.com/chart/interactive/docs/basic_preparing_data
Related
I'm developing part of application in which i need to generate reports on some user athletes and preview on chart following:
dates and number of exposures to certain lift
Here is the html and javascript:
<div class="chart" id="bar-chart-#exposureReport.AthleteId" style="height: 300px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<script>
drawChart('#exposureReport.CoachId', '#exposureReport.AthleteId');
function drawChart(coachId, athleteId) {
//debugger;
$.getJSON('#Url.Action("FetchAthleteChartData", "Reports")?coachId=' + coachId + '&athleteId=' + athleteId,
function (data) {
var datax = JSON.stringify(data);
alert(datax);
Morris.Bar({
element: 'bar-chart-' + athleteId,
resize: true,
barSizeRatio: 0.12,
barGap: 3,
data: $.parseJSON(datax),
barColors: ['#ff0000'],
xkey: ['exposures'],
ykeys: ['dates'],
labels: ['Times exposed'],
hideHover: 'auto'
});
}
);
}
</script>
</div>
I foreach all the reports i have on current view and preview them. I want to show a chart for each report.
I call the javascript function and pass the coachId and athleteId values and let server fetch the data for me:
[HttpGet]
public JsonResult FetchAthleteChartData(string coachId, string athleteId)
{
var exerciseReport =
_applicationUserOperations.GetAllExposureReportsForCoachByAthleteId(coachId, athleteId);
var filteredDates = exerciseReport.Exposures.Select(x => x.ExposureDate).ToList();
var filteredExposures = exerciseReport.Exposures.Select(x => x.NumberOfLifts).ToList();
var result = new
{
Dates = filteredDates,
Exposures = filteredExposures
};
return Json(result);
}
When my alert(datax) triggers it shows (I have only one training/exercise/lift entry atm):
{"dates":["2018-06-01T00:00:00"],"exposures":[5]}
Is this correct format to parse ? How do I parse it so the chart data can understand it and display it.
I want to plot C3js pie chart based on the following JSON (received from HQL-hibernate Java Play framework)...
JSON looks like this (This is dynamic data):
{"ug":["K","M2","M3","M4"],"wtv":[10,20,35,60]}
HTML:
<div id="chart"></div>
JS (what I actually tried):
var json ={"ug":["K","M2","M3","M4"],"wtv":[10,20,35,60]};
var ug =json.ug;
var wtv=json.wtv;
var chart = c3.generate({
data: {
json: {
ug:wtv[0],
ug1:wtv[1],
ug2:wtv[2],
ug3:wtv[3],
},
type : 'pie',
}
});
Here is a fiddle for reference.
In places of ug,ug1,ug2,ug3 I need K,M2,M3,M4(To be noted these are dynamic data)
Can anyone help me to manipulate the data to draw the pie chart as required?
I hope changing the structure of JSON at the back end is not the only solution (it is very difficult in my case though). Any other solutions are appreciated.
so long as "ug" and "wtv" have the same number of elements...
var json = {"ug":["K","M2","M3","M4"],"wtv":[10,20,35,60]};
var pieJson = {};
json.ug.forEach(function (ug, index) {
pieJson[ug] = json.wtv[index];
});
var chart = c3.generate({
data: {
// iris data from R
json: pieJson,
type : 'pie',
}
});
jsfiddle.net/4h4z00g7/
i have this code and i want to change the static data with data from csv
the csv is look like:
GPA,Total Distance,id
3.27,22.0,20032202
2,64.0,20038107
2.81,10.0,20051566
2.33,66.5,20060382
i want to add the GPA in y axis
and total distance in the X axis
when i try to add code from d3 library it does not works
<html>
<head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart', 'line']
});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'GPA');
data.addRows([
[0, 0],
[1, 10],
[2, 23],
[3, 17],
[4, 18],
]);
var options = {
hAxis: {
title: 'Total Distance'
},
vAxis: {
title: 'GPA'
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="curve_chart" style="width: 900px; height: 500px"></div>
</body>
</html>
Here is the best answer I can come up with to help you.
In your question, you have to tackle different topics in javascript
get content of a local file in javascript
parse this content as a csv file (and make it a multidimensional array)
prepare the values to put in the chart
First, add the following two libraries : jQuery for the simplified ajax calls to the file and jquery-csv for an also simplified way to parse the content.
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
Then, you have to re-route the charts callback : you have to point to a function that get asynchronously the file content (getFileContent in the example below).
Only in case of success, you can format the csv data into array.
And only then, you can serve the data to the chart by passing your formatted and sorted array to your drawbasic method.
Finally, you end up with that script
<script type="text/javascript">
google.charts.load('current', {
packages: ['corechart', 'line']
});
google.charts.setOnLoadCallback(getFileContent);
function getFileContent() {
var filePath = 'file:///path/to/file.csv';
// 1. Get local file content asynchronously
$.get(filePath, {}, function (data) {
console.log(arguments);
var lines = $.csv.toArrays(data); // 2. Parse the csv as a multidimensional array
var header = lines.shift(); // 3. Remove the header of the file
// 4. Sort the lines by the second column
lines.sort(function (a, b) {
if (a[1] === b[1]) {
return 0;
}
else {
return (a[1] < b[1]) ? -1 : 1;
}
});
// 5. Pass your lines to the draw method
drawBasic(lines);
}, 'text')
.fail(function () {
console.log(arguments);
})
;
}
function drawBasic(lines) {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'GPA');
for (i = 0; i < lines.length; i++) {
// 6. Don't forget to parse as float the numbers in the array, they are strings at this point
// You'll get a 'Type mismatch. Value 3,27 does not match type number' error if you don't
var xValue = parseFloat(lines[i][1]);
var yValue = parseFloat(lines[i][0]);
data.addRow([xValue, yValue]);
}
var options = {
hAxis: {
title: 'Total Distance'
},
vAxis: {
title: 'GPA'
}
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
Don't forget to change the filepath in getFileContent, preceded by file://
I give credit to the answers in SO that helped me create this answer:
Javascript - read local text file
How to sort 2 dimensional array by column value?
Side note
In different conditions, it's much more common if you get csv (or, better with Javascript, JSON) via an HTTP call when working with Javascript to display data.
Local file reading may be reserved for server-side processing, that make this content available through HTTP.
I'm trying to get an image from a Wikipedia article. I have the title of the article but it seems like I need to know the pageid to access the thumbnail. How do I get the pageid from the title?
My JavaScript code:
$.getJSON("http://en.wikipedia.org/w/api.php?action=query&titles=" + article + "&prop=pageimages&format=json&pithumbsize=350", function (data) {
imageURL = data.query.pages[/* pageid */].thumbnail.source;
});
Here's what I'm parsing (example for article = "Car"):
{"query":{"pages":{"13673345":{"pageid":13673345,"ns":0,"title":"Car","thumbnail":{"source":"http://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Benz-velo.jpg/100px-Benz-velo.jpg","width":100,"height":80},"pageimage":"Benz-velo.jpg"}}}}
^ It seems like I first need to know that it's the 13673345 index.
OP asks how to "access the thumbnail", i.e., the URL within the returned data. He did not ask how to access the full image behind the thumbnail ... which is something other answers address.
OP's problem is that the data is keyed to the page ID. In fact, the query could return more than one article in which case there would be multiple page IDs and thumbnails.
The following query returns the data used in the code snippet:
http://en.wikipedia.org/w/api.php?action=query&titles=Stack_Overflow&prop=pageimages&format=json&pithumbsize=350
And OP can extract the page IDs using this code:
var pageid = [];
for( var id in data.query.pages ) {
pageid.push( id );
}
Run the code snippet below to test.
<html>
<body>
<img id="thumbnail"/>
<script type="text/javascript">
var data = {
"query":
{
"normalized": [
{
"from": "Stack_Overflow",
"to": "Stack Overflow"
}],
"pages":
{
"21721040":
{
"pageid": 21721040,
"ns": 0,
"title": "Stack Overflow",
"thumbnail":
{
"source": "http://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Stack_Overflow_homepage.png/350px-Stack_Overflow_homepage.png",
"width": 350,
"height": 185
},
"pageimage": "Stack_Overflow_homepage.png"
}
}
}
};
// get the page IDs
var pageid = [];
for( var id in data.query.pages ) {
pageid.push( id );
}
// display the thumbnail using a page ID
document.getElementById('thumbnail').src = data.query.pages[ pageid[0] ].thumbnail.source;
</script>
</body>
</html>
Just build your JSON object with JSON.parse so you have an object that looks like:
var response = {
query: {
pages: {
"13673345":{
pageid: 13673345,
ns: 0,
title: "Car",
thumbnail: {
source: "http://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Benz-velo.jpg/100px-Benz-velo.jpg",
width: 100,
height: 80
},
pageimage: "Benz-velo.jpg"
}
}
}
};
And then you can clearly see you don't need pageid in the slightest, you just need to process the correct "pages" object.
In this case there's only one, but even if there would be multiple, just run through Object.keys for the response.query.pages object:
var pages = response.query.pages;
var propertyNames = Object.keys(pages);
propertyNames.forEach(function(propertyName) {
var page = pages[propertyName];
var thumbnail = page.thumbnail.src;
var imgURL = thumbnail.replace("/thumb/",'').replace(/\.(jpg|png).*/,".$1");
doSomethingWith(imgURL);
});
(note the file extension regexp, which we do because who says all images are jpg? Better to pick jpg and png, since those are the two prevailing image formats on the web)
Please Help me....any plugin is there..?
I have searched for exporing excel and PDF in angularjs. using ng-grid.
Exporting ng-grid data to CSV and PDF format in angularjs
For csv export there is the ngGridCsvExportPlugin that you can find here
Just at a reference to the script and add the ngGridCsvExportPlugin to the gridOptions (and activate the footer too by adding showFooter : true to the gridOption)
$scope.gridOptions = {
data: 'myData',
plugins: [new ngGridCsvExportPlugin()],
showFooter: true,
};
A basic plunker where you can see it at work can be found here
You don't need any external plugin now. ng grid which new version is called now UI-Grid has native support. Method names are csvExport and pdfExport.
http://ui-grid.info/docs/#/tutorial/206_exporting_data
If you are able to do something outside of angular you could use https://github.com/Ziv-Barber/officegen for excel. See here https://stackoverflow.com/questions/18476921/angularjs-generating-a-pdf-client-side for pdfs.
I used jsPDF. It's the simplest ever.
Include it in your html:
<script src="jspdf.min.js"></script>
<!-- script src="jspdf.debug.js"></script--><!-- for development -->
Use it1:
var doc = new jsPDF();
doc.text(20, 20, 'Hello world.');
doc.save('Test.pdf');
And bind your button or whatever to this code.
Advanced Tip
I also found the jsPDF-AutoTable plugin-for-jsPDF extremely useful.
Include it in your html:
<script src="jspdf.plugin.autotable.js"></script>
In the controller, transfer data from ng-grid data to jsPDF, using jsPDF-AutoTable plugin.
Assuming you define your ng-grid table:
$scope.gridOptions = {
data: 'myData',
columnDefs: [
{field: 'user', displayName: 'User' /*,...*/ },
{field: 'email', displayName: 'Email' /*,...*/ },
{field: 'favoriteShruberry', displayName: 'Favorite Shrubbery' /*,...*/ }
]
};
... Then, in the function that generates the pdf:
var columns = [];
var rows = [];
// copy ng-grid's titles to pdf's table definition:
var allColumnDefs = $scope.gridOptions.columnDefs;
for ( var columnIdx in allColumnDefs ) {
var columnDef = allColumnDefs[columnIdx];
var newColumnDef = {
title: columnDef.displayName,
dataKey: columnDef.field
};
columns.push(newColumnDef);
}
// copy ng-grid's actual data to pdf's table:
var allRecords = $scope.myData;
for ( var recordIdx in allRecords ) {
var record = allRecords[recordIdx];
var newRow = {};
for ( var columnIdx in allColumnDefs ) {
var columnDef = allColumnDefs[columnIdx];
var value = record[columnDef.field];
if (value !== null) {
newRow[columnDef.field] = value;
}
}
rows.push(newRow);
}
var docName = 'favoriteShrubberies.pdf';
var pdfStyle = { styles: { overflow: 'linebreak' } } // this handles cells that contain really long text like in this comment, by auto-inserting a
// line break inside the cell, causing the whole line's height to increase accordingly
var doc = new jsPDF('p', 'pt'); // currently supports only 'pt'
doc.autoTable(columns, rows, pdfStyle);
doc.save(docName);
1 Example is straight from the jsPDF GitHub repo
Very late to this party, but I wrote a PDF output that works for me. There is a plunker, and it is available as a plugin for V2 of ng-grid, but it doesn't look like they have taken it through into V3 (but I just had a very quick peek, so I could be wrong).