Getting data from a Javascript Object Array in Node js? - javascript

I am trying to parse data from a JS Object array and get the value by passing field names and then saving the data in an array. But for some reason, I am not getting the right results. This is what I tried so far. I tried logging the results that I get in val and this is what I get.
val:Array[6]
0
:
Object
BankName
:
"IM BANK"
MERCHANTNAME
:
"MPesa"
NO_OF_FAILED_BANK_TRANSACTIONS
:
0
NO_OF_FAILED_SERVICE_TRANSACTIONS
:
2
NO_OF_SUCCESSFUL_TRANSACTIONS
:
28
__proto__
:
Object
1
:
Object
2
:
Object
3
:
Object
4
:
Object
5
:
Object
length
:
6
How Do I parse the data from my val array by passing field names and then store inside my merchantname array etc.
Homepage.js
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js" ></script>
<script src="http://code.highcharts.com/highcharts.js" ></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container1" style="width:100%; height:400px;"></div>
<div id ="container2" style="height:20px;"></div>
<div id ="container3" style="width:100%; height:400px;"></div>
<script type="text/javascript">
$(document).ready(function () {
var bankid = [ 57, 9912, 9905, 16, 58 ];
var country = ["KENYA", "KENYA", "KENYA", "UGANDA", "UGANDA"];
var counter = 0;
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
var rows =<%-JSON.stringify(Resultset)%>
function initfunc() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/dashboard",
data: JSON.stringify({country: country[counter], bankid: bankid[counter]}),
dataType: "json",
success: function (Result) {
Result = Result.Resultset
// console.log("result", Result);
// console.log("result",Result);
var data = [];
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
$.each(Result, function(item, value){
console.log("val",value);
for (var i in value) {
$.each(value[i], function(item, val){
console.log(val);
for(var i =0;i<val.length;i++)
{
merchantname.push(val[i].merchant_name);
successtranscs.push(val[i].success_transcs);
failedtranscs.push(val[i].failed_transcs);
servicetranscs.push(val[i].service_transcs);
bankname =val[i].bankname;
console.log("merchantname",merchantname);
}
//
})
}
})
// merchantname.push(Result[i].merchant_name);
// successtranscs.push(Result[i].success_transcs);
// failedtranscs.push(Result[i].failed_transcs);
// servicetranscs.push(Result[i].service_transcs);
// bankname = Result[i].bankname;
// console.log("merchantname",merchantname);
StackedChart(bankname, merchantname, successtranscs, failedtranscs, servicetranscs);
merchantname = [];
successtranscs = [];
failedtranscs = [];
servicetranscs = [];
if (counter == country.length - 1) {
counter = -1;
counter++;
}
else {
counter++;
}
},
error: function (Result) {
console.log(Result);
}
});
}
initfunc();
function StackedChart(bank_name,merch_name, succ_val, fail_val, ser_val) {
var myChart = Highcharts.chart('container1', {
chart: {
type: 'column'
},
title: {
text: bank_name
},
xAxis: {
categories: merch_name
},
yAxis: {
min: 0,
title: {
text: 'TransactionStatus'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'Servicefailure',
data: ser_val
}, {
name: 'Failure',
data: fail_val
}, {
name: 'Success',
data: succ_val
}]
});
}
setInterval(initfunc, 2000);
});
</script>
</body>
</html>

Your access keys (marchant_name, success_transcs, ..) are not same with the keys of the objects in the array (MERCHANTNAME, NO_OF_FAILED_BANK_TRANSACTIONS, ...).
Try using the exact same keys:
...
merchantname.push(val[i].MERCHANTNAME);
successtranscs.push(val[i].NO_OF_SUCCESSFUL_TRANSACTIONS);
...

