Turn jQuery array of objects into a new array - javascript

Currently my Rails controller is returning an array of objects:
var _data = [];
$.getJSON(my_url, function(data) {
$.map(data, function(v) {
_data.push([v.occurrences, v.period])
});
});
console.log(_data) => []
Which when expanded looks like this:
Array[4]
0:Object
1:Object
2:Object
3:Object
And individual objects when expanded look like this:
0:Object
occurrences:1
period:1488499200000
I'm having trouble mapping the initial array of objects in such a way that my final result will be an array of arrays that is comprised of each objects' occurrences value and period value.
The end result should like like:
[[1488499200000, 1],[.., ..],[.., ..],[.., ..]]
So that I can use each array in a chart as an x and y axis point.
I've tried using .map, .each, (for i in ..), etc. with no luck.
EDIT:
This is my chart data:
var line_data2 = {
data: _data,
color: "#00c0ef"
};
$.plot("#myGraph", [line_data2], {
grid: {
hoverable: true,
borderColor: "#f3f3f3",
borderWidth: 1,
tickColor: "#f3f3f3"
},
series: {
shadowSize: 0,
lines: {
show: true
},
points: {
show: true
}
},
lines: {
fill: false,
color: ["#3c8dbc", "#f56954"]
},
yaxis: {
show: true,
},
xaxis: {
show: true,
mode: "time",
timeformat: "%m/%d/%Y"
}
});

There is likely a more elegant solution than this, but this will get you the shaped array I think you are asking for.
let _data = [
{occurrences: 1, period: 200},
{occurrences: 3, period: 300},
{occurrences: 6, period: 400}
];
let newData = _data.map((x)=>{
let arr = [];
arr.push(x.occurrences);
arr.push(x.period);
return arr;
});
console.log(newData);
You could take it a step further and simply loop through the object rather than hard coding the names.
let newData = _data.map((x)=>{
let arr = [];
for(let i in x){
arr.push(x[i]);
}
return arr;
});

Related

make highcharts graph with data in json format, with 4-element array

json data is of this type:
[["SSL Certificate Signed Using Weak Hashing Algorithm",4500,"98","10980"],["SSL Self-Signed Certificate",2000,"98","-1"],...]
I can correctly display the name (the first element) and the numeric value (second element).
I would like the third and fourth elements to appear along with the name.
I would also like to distinguish the bars with different colors based on the value of the third element. It's possible? How can I do?
This is the code I wrote:
$(document).ready(function() {
var options = {
chart: {renderTo:'grafico1',type:'column'},
series: [{ }] // Lascio vuoto
};
$.getJSON('json.json', function(data){
options.series[0].data = data;
var chart = new Highcharts.Chart(options);
});
});
Use jQuery to generate category array and 3 series arrays
Your third/forth values are not numeric, so they are parsed.
I create this jsFiddle and it works, check this:
https://jsfiddle.net/s87pg0ew/2/
javascript:
var myJsonData = [["SSL Certificate Signed Using Weak Hashing Algorithm",4500,"98","10980"],["SSL Self-Signed Certificate",2000,"98","-1"]];
var categories = [];
var value1 = [];
var value2 = [];
var value3 = [];
$.each(myJsonData, function( index, value ) {
categories.push(value[0]);
value1.push(value[1]);
value2.push(parseInt(value[2]));
value3.push(parseInt(value[3]));
});
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Test'
},
subtitle: {
text: 'Test'
},
xAxis: {
categories: categories,
title: {
text: null
}
},
yAxis: {
title: {
text: 'Test y axis',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 80,
floating: true,
borderWidth: 1,
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: "type1",
data: value1
}, {
name: "type2",
data: value2
}, {
name: "type3",
data: value3
}]
});
You can use the array.map feature in the simply way to parse your data.
const mainData = [["SSL Certificate Signed Using Weak Hashing Algorithm",4500,"98","10980"],["SSL Self-Signed Certificate",2000,"98","-1"]];
const categories = mainData.map(d => d[0]);
const data1 = mainData.map(d => d[1]);
const data2 = mainData.map(d => parseInt(d[2]));
const data3 = mainData.map(d => parseInt(d[3]));
Demo: https://jsfiddle.net/BlackLabel/btv80h1q/
But I think that those operations should be done on the backend side.

Where to add and register the custom attributes in flot-pie chart js?

