Split JSON into two arrays gives undefined keys-values - javascript

I have a project to do that I create a json object from a database and then I need to get it with the help of ajax and split it into two arrays so I can use the values to create a chart on chart.js.I can get the json object but the problem is that when i try to loop through it to create my two arrays I get undefined values instead of the values that the json contains...It maybe be something really stupid but I still learning so I cant figure it out.I already tried many of the answers that were given in other similar cases but nothing worked.
When I try to run my data.php that creates the json I get this on my browser:
[{"name":"Messenger","number":"29"},{"name":"Viber","number":"28"},{"name":"Facebook","number":"28"},{"name":"Skype","number":"17"}]
My javascript to get the json,split it into two arrays and create the chart:
$(document).ready(function(){
$.ajax({
url: "http://localhost/project_test/data.php",
method: "GET",
success: function(data) {
console.log(data);
//trying to create the two arrays...
var applications = [];
var number = [];
for(var i in data) {
applications.push("App name " + data[i]['name']);
number.push(data[i].number);
}
console.log(applications);
console.log(number);
//chart.js things....
var ctx = $("#mycanvas");
var barGraph = new Chart(ctx, {
type: 'line',
data: {
labels: applications,
datasets: [{
label: 'Chart',
data: number,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
},
error: function(data) {
console.log(data);
}
});
});
I used both ways ( data[i].name and data[i]['name'] ) to get the values but none of them worked.
my console logs

You are using a for in loop, instead of a for loop.
for(var i in data) {
applications.push("App name " + data[i]['name']);
number.push(data[i].number);
}
should be
for(var i = 0; i < data.length; i++) {
applications.push("App name " + data[i]['name']);
number.push(data[i].number);
}

You are getting an array of objects. With jQuery, you can approach the 2 arrays like this:
var data = [{"name":"Messenger","number":"29"},{"name":"Viber","number":"28"},{"name":"Facebook","number":"28"},{"name":"Skype","number":"17"}];
var names = [];
var numbers = [];
$.each(data, function(i, row) {
names.push(row.name);
numbers.push(row.number);
});
Fiddle

Related

Chart.js how to inser values from json

I have an issue inserting in Chart.js only two values(timestamp and cpu telemetry) from external JSON(which is located remotely on VPS). In Console all data loaded correctly, my code is:
var theCpuUrl = "http://" + address + "/api/metric/cpu";
var xmlhttp = new XMLHttpRequest();
var ctx = document.getElementById('cpuchart').getContext('2d');
var cpuchart = new Chart(ctx, {
type: 'bar',
data: {
labels: '......',
datasets: [{
label: 'cpu',
data: [80, 70, 80, 20, 10, 50],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}],
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
}
}
}
});
httpGetAsync(theCpuUrl, function(data, status) {
var myData = JSON.parse(data);
for (var i = 0; i < myData[0].length; i++) {
let time = myData[0][i].timestamp;
let value = myData[0][i].cpu;
}
});
xmlhttp.open("GET", theCpuUrl, true);
console.log(xmlhttp.readyState);
This code is also connected to global.js with next code:
var address = "192.168.13.60:12345"
function httpGetAsync(theUrl, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true);
xmlHttp.setRequestHeader("Access-Control-Allow-Origin", "*");
xmlHttp.send(null);
}
Please somebody can you explain me how do I draw data on Y and X axis.
Thank you very much.
Welcome to Stackoverflow. The issue is coming because you have initialised the chart first new Chart and you're getting the updated values asynchronously. You can solve this problem by initialising chart once you have received the data.
e.g.
httpGetAsync(theCpuUrl, function(data, status) {
var myData = JSON.parse(data);
// storing time and values
let time=[], value=[];
for (var i = 0; i < myData[0].length; i++) {
time.push(myData[0][i].timestamp);
value.push(myData[0][i].cpu);
}
// now you have data in time and value array ready
--> here call the "new Chart" which you're calling above. <--
});

The Implode function in PHP isn't showing up my results in a js chart

Im using the implode() function for 2 items in a bar chart:
1.) For the checkPoint (Which is an integer value and this gives the bar chart the values data which is held under data in the js code). Which works perfectly
2.) For the module names (which is just Strings, the names of the module). which I paste under labels
However the names of the columns in my bar chart (module names) under the labels is not showing up, however in the inspect element of my web page, they are being shown there. The error is the console is: SyntaxError: Unexpected identifier 'ManagementCareer'. Expected either a closing ']' or a ',' following an array element.
The code:
$query = "SELECT `module`.`ModuleName`,`userTakingModule`.`checkPoint` FROM `userTakingModule` JOIN `module`ON `userTakingModule`.`ModuleID`= `module`.`ModuleID` JOIN `users`ON `userTakingModule`.`idUsers`=`users`.`idUsers` WHERE `userTakingModule`.`idUsers`= '".$_SESSION['id']."' ";
//Execute
$result = $conn -> query($query);
$moduleCheckPoint = Array();
$moduleName = Array();
while($row = $result -> fetch_assoc())
{
$moduleCheckPoint[] = $row['checkPoint'];
$moduleName[] = $row['ModuleName'];
}
<?php
$modCheckPoint = implode(',',$moduleCheckPoint);
$modName = implode(',', $moduleName);
?>
<script type="text/javascript">
var ctx = document.getElementById("my3Chart");
var myBarChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [<?php echo $modName ?>],
datasets: [{
label: 'Module Tracker',
data: [<?php echo $modCheckPoint ?>],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
The module check point is working fine and populating the bar chart, however the module names are not appearing at all. Please can someone highlight what I've done incorrectly?
What should be appearing (moduleNames):
Under Inspect Element they are showing:
Correct approach here is to use json_encode function:
$modCheckPoint = json_encode($moduleCheckPoint);
// though `$moduleName` is array of numbers - you can leave `implode`
// but in case of array strings - always use `json_encode`
$modName = implode(',', $moduleName);
Also:
labels: <?php echo $modName ?>, // remove [] here, as `json_encode` returns them already.

Chart bundle js is not showing dynamic data

I am using chart bundle js.
On alter show everything is fine but on map nothing is showing.
Please fix this issue if anyone can. Thanks in advance.
<script>
var url = "{{url('stock/chart')}}";
var Month = new Array();
var Labels = new Array();
var Prices = new Array();
$(document).ready(function () {
$.get(url, function (response) {
var total=0;
var date=0;
response.forEach(function (data) {
var dateObj = new Date(data.created_at)
var month = dateObj.getUTCMonth() + 1;
var day = dateObj.getUTCDate();
var year = dateObj.getUTCFullYear();
var date=year + '-' + month + '-' + day;
$.ajax({
type: 'get',
url: '{{URL::to('day/sale')}}',
data: 'date=' + date + '&vendor_id=' + data.vendor_id,
success: function (data1) {
//when i alert data and data 1 it showing right result
Month.push(day + '-' + month + '-' + year);
Prices.push(data1.sum);
}
});
});
var ctx = document.getElementById("canvas").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: Month,
datasets: [{
label: 'eFreshUp',
/* data: Prices,*/
data: Prices,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 2
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
});
});
</script>
I am using chart bundle js map. On alter show everything is fine but on map nothing is showing.
The ajax call does not seem to be working in the above code.
The data option for your $.ajax call needs to be specified as name/value pairs, not as a query string. The ajax call converts these into the query string for you.
So
data: {"date" : date, "vendor_id": data.vendor_id},

Chart.js passing value data dynamic

I am want to use data and level dynamic by ajax, so i am using as below but not working.
My ajax return data in json_encode of php.
My code is:
success: function (result) {
result = JSON.parse(result);
var labels = result['labels'];
var data = result['data'];
//console.log(data);
var ctx = document.getElementById("chartbtc");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [labels],
datasets: [{
label: 'Market Price (USD)',
data: [data],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
}
}
});
}
But chart is not generating:
Ajax result is:
{"labels":"13-Nov-2017, 14-Nov-2017, 15-Nov-2017, 16-Nov-2017, 17-Nov-2017, 18-Nov-2017, 19-Nov-2017, 20-Nov-2017, 21-Nov-2017, 22-Nov-2017, 23-Nov-2017, 24-Nov-2017, 25-Nov-2017, 26-Nov-2017, 27-Nov-2017, 28-Nov-2017, 29-Nov-2017, 30-Nov-2017, 01-Dec-2017, 02-Dec-2017, 03-Dec-2017, 04-Dec-2017, 05-Dec-2017, 06-Dec-2017, 07-Dec-2017, 08-Dec-2017, 09-Dec-2017, 10-Dec-2017, 11-Dec-2017, 12-Dec-2017","data":"6550.22, 6635.41, 7301.42, 7815.03, 7786.88, 7817.14, 8007.65, 8255.59, 8059.8, 8268.03, 8148.94, 8250.97, 8707.4, 9284.14, 9718.29, 9952.5, 9879.32, 10147.37, 10883.91, 11071.36, 11332.62, 11584.82, 11878.43, 13540.98, 16501.97, 16007.43, 15142.83, 14869.8, 16762.11, 17276.39"}
Since you have provided your ajax result, this will not work with the chart generation. In your case result["labels"] is a string and you are just making a list with 1 element which is the whole string(which is not valid for the labels property and will not work). What you should do is split the string, format it correctly and then supply it as a list to the labels property. Easiest way would be to use the split() function, and in your case you could split by ", ". Although I would recommend to implement a better response if its possible (have it something like so: {"labels": ["13-Nov-2017", "14-Nov-2017", ...]}).
Hope this helps!
For the first time you can fill the chart with your own value, but when it is coming for dynamically appending data then you should remove the canvas element and regenerate it. So that your data will get appended dynamically on chart.
You can try something like this.
<canvas id="chartbtc" class="canvasChart"></canvas>
<script>
dynamicDataAppendOnChart(labels, data); // On page loading you will be having your own data so you can pass them, or if you want that to be happen with ajax when page loading itself you can trigger the click event.
$('#btnClick').trigger('click');
// You will be calling the function with click event...
$('#btnClick').on('click', function () {
var data = '', labels = '';
$.ajax({
url: url,
type: "POST",
data: data,
async: isAsync,
success: function (result) {
result = JSON.parse(result);
labels = result['labels'];
data = result['data'];
}
});
dynamicDataAppendOnChart(labels, data); // Now you can call the function by passing labels and data
});
function dynamicDataAppendOnChart() {
$('#chartbtc').remove();
$('#appendTheCanvasElement').append('<canvas id="chartbtc" class="canvasChart"><canvas>'); // This would create new canvas element every time and removes the older one.
var ctx = document.getElementById("chartbtc");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [labels],
datasets: [{
label: 'Market Price (USD)',
data: [data],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
}
}
});
}
</script>
Try This.
Declare label and data as
var labels = result['labels'].split(","); // Return Array of Strings Of labels
var data = JSON.parse("[" + result['data'] + "]");// return array of data
Chage
labels: [labels],
data: [data],
to
labels: labels,
data: data,
Because it already in array