Nested loops in initfunc() look all wrong.
Callback signature
$.each()'s callback signature is (item, index)
Nesting
Do you realise that $.each(function() {...}) is a looping structure in its own right, without the need of a for loop?
You have loops nested at 4-levels. In summary :
$.each(..., { // outer loop (n1 iterations)
for(...) { // first inner loop (n2 iterations)
$.each(..., function(element2, index2) { // second inner loop (n3 iterations)
for() { // third inner loop (n4 iterations)
// Here, inner statements are called n1 x n2 x n3 x n4 times
}
});
}
});
That's not necessarily wrong, but it's very unusual to need loops nested that deeply.
I rather imagine you want :
$.each(Result, function(item) {
$.each(item, function(val) {
merchantname.push(val.merchant_name); // or .MERCHANTNAME?
successtranscs.push(val.success_transcs); // or .NO_OF_SUCCESSFUL_TRANSACTIONS?
failedtranscs.push(val.failed_transcs); // or .NO_OF_FAILED_BANK_TRANSACTIONS?
servicetranscs.push(val.service_transcs); // or .NO_OF_FAILED_SERVICE_TRANSACTIONS?
bankname = val.bankname; // or .BankName?
});
});
or maybe just :
$.each(Result, function(val) {
merchantname.push(val.merchant_name); // or .MERCHANTNAME?
successtranscs.push(val.success_transcs); // or .NO_OF_SUCCESSFUL_TRANSACTIONS?
failedtranscs.push(val.failed_transcs); // or .NO_OF_FAILED_BANK_TRANSACTIONS?
servicetranscs.push(val.service_transcs); // or .NO_OF_FAILED_SERVICE_TRANSACTIONS?
bankname = val.bankname; // or .BankName?
});

Related

Change Highcharts Graph based on two Select inputs