Although this question has answer at: Adding custom attributes to flot data
but I have tried every possible way but my custom attributes are not showing on click event.
So far I tried this:
html:
<div id="audit_status" class="chart"></div>
JS:
var audit_status = [
{label: "Pending", data: 2, location_value="Majiwada,Pune"},
{ label: "Ongoing", data: 1 location_value="Mumbai"},
];
var options = {
series: {
pie: {
show: true,
label: {
show: true,
radius: 120,
formatter: function (label, series) {
return '<div style="border:1px solid grey;font-size:8pt;text-align:center;padding:5px;color:white;background-color: #90bdce;">' +
label + ' : ' +
series.data[0][1] +
' ('+Math.round(series.percent)+' %)</div>';
},
background: {
opacity: 0.8,
color: '#000'
}
}
}
},
legend: {
show: true
},
grid: {
hoverable: true,
clickable: true
}
};
$("#audit_status").bind("plotclick", function(event, pos, obj) {
console.log(obj);
//alert(obj.series.value);
if (obj) {
alert(obj.series.location_value);
}
});
$(document).ready(function () {
$.plot($("#audit_status"), audit_status, options);
});
The problem is: whenever I click the pie segment I want to alert "location_value"
but i am getting [Object Object]
I see two issues with the code as it is now. First, the audit_status JSON object isn't quite defined right. The location_value properties need to use colons, not equal signs:
var audit_status = [
{ label: "Pending", data: 2, location_value: "Majiwada,Pune" },
{ label: "Ongoing", data: 1, location_value: "Mumbai" }
];
Second, in your plotclick function, the extra properties defined in your data object don't make it over to the series object passed into the callback. You need to reference the original data object, using the obj.seriesIndex provided to the callback. This JSFiddle provides an example of the code below.
var data = [{
label: "Yes",
data: 50,
location_value: 'Majiwada,Pune'
}, {
label: "No",
data: 150,
location_value: 'Mumbai'
}];
// plot initialization code here
$("#pie").bind("plotclick", function(event, pos, obj) {
if (obj) {
// use the obj.seriesIndex to grab the original data object,
// then you can use any property you defined on that object
alert(data[obj.seriesIndex].location_value);
}
});

Add dynamic series

I'm using Highcharts plugin and I have two array, here is an example of my arrays:
array1: Serie1, Serie2, Serie3
array2: 20, 30, 40
What I want to do is use this array in series options, array 1 as serie name and array 2 as serie value, I could do this manually but in the future maybe array1 is going to have more values and also array2.
$('#Chart').highcharts({
title: {
text: 'Example'
},
xAxis: {
labels:
{
enabled: false
}
},
yAxis: {
allowDecimals: true,
min: 0,
title: {
text: 'Results'
}
},
credits: {
enabled: false
},
legend: {
reversed: true
},
series: [{
name: array1[x],
data: array2[x].map(function (value) {
return Number(value);
})
}]
});
I tried using a for loop but I think that is not possible use this inside series option. Also I'm trying using a for loop outside the highcharts code and using a string var concatenating the above code but I'm not pretty sure about this, here is my code:
var constructor = "";
for (var i = 0; i < array1.length; i++) {
constructor += "name: '"+ array1[i] + "',";
constructor += "data: " + array2[i] + ".map(function (value) {"
constructor += "return Number(value);";
})
You could create the graph without series and then in a separate function you can do iterations on the array to get the data correctly and dynamically add the series in this way:
for (var i = 0; i < array1.length; i++) {
chart.addSeries({
name: array1[i],
data: [array2[i]]
}, false);
}
chart.redraw();
Not tested but the idea is that

Javascript: how can I populate an array of property values dynamically?