Need help Chart.js in asp.net mvc

A few days can make a graph, we need your guidance.
Arrow displays the objects, but on the chart nothing is displayed. The search was not successful.
My models:
public class Voting
{
public int Id { get; set; }
public string Name { get; set; }
public int Voice { get; set; }
public DateTime DateVote { get; set; }
public string IpAdress { get; set; }
}
My controller:
[HttpGet]
public JsonResult GetVotings()
{
List<Voting> votings = db.Votings.ToList();
return Json(votings, JsonRequestBehavior.AllowGet);
}
Probably the main problem in the script calling the data did. While it is possible the controller is not properly configured to output data, will be very glad of your help.
My View:
<canvas id="ChartVote" width="300" height="200"></canvas>
<script type="text/javascript" charset="utf-8">
$(function () {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: 'json',
url: '/Chart/GetVotings',
}).done(function (votings) {
console.log(votings);
$.each(votings, function (index, data) {
myChart.labels.push(data.Name);
myChart.datasets[0].data.push(data.Voice);
});
});
});
var ctx = document.getElementById("ChartVote");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: '# of Votes',
data: [],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
</script>
Your code has few problems ! First of all, inside your $.each you are trying to access labels property of myChart. But you did not define what myChart variable is. So you are going to get an undefined error!
Another thing to think about is, your ajax call is asynchronous. It may take a long time to get the data. So whenever you get the data, you need to execute the code to render the chart with that data. I suggest you move that code to a method and call that method in your ajax call's success/done event.
This should work.
function renderChart(labels, voice) {
var ctx = document.getElementById("ChartVote");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: '# of Votes', data: voice,
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: { beginAtZero: true }
}]
}
}
});
}
Now in your ajax call's done event, you can pass the label array and data array to your RenderChart method.
$(function(){
$.ajax({
type: "GET",
url: '#Url.Action("GetVotings","Chart")',
}).done(function (votings) {
var labelsArray = [];
var dataArray = [];
$.each(votings, function (index, data) {
labelsArray.push(data.Name);
dataArray.push(data.Voice);
});
renderChart(labelsArray, dataArray);
});
});

Categories

Resources