I have an array of data of the following format:
[["sno","day","status","data1","data2","data3","data4"],
["1","01-12-2020","success","23","66","53","34"],
["2","02-12-2020","success","12","9","8","6"],
["3","03-12-2020","success","10","11","16","13"],
["4","04-12-2020","success","34","43","54","34"],
["5","01-12-2020","fail","45","26","36","44"],
["6","02-12-2020","fail","12","15","11","13"],
["7","03-12-2020","fail","34","43","33","29"],
["8","04-12-2020","fail","23","34","31","23"]
]
to display the particular text in Highcharts I used the Following code:
var weekData = [["sno","day","status","data1","data2","data3","data4"],["1","01-12-2020","success","23","66","53","34"],["2","02-12-2020","success","12","9","8","6"],["3","03-12-2020","success","10","11","16","13"],["4","04-12-2020","success","34","43","54","34"],["5","01-12-2020","fail","45","26","36","44"],["6","02-12-2020","fail","12","15","11","13"],["7","03-12-2020","fail","34","43","33","29"],["8","04-12-2020","fail","23","34","31","23"]] ;
//console.log(weekData);
function change()
{
var valStatus = document.getElementById("statusSelect");
status = valStatus.value;
//console.log(status);
if(status == 'success')
{
const successValues = weekData.filter((x)=>x[2] === "success"); //New Cases
console.log(successValues);
return successValues;
}
else if(status == 'fail')
{
const failValues = weekData.filter((x)=>x[2] === "fail"); //New Cases
console.log(failValues)
return failValues;
}
}
function getCol(matrix, col){
var column = [];
for(var i=0; i<matrix.length; i++){
column.push(matrix[i][col]);
}
return column;
}
function chartCreate()
{
change();
const toNumbers = arr => arr.map(Number);
var getstat= change();
var day = getCol(getstat,1);
console.log(day);
var sdata1 = toNumbers(getCol(getstat,3));
console.log("data 1" ,sdata1);
var sdata2 = toNumbers(getCol(getstat,4));
console.log(sdata2);
var sdata3 = toNumbers(getCol(getstat,5));
console.log(sdata3);
var sdata4 = toNumbers(getCol(getstat,6));
console.log(sdata4);
For the full program You can check my fiddle : https://jsfiddle.net/abnitchauhan/L27n0wfs/
the problem is that when I am status select box, The Chart is not updating.
Also I feel that this code is quite lengthy when the datasets will increase overtime. is there any efficient approach to display this data on Highchart's based on the same select options.
I made an update to JS code. See if this is what you want:
var weekData = [["sno","day","status","data1","data2","data3","data4"],["1","01-12-2020","success","23","66","53","34"],["2","02-12-2020","success","12","9","8","6"],["3","03-12-2020","success","10","11","16","13"],["4","04-12-2020","success","34","43","54","34"],["5","01-12-2020","fail","45","26","36","44"],["6","02-12-2020","fail","12","15","11","13"],["7","03-12-2020","fail","34","43","33","29"],["8","04-12-2020","fail","23","34","31","23"]] ;
//console.log(weekData);
function change()
{
var valStatus = document.getElementById("statusSelect");
status = valStatus.value;
//console.log(status);
if(status == 'success')
{
const successValues = weekData.filter((x)=>x[2] === "success"); //New Cases
console.log(successValues);
return chartCreate(successValues);
}
else if(status == 'fail')
{
const failValues = weekData.filter((x)=>x[2] === "fail"); //New Cases
console.log(failValues)
return chartCreate(failValues);
}
}
function getCol(matrix, col){
var column = [];
for(var i=0; i<matrix.length; i++){
column.push(matrix[i][col]);
}
return column;
}
function chartCreate(stat)
{
const toNumbers = arr => arr.map(Number);
var getstat= stat;
var day = getCol(getstat,1);
console.log(day);
var sdata1 = toNumbers(getCol(getstat,3));
console.log("data 1" ,sdata1);
var sdata2 = toNumbers(getCol(getstat,4));
console.log(sdata2);
var sdata3 = toNumbers(getCol(getstat,5));
console.log(sdata3);
var sdata4 = toNumbers(getCol(getstat,6));
console.log(sdata4);
var options = {
chart:{
renderTo: 'chart',
defaultSeriesType: 'line'
},
title: {
text: 'dummy'
},
subtitle: {
text: ' '
},
yAxis: {
title: {
text: ' ',
//tickPointInterval: 250
},
minorTickInterval: 'auto',
// tickInterval: 4,
},
xAxis: {
labels :{
minorTickInterval: 'auto',
formatter: function(){
return day[this.value];
}
},
tickInterval: 10
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
// pointStart: 0
}
},
tooltip: {
// split: true,
formatter: function() {
var points = this.points,
tooltipArray = ['day: <b>' + day[this.x] + '</b><br/> Value : <b>'+ this.y +'</b>']
return tooltipArray;
}
},
series: [
{
name: 'Check',
data: sdata1
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
};
var chart = new Highcharts.Chart(options);
$("#dataSelect").on('change', function(){
//alert('f')
var selVal = $("#dataSelect").val();
if(selVal == 'data1' || selVal == '')
{
options.series = [{name: 'Data', data: sdata1}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
else if(selVal == 'data2')
{
options.series = [{name: 'Data', data: sdata2}]
}
else if(selVal == 'data3')
{
options.series = [{name: 'Data', data: sdata3}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
else if(selVal == 'data4')
{
options.series = [{name: 'Data', data: sdata4}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
var chart = new Highcharts.Chart(options);
});
}
change();
Your code looks very complex and does not fully work. In this case, I will suggest using the series setData method mixed with the change event listener. My example is a bit simplified, but I think it might be the right way.
document.getElementById('dataSelect').addEventListener('change', () => {
const selectorValue = document.getElementById('dataSelect').value
chart.series[0].setData(data[selectorValue])
});
API: https://api.highcharts.com/class-reference/Highcharts.Series#setData
Demo: https://jsfiddle.net/BlackLabel/nfz0a9bm/

Javascript variable not working inside of highcharts

I am trying to show high charts pie chart dynamically, i pass exact value format into data index in high chart but it doesn't show anything in chart, if i give what a variable have a value directly it's working fine, but passing variable directly it show empty pie chart,
Here is my javascript code,
function get_product_chart_by_filter()
{
var product_year_raw = $('#top_least_pro_year_filt').val();
var pro_top_least = $('#top_least_pro_filt').val();
var next_year = '';
var product_year = '';
var pro_top_res = '';
if (product_year_raw.length == 4) {
next_year = parseInt(product_year_raw) + 1;
product_year = product_year_raw+'-'+next_year;
}
else {
product_year = product_year_raw;
}
if (pro_top_least == 1) {
$('#pro_top_or_least').empty().html('Top ');
}
else {
$('#pro_top_or_least').empty().html('Least ');
}
$.ajax({
type:"POST",
url:baseurl+'Dashboard/product_dashboard_dynamic',
data:{'year':product_year,'top_or_least':pro_top_least},
cache: false,
dataType: "html",
success: function(result){
pro_top_res = JSON.parse(result);
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
data_series = data_series.replace(/,\s*$/, "");
// Output of 'data_series' variable = ['Basmathi',6],['null',6],['Basmathi',6],['Basmathi',20],['Basmathi',21]
Highcharts.chart('top_5_products_container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false
},
credits:false,
title: {
text: 'Products',
align: 'center',
verticalAlign: 'middle',
y: 60
},
tooltip: {
pointFormat: '{series.name}: <b>{point:y}</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
distance: -50,
style: {
fontWeight: 'bold',
color: 'white'
}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '75%'],
size: '110%'
}
},
series: [{
type: 'pie',
name: 'Product',
innerSize: '50%',
data: [data_series]
}]
});
}
});
}
Here is my server side code,
public function product_dashboard_dynamic()
{
$dashboard_settings_info = get_dashboard_settings_info();
$top_or_least = $this->input->post('top_or_least');
$raw_yr = $this->input->post('year');
$exp_yr = explode('-', $raw_yr);
$yr1 = $exp_yr[0];
$yr2 = $exp_yr[1];
$top_least_count = $dashboard_settings_info->max_product_count;
$get_top_least_product = $this->Dashboard_model->get_top_least_product($top_or_least,$yr1,$yr2,$top_least_count);
echo json_encode($get_top_least_product);
}
Anyone can assist me?
My thought is that it has something to do with the use of a concatenated string rather than an array so you could perhaps try... though I have not used highcharts before
Change
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
to:
var data_series = [];
for( var i = pro_top_res.length - 1; i >= 0; i-- ) {
var obj=pro_top_res[i];
data_series.push( [ obj.product_name, parseInt( obj.product_order_count ) ] );
}
remove
data_series = data_series.replace(/,\s*$/, "");
Finally modify the configuration to accomodate new input data as an array
'series': [{
'type': 'pie',
'name': 'Product',
'innerSize': '50%',
'data':data_series
}]

Ajax returns undefined response in node js?

I am trying to post a ajax request to my server.js script in node js. The script then passes the data from the ajax request to the stored procedure and is supposed to return the result to the ajax function. But for some reason, I am getting an undefined error while debugging my ajax function. What could I be doing wrong?
plain.ejs
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js" ></script>
<script src="http://code.highcharts.com/highcharts.js" ></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container1" style="width:100%; height:400px;"></div>
<div id ="container2" style="height:20px;"></div>
<div id ="container3" style="width:100%; height:400px;"></div>
<script type="text/javascript">
$(document).ready(function () {
var bankid = [ 57, 9912, 9905, 16, 58 ];
var country = ["KENYA", "KENYA", "KENYA", "UGANDA", "UGANDA"];
var counter = 0;
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
var rows =<%-JSON.stringify(Resultset)%>
function initfunc() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/dashboard",
data: JSON.stringify({country: country[counter], bankid: bankid[counter]}),
dataType: "json",
success: function (Result) {
Result = Result.d;
console.log("result" +Result);
var data = [];
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
for (var i in Result) {
merchantname.push(Result[i].merchant_name);
successtranscs.push(Result[i].success_transcs);
failedtranscs.push(Result[i].failed_transcs);
servicetranscs.push(Result[i].service_transcs);
bankname = Result[i].bankname;
}
StackedChart(bankname, merchantname, successtranscs, failedtranscs, servicetranscs);
merchantname = [];
successtranscs = [];
failedtranscs = [];
servicetranscs = [];
if (counter == country.length - 1) {
counter = -1;
counter++;
}
else {
counter++;
}
},
error: function (Result) {
console.log(Result.d);
}
});
}
initfunc();
function callfunc() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/dashboard",
data: JSON.stringify({country: country[counter], bankid: bankid[counter]}),
dataType: "json",
success: function (Result) {
Result = Result.d;
console.log("result" +Result);
var data = [];
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
for (var i in Result) {
merchantname.push(Result[i].merchant_name);
successtranscs.push(Result[i].success_transcs);
failedtranscs.push(Result[i].failed_transcs);
servicetranscs.push(Result[i].service_transcs);
bankname = Result[i].bankname;
}
StackedChart(bankname, merchantname, successtranscs, failedtranscs, servicetranscs);
merchantname = [];
successtranscs = [];
failedtranscs = [];
servicetranscs = [];
if (counter == country.length - 1) {
counter = -1;
counter++;
}
else {
counter++;
}
},
error: function (Result) {
console.log(Result.d);//it keeps going to the error //function
}
});
}
function StackedChart(bank_name,merch_name, succ_val, fail_val, ser_val) {
var myChart = Highcharts.chart('container1', {
chart: {
type: 'column'
},
title: {
text: bank_name
},
xAxis: {
categories: merch_name
},
yAxis: {
min: 0,
title: {
text: 'TransactionStatus'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'Servicefailure',
data: ser_val
}, {
name: 'Failure',
data: fail_val
}, {
name: 'Success',
data: succ_val
}]
});
}
setInterval(callfunc, 2000);
});
</script>
</body>
</html>
server.js -
var express = require('express');
var cnn = require('./DbConnection.js');
var bodyParser = require('body-parser');
require('highcharts');
var app = express();
app.use(express.bodyParser());
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); //
app.engine('html', require('ejs').renderFile);
dirname = "C:/Users/user/WebstormProjects/untitled/public";
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
app.get('/', function (req, res) {
var obj;
cnn.TransactionInfo("KENYA","57", function (err, result) {
// process result here
console.log(result.length);
var resultset = {"Result":result};
obj = { "title":"fruit consumption", "name":"fruit eaten"};
res.render("plain.ejs",{Resultset:resultset});
});
});
app.post('/dashboard', function (req, res) {
cnn.TransactionInfo(req.body.country,req.body.bankid, function (err, result) {
var resultset = {"Result":result};
res.render("plain.ejs",{Resultset:resultset});
});
});
By specifying dataType : "json", you're telling jQuery that it should expect JSON data to be returned by the server. However, your Express handler is sending back HTML:
res.render("plain.ejs",{Resultset:resultset});
So the error will likely be that jQuery couldn't decode the response.
Try sending back a JSON response:
res.json({ Resultset : resultset });