I have an array of values, which I want to insert into a property of an object, but I'm not sure how. Here's my object. The property is called "values" (located at the very bottom), and as you can see, I'm trying to insert a dynamic list of data (called "result") into it:
var myConfig = {
globals: {
fontFamily: "Roboto"
},
type: "bar",
backgroundColor: "#f4f2f2",
plotarea: {
backgroundColor: "#fff"
},
scaleX: {
lineColor: "#7d7d7d",
tick: {
lineColor: "#7d7d7d"
},
guide: {
visible: false
},
values: [result[0]["Heading"], result[1]["Heading"], result[2]["Heading"], ...],
}};
Is there any way I can set this up to dynamically place this result["Heading"] data into my "values" property?
Thanks
So, assuming results is an array of objects that have the Heading property, you can get an array of only those, using the map function, like this:
values: result.map(function(item){ return item.Heading; })
map is a new-ish function, defined in ECMAScript 5.1, but all major browsers support it. Basically, for every item in the array, it will execute the provided selector function, and return the result. So, you're starting with an array of objects having a Heading property, and ending up with an array of the Heading property values themselves.
Make another function to do that.
It's an Array.
You should traverse it at least once.
function getHeading( arr ) {
var aa = [];
for( var i = 0, size = arr.length ; i < size ; i++ ) {
aa.push( arr[i].Heading );
}
return aa;
}
var myConfig = {
globals: {
fontFamily: "Roboto"
},
type: "bar",
backgroundColor: "#f4f2f2",
plotarea: {
backgroundColor: "#fff"
},
scaleX: {
lineColor: "#7d7d7d",
tick: {
lineColor: "#7d7d7d"
},
guide: {
visible: false
},
values: getHeading( result ),
}};

javascript associative array, looping, and / or scope issue with Highcharts JSON call

I have a javascript associative array issue, looping issue, and / or scope issue. I'm trying to call data from a postgresql database, parse it, and implement it in a Highchart.
The data consists of five series with five items (columns / fields) each:
[Object, Object, Object, Object, Object]
Opened, the fifth object looks like:
4: Object
acronym: "1"
current: "3.4"
id: 1
name: "a"
pc1: "2.5"
previous: "2.4"
url: "http://myhost:3000/series/1.json"
__proto__: Object
length: 5
__proto__: Array[0]
After parsing, I get a sequence of objects:
[Object]
[Object]
[Object]
[Object]
[Object]
Which consist of the parsed data expect, i.e., a k:v pair [name: "a", y: 2.5]:
[Object]
0: Object
name: "a"
y: 2.5
__proto__: Object
length: 1
__proto__: Array[0]
However, what I need is an array of objects:
[{name: "a", y: 2.5}, {name: "b", y: 3.0}, {name: "c", y: 1.0}, {name: "d", y: 2.0}, {name: "e", y: 3.2}]
If I insert "dummy" data - below - the chart renders correctly, so the issue's with my code, specifically, the creation of the array and its availability outside the JSON function.
[{name: 'name1', y: 2.5}, {name: 'name2', y: 4.0}];
Any and all help would be appreciated. Here's the entire javascript code for the Highchart - with notes where the issues are.
$(document).ready(function () {
var options = {
chart: {
renderTo: 'container',
type: 'column',
},
title: {
text: 'The Conference Board'
},
legend: {
enabled: false
},
subtitle: {
text: 'Leading Indicators '
},
xAxis: {
type: 'category',
labels: {
rotation: -45,
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
credits: {
enabled: false
},
yAxis: {
title: {
text: 'Percent Change Year / Year'
},
},
series: [{
data: [] // dummy code inserted here makes the chart render
}]
};
url = "http://myhost:3000/series";
$.getJSON(url, function (series) {
console.log(series); // five series of five k:v pairs each
$.each(series, function(key_i, val_i) { // parsing to a single k:v (name: value) pair
data = []; // I'm trying to create an array of objects // [{},{},{},{},{}]
data.push({ // for insertion into the var options.series.data above
name: val_i.name,
y: parseFloat(val_i.pc1)
});
options.series[0].data = data;
console.log(options.series[0].data); // getting all k:val_i pairs sequentially; however, not as an array of objects
});
options.series[0].data = data;
console.log(options.series[0].data); // only getting the last k:v pair and the chart doesn't render
});
console.log(options.series[0].data); // an empty array []
var chart = new Highcharts.Chart(options);
});
Again, thank you in advance for your help with this. I've been working on it for days.
try
$.getJSON(url, function (series) {
options.series[0].data = $.map(series, function(val) {
return { name: val.name, y: parseFloat(val.pc1) };
});
new Highcharts.Chart(options);
});
Update fix your existing each loop
$.getJSON(url, function (series) {
var data = [];
$.each(series, function(val) {
data.push({ name: val.name, y: parseFloat(val.pc1) });
});
options.series[0].data = data;
new Highcharts.Chart(options);
});
I believe something like:
var jsonArray = yourArray.map(function(item) { return JSON.stringify(item); });
will handle the conversion to JSON for you.

Categories

Resources