Convert regular json to flare.json for d3.js? - javascript

I have a json like so:
{
"a": {
"x": {
"y": {
"a": {},
"z": {},
"b": {}
}
},
"c": {},
"b": {
"c": {
"d": {}
}
},
"d": {},
...
}
}
Is there a quick way to convert it to flare.json format?
Like so:
{
"name":"a",
"children":[
{
"name":"x",
"children":
{
"name":"y",
"children":[{"name":"a", "size":0},{"name":"z","size":0},{"name":"b","size":0}]
...
}
Thank you.

I have come up with a series of regex transforms for this.
#replace-this #with-this
^\s*" \{"name":"
: \{\}, \},
: \{\} \}
": \{$ ","children":\[
^\s*\}, \]\},
^\s*\} \]\}
#in that order
and just delete the first and last line (should be an extra { and ]} )
on applying these regex transforms,
this:
{
"a": {
"x": {
"y": {
"a": {},
"z": {},
"b": {}
}
},
"c": {},
"b": {
"c": {
"d": {}
}
},
"d": {}
}
}
will become this:
{
"name": "a",
"children": [{
"name": "x",
"children": [{
"name": "y",
"children": [{
"name": "a"
},
{
"name": "z"
},
{
"name": "b"
}]
}]
},
{
"name": "c"
},
{
"name": "b",
"children": [{
"name": "c",
"children": [{
"name": "d"
}]
}]
},
{
"name": "d"
}]
}
which can then be used with some of the d3js examples.