Jquery - Counting JSON objects

Im building a chart system that will show me all data entries. I retrieve my data using ajax and I loop trough the data and group the results by colors (red, blue and yellow) and then divide them by months.
I setup base objects (dateCounts_Red, dateCounts_Blue and dateCounts_Yellow) so that by default it starts all months at 0. A counter would then add when it finds a match tot he apropriate color and month.
When I output my dateCounts I get:
{"2015":{"2015-12":1,"2015-10":null,"2015-08":null,"2015-11":null}}
{"2015":{"2015-12":0,"2015-10":null}}
{"2015":{"2015-12":0,"2015-10":null}}
Here is the code I have so far:
var dateCounts_Red = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Blue = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
var dateCounts_Yellow = {"2015":{"2015-01":0,"2015-02":0,"2015-03":0,"2015-04":0},"2015":{"2015-05":0},"2015":{"2015-06":0},"2015":{"2015-07":0},"2015":{"2015-08":0},"2015":{"2015-09":0},"2015":{"2015-10":0},"2015":{"2015-11":0},"2015":{"2015-12":0}};
data.d.results.forEach(function(element) {
var date = element.created_date.slice(0, 7);
var yr = date.slice(0, 4);
var Color = element.colorvalue;
if(Color == "red") {
dateCounts_Red[yr][date]++;
}
if(Color == "blue"){
dateCounts_Blue[yr][date]++;
}
if(Color == "yellow"){
dateCounts_Yellow[yr][date]++;
}
});
Red_yr_2015_data = [dateCounts_Red['2015']['2015-01'], dateCounts_Red['2015']['2015-02'], dateCounts_Red['2015']['2015-03'], dateCounts_Red['2015']['2015-04'], dateCounts_Red['2015']['2015-05'], dateCounts_Red['2015']['2015-06'], dateCounts_Red['2015']['2015-07'], dateCounts_Red['2015']['2015-08'], dateCounts_Red['2015']['2015-09'], dateCounts_Red['2015']['2015-10'], dateCounts_Red['2015']['2015-11'], dateCounts_Red['2015']['2015-12']];
Blue_yr_2015_data = [dateCounts_Blue['2015']['2015-01'], dateCounts_Blue['2015']['2015-02'], dateCounts_Blue['2015']['2015-03'], dateCounts_Blue['2015']['2015-04'], dateCounts_Blue['2015']['2015-05'], dateCounts_Blue['2015']['2015-06'], dateCounts_Blue['2015']['2015-07'], dateCounts_Blue['2015']['2015-08'], dateCounts_Blue['2015']['2015-09'], dateCounts_Blue['2015']['2015-10'], dateCounts_Blue['2015']['2015-11'], dateCounts_Blue['2015']['2015-12']];
Yellow_yr_2015_data = [dateCounts_Yellow['2015']['2015-01'], dateCounts_Yellow['2015']['2015-02'], dateCounts_Yellow['2015']['2015-03'], dateCounts_Yellow['2015']['2015-04'], dateCounts_Yellow['2015']['2015-05'], dateCounts_Yellow['2015']['2015-06'], dateCounts_Yellow['2015']['2015-07'], dateCounts_Yellow['2015']['2015-08'], dateCounts_Yellow['2015']['2015-09'], dateCounts_Yellow['2015']['2015-10'], dateCounts_Yellow['2015']['2015-11'], dateCounts_Yellow['2015']['2015-12']];
Im currently getting the following error from my Highcharts js:
Uncaught TypeError: Cannot set property 'index' of undefined
THis is preventing the chart system to work correctly the data returned is not being returned with it's expected data.
Here a full example to the issue https://jsfiddle.net/awo5aaqb/21/
Would anyone know what im missing?
Your date count objects have major structural flaw.
When you prettify them they look like:
var dateCounts_Blue = {
"2015": {
"2015-01": 0,
"2015-02": 0,
"2015-03": 0,
"2015-04": 0
},
"2015": {
"2015-05": 0
},
"2015": {
"2015-06": 0
},
"2015": {
"2015-07": 0
},
......
Object keys must be unique so these are clearly being repeated and the compiler will over write duplicates.
Fix the pattern that breaks away from the intended pattern grouping at the beginning
var dateCounts_Red = {
"2015":
{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0
},
};
var dateCounts_Blue = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0
}
};
var dateCounts_Yellow = {
"2015":{
"2015-01":0,
"2015-02":0,
"2015-03":0,
"2015-04":0,
"2015-05":0,
"2015-06":0,
"2015-07":0,
"2015-08":0,
"2015-09":0,
"2015-10":0,
"2015-11":0,
"2015-12":0}
};
Your data structure is flawed and such comparing values when doing the foreach loop becomes inconsistent because it compares it to multiple values, the above JSON is the fix for your problem.
Not quite codereview.stackexchange.com, but I heavily modified your javascript to make it work a bit better
$.ajax({
url: basePath,
dataType: 'json',
cache: false,
success: function(data) {
var counts = {};
data.d.results.forEach(function(element) {
// If you know it's all the same year, you could totally ignore this
var yr = element.created_date.slice(0, 4);
var month = parseInt(element.created_date.slice(5,7));
var color = element.colorvalue;
if (counts[color] === undefined) {
counts[color] = {};
}
if (counts[color][yr] === undefined) {
counts[color][yr] = {};
}
current_value = counts[color][yr][month];
if (current_value === undefined) {
// Doesnt exist yet, so add it
counts[color][yr][month] = 1;
} else {
// Exists, so increment by 1
counts[color][yr][month] = current_value + 1;
}
});
console.log(JSON.stringify(counts));
console.log(transform_series(counts['red']['2015']));
console.log(transform_series(counts['blue']['2015']));
console.log(transform_series(counts['yellow']['2015']));
var Options = {
chart: {
renderTo: 'myfirstchart',
type: 'column',
margin: 75,
options3d: {
enabled: true,
alpha: 25,
beta: 0,
depth: 70
}
},
title: {
text: "Test Highcharts"
},
subtitle: {
text: 'Test charts'
},
plotOptions: {
column: {
depth: 25
}
},
xAxis: {
categories: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
},
yAxis: {
title: {
text: "Number of entries"
}
},
tooltip: {
headerFormat: '<b>{point.key}</b><br>',
pointFormat: '<span style="color:{series.color}">\u25CF</span> {series.name}: {point.y} / {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
depth: 40
}
},
series: [{
name: 'Red',
color: 'red',
data: transform_series(counts['red']['2015']),
stack: '2015'
}, {
name: 'Blue',
color: 'blue',
data: transform_series(counts['blue']['2015']),
stack: '2015'
}, {
name: 'Yellow',
color: 'yellow',
data: transform_series(counts['yellow']['2015']),
stack: '2015'
}]
};
return new Highcharts.Chart(Options);
}
});
// this transforms the hash {10: 5, 11:1, 12:1} to get you all 12 months
// and returns an array of values [ 0, 0, 0, 0, 0 ... 5, 1, 1] that
// can be used in high charts
function transform_series(series) {
return Array.apply(null, Array(13)).map(function (_, i) {return (series[i] === undefined) ? 0 : series[i];}).slice(1,13);
}