You are going to have to write your own JSON or a function to dynamically change the JSON. Flare.json just follows a schema that adheres to Mike Bostock's d3 files.
I'll give you a hint. The schema that you wrote appears to be (in psuedocode)
array("name":"a", "children":array("name":"x","children":array(.....
Basically, you need to create a multidimensional array in order to get the desired results. I don't know how you are getting your data, unfortunately, so I can't tell you much more. If using php use the json_encode method
echo json_encode($jsonArray)
or in javascript use json.stringify
var json = JSON.stringify($jsonArray)
in order to get the array to turn into json.

You can use d3.nest(), however this function won't give you the size as desired, even . You might want to format your data accordingly before sending it to the app.
If you want to create a custom function, then you can have a look at this answer and iterate on the keys of your object, as it is not even an array.

Related

Read Google Sheet Exported JSON by column name in Apps Script

I'm exploring the use of JSON exported Google Sheets as database for Apps Script.
The fetched url follows the structure:
https://docs.google.com/spreadsheets/d/DOCUMENTID/gviz/tq?tqx=out:json&gid=SHEETID
JSON.json
{
"reqId": "0",
"sig": "000",
"status": "ok",
"table": {
"cols": [
{
"id": "A",
"label": "",
"type": "string"
},
{
"id": "B",
"label": "",
"type": "string"
},
{
"id": "C",
"label": "",
"type": "string"
}
],
"parsedNumHeaders": 0,
"rows": [
{
"c": [
{
"v": "Data 1-1"
},
{
"v": "Data 1-2"
},
{
"v": "Data 1-3"
}
]
},
{
"c": [
{
"v": "Data 2-1"
},
{
"v": "Data 2-2"
},
{
"v": "Data 2-3"
}
]
},
{
"c": [
{
"v": "Emails"
},
{
"v": "Ids"
},
{
"v": "Names"
}
]
}
]
},
"version": "0.6"
}
In this function I'm getting returned an array of values for the C column:
dataArray = [Data 1-3, Data 2-3]
function getRolePermission(databaseUrl) {
let databaseParsed = JSON.parse(UrlFetchApp.fetch(databaseUrl).getContentText().match(/(?<=.*\().*(?=\);)/s)[0]);
let tableLength = Object.keys(databaseParsed.table.rows).length;
let dataArray = [];
for (let i = 0; i < tableLength; i++) {
dataArray.push(databaseParsed.table.rows[i].c[2].v)
}
return dataArray;
}
It works well, but I don't know how to make this function more generic, so I call it with (url, headerName) arguments to get an array with the values of a column. Something like:
function getRolePermission(databaseUrl, headerName) {
// CODE ??
return dataArray;
}
getRolePermission('https://docs.google.com/spreadsheets/d/1lc...', 'Emails')
to get dataArray = [Data 1-3, Data 2-3], so if I change the order of columns I'm still getting the same results.
dataArray.push(databaseParsed.table.rows[i].c[2].v)
You just need to find the index 2 here to make the function more generic. The table.cols should give you the column headers, but it is not doing that because parsedNumHeaders is 0 in your case. To manually set number of headers, use &headers=1. The url should look like:
https://docs.google.com/spreadsheets/d/DOCUMENTID/gviz/tq?tqx=out:json&gid=SHEETID&headers=1
The response then would look like:
{
"reqId": "0",
"sig": "000",
"status": "ok",
"table": {
"cols": [
{
"id": "A",
"label": "Names",
"type": "string"
},
{
"id": "B",
"label": "Ids",
"type": "string"
},
{
"id": "C",
"label": "Emails",
"type": "string"
}
],
"parsedNumHeaders": 1,
"rows": [
{
"c": [
{
"v": "Data 1-1"
},
{
"v": "Data 1-2"
},
{
"v": "Data 1-3"
}
]
},
{
"c": [
{
"v": "Data 2-1"
},
{
"v": "Data 2-2"
},
{
"v": "Data 2-3"
}
]
}
]
},
"version": "0.6"
}
Once you get the headers, you can find the index:
const columnNeeded = databaseParsed.table.cols.findIndex(obj => obj.label === headerName/*"Emails"*/);
Then, use it in your function
dataArray.push(databaseParsed.table.rows[i].c[columnNeeded].v)

java script to parse an array from json

{
"took": 72,
"hits": {
"total": {
"value": 10000
}
},
"aggregations": {
"2": {
"buckets": [{
"key": "Perf",
"doc_count": 159874
}]
}
}
}
Could someone guide me to take the value of buckets
The built-in JSON should do the heavy lifting for you:
const str = '{ "took": 72, "hits": { "total": { "value": 10000 } }, "aggregations": { "2": { "buckets": [{ "key": "Perf", "doc_count": 159874 }] } } }';
const obj = JSON.parse(str);
the_arry = obj['aggregations']['2']['buckets'];
This should work:
var myrs = { "took": 72, "hits": { "total": { "value": 10000 } }, "aggregations": { "2": { "buckets": [{ "key": "Perf", "doc_count": 159874 }] } } };
for(var i in myrs["aggregations"]) {console.log(myrs["aggregations"][i]['buckets']);}
You can start by parsing the JSON string with var obj = JSON.parse(). It gives you an object representation of the string to work on. Log the object to the console to easily discover the structure console.log(obj); or use an online JSON viewer to do that.
Assuming the structure is fixed, the buckets array can be accessed by var buckets = obj.aggregations["2"].buckets. Notice the access of the property 2.

Remove special characters from a specific JSON object in JSON payload

I have a large JSON payload and I want to format, the specific object of the payload using JS.
I want flightdetails array object to edit and remove the special characters from it. How can I achieve this?
I have been working on this using XSLT for the past 2 days, and I went nowhere hence I decided to remove it using JS.
Example of the array(there can be more than 30 records inside the flightdetails)
"flightdetails": [
{
"id": XF-2092,
"trips": 2,
"categories": {
"flights": [
"\"return\",\"oneway\""
]
},
"id": XF-2093,
"trips": 1,
"categories": {
"flights": [
"\"return\""
]
}
}
]
Expected Output
"flightdetails": [
{
"id": XF-2092,
"trips": 2,
"categories": {
"flights": [
"return","oneway"
]
},
"id": XF-2093,
"trips": 1,
"categories": {
"flights": [
"return"
]
}
}
]
The flightdetails object inside the //destinations/flightdetails path

Angularjs: Convert objects to arrays

This is my data:
$scope.data = [
{
"top":"2",
"status":"1",
"name":"Anna",
},
{
"top":"2",
"status":"1",
"name":"Jodie",
},
{
"top":"2",
"status":"1",
"name":"susan",
}
];
Now I want to convert the objects to arrays. When I run my program I get this following output in console log:
{
"1":{
"2":"3"
}
}
But I need them to output as an array not object. Someone told me to use map function but I need to do them without using map function because it will cause a conflict in the process of my project. Is there any other way to do it without using map function?
The 1 in output means status object. 2 means top object and 3 means the number of students who's top is in 2.
This is the code I have so far: http://jsfiddle.net/DharkRoses/sjz5aLv1/
Any suggestions? TIA
Update:
I want the output which looks like this:
(
[1] =>Array
(
[2] => 3
)
)
I took below array for processing:
$scope.data = [
{ "top": "1", "status": "1", "name": "Anna" },
{ "top": "2", "status": "1", "name": "Jodie" },
{ "top": "2", "status": "1", "name": "Susan" },
{ "top": "3", "status": "1", "name": "Eddie" },
{ "top": "2", "status": "2", "name": "Megan" },
{ "top": "2", "status": "2", "name": "Frank" }
];
If I am not wrong you want a response like that:
[
{
"1": [
{ "1": 1 },
{ "2": 2 },
{ "3": 1 }
]
},
{
"2": [
{ "2": 2 }
]
}
]
This is a live demo in order to achieve above result: http://jsfiddle.net/nerezo/vz0dbdeq/

Create a map out of a grouped array objects

I'm using Underscore.js to map a new object array out of an existing object array but cannot really get the desired results.
Essentially I have an object array like:
[
{
"total": 5.21,
"number": 3,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 374.65,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
},
{
"total": 310.84,
"number": 1,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 284.41,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
}
]
which I would like to map into something like:
[
{
"key": "Paid",
"values": [
[
"2015-01-17T23:58:34.115Z",
5.21
],
[
"2015-01-17T23:58:34.115Z",
310.84
]
]
},
{
"key": "Scheduled",
"values": [
[
"2015-01-18T02:16:03.503Z",
374.65
],
[
"2015-01-18T02:16:03.503Z",
284.41
]
]
}
]
I've tried using the ._map method returns a map like this (JSFiddle):
var mapped_bill = _.map(bill, function(item) {
return {"key": item.a, "values": [item.d, item.total]}
});
console.log(JSON.stringify(mapped_bill));
/* returns:
[
{
"key": "Paid",
"values": [
"2015-01-17T23:58:34.115Z",
5.21
]
},
{
"key": "Scheduled",
"values": [
"2015-01-18T02:16:03.503Z",
374.65
]
},
{
"key": "Paid",
"values": [
"2015-01-17T23:58:34.115Z",
310.84
]
},
{
"key": "Scheduled",
"values": [
"2015-01-18T02:16:03.503Z",
284.41
]
}
]
*/
How do I group the resulting map above so that I can achieve the desired map?
You can use two _.map methods with _.groupBy:
var result = _.map(_.groupBy(data, 'a'), function(el, key) {
return {
key: key,
values: _.map(el, function(item) {
return [item.d, item.total];
})
};
});
Check the demo below.
var data = [
{
"total": 5.21,
"number": 3,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 374.65,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
},
{
"total": 310.84,
"number": 1,
"a": "Paid",
"y": 2015,
"m": 1,
"d": "2015-01-17T23:58:34.115Z"
},
{
"total": 284.41,
"number": 3,
"a": "Scheduled",
"y": 2015,
"m": 1,
"d": "2015-01-18T02:16:03.503Z"
}
];
var result = _.map(_.groupBy(data, 'a'), function(el, key) {
return {
key: key,
values: _.map(el, function(item) {
return [item.d, item.total];
})
};
});
pre.innerHTML = JSON.stringify(result, null, 4);
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<pre id="pre"></pre>
Going by your history here then it could be assumed this is actually a mongodb question even though you are just looking at the resulting JavaScript object in the question as presented.
So with the structure you mention actually being the members of a MongoDB collection then the answer to produce the the required output would be:
db.mapped.aggregate([
{ "$group": {
"_id": "$a",
"values": {
"$push": {
"$map": {
"input": { "$literal": ["A","B"] },
"as": "l",
"in": {
"$cond": [
{ "$eq": [ "$$l", "A" ] },
"$d",
"$total"
]
}
}
}
}
}}
])
So the $map operator there processes our "two element array template" provided in the $literal operator section, and "transposes" the values via the $cond "ternary" to either produce the element from "$d" where the first "A" element is matched or the element "$total" where the element is not "A" but therefore "B" as the only other logical choice.
Results in mapping an array that has the first elementof the first match and the second element as the other expected value. These can then be provided to $push, to create and "array of arrays" as requested.
Which produces from your source as a collection:
{
"_id" : "Scheduled",
"values" : [
[
"2015-01-18T02:16:03.503Z",
374.65
],
[
"2015-01-18T02:16:03.503Z",
284.41
]
]
},
{
"_id" : "Paid",
"values" : [
[
"2015-01-17T23:58:34.115Z",
5.21
],
[
"2015-01-17T23:58:34.115Z",
310.84
]
]
}
So you didn't need this post processing in JavaScript as you thought you did. Using the operators that are appropriate to match your conditions on the server side $group is all you need.

Categories

Resources