Why is my addPoint() not recognized as a function in my highcharts code?

I am working with Highcharts and live data. I have my ajax all set up properly it seems and have a setTimeout called to bring in live data. Whenever that data comes in I want to addPoint() to my series and draw the new graph (shifting to the left). Below is my code, line 85 is the .addPoint call but you will see in the console that it is showing as not a function or undefined.
I know from the console as well that I am a calling my data correctly from my chart (chart1.data.series[0] returns and object). Here is the highcharts documentation on series data and addPoint : < http://api.highcharts.com/highcharts#Series.addPoint >
Any idea where I went wrong? I am new to js 1 year <. so I appreciate all your help!
<!doctype html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="container" style="width:100%"></div>
</body>
<script>
chart1 = {
yAxisMin: null,
yAxisMax: null
};
// empty objects for our data and to create chart
seriesData = [];
BPM = [];
time1 = [];
// console.log(chart1.data.series);
$(function() {
$(document).ready(function() {
Highcharts.setOptions({
global: {
useUTC: false
}
});
function requestData() {
var url = 'http://msbandhealth.azurewebsites.net/odata/PulsesAPI/';
$.ajax({
url: url,
dataType: 'json',
context: seriesData,
success: function(data) {
shift = chart1.data.series[0].data.length > 20;
// structure our data
for (var i = 0; i < data.value.length; i++) {
bpm = data.value[i].BPM;
time = data.value[i].Time;
console.log(time);
this.push([time, BPM]);
BPM.push(bpm);
time1.push(time);
}
// console.log(series[0]);
// find the highest pulse so we can set it to the highest y point
chart1.yAxisMax = (function(array) {
var pulse_array = [];
for (var i = 0; i < array.length; i++) {
if (array[i] != null) {
pulse_array.push(array[i]);
}
}
return Math.max.apply(Math, pulse_array);
})(BPM);
// find the lowest pulse rate and set it to lowest y point
chart1.yAxisMin = (function(array) {
var pulse_array = [];
for (var i = 0; i < array.length; i++) {
if (array[i] != null) {
pulse_array.push(array[i]);
}
}
return Math.min.apply(Math, pulse_array);
})(BPM);
// set our data series and create new chart
chart1.data.series[0].data = BPM;
chart = new Highcharts.Chart(chart1.data);
$('#container').css({
height: '400px'
});
chart1.data.series[0].addPoint(BPM, true, true);
// setTimeout(requestData, 3000);
console.log(chart1.data.series);
}
});
}
// give highcharts something to render to
container = document.getElementById("container");
chart1.data = {
chart: {
renderTo: container,
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: requestData()
}
},
title: {
text: ' Real Time Pulse Analysis'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
min: chart1.yAxisMin,
max: chart1.yAxisMax,
title: {
text: 'Heart Rate'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Beats Per Minute',
data: []
}]
};
});
});
</script>
</html>
You should use reference to chart and then call addPoint, instead of refer to chart configuration object.
Correct form: chart.series[0].addPoint()

Categories

Resources