How to process user defined json format in D3.js - json

I have a json File that is in the format. I would like to access each branch and sub branch of this file using d3.js
"x":
{
"a":
{
no.of employees:30
total salary:2500000
count_email:25
}
"b":
{
no.of employees:20
total salary:350000
count_email:25
}
}
"y":
{
"c":
{
no.of employees:30
total salary:4500000
count_email:30
}
}
"z":
{
"d":
{
no.of employees:40
total salary:550000
count_email:40
}
"e":
{
no.of employees:10
total salary:100000
count_email:15
}
"f":
{
no.of employees:15
total salary:1500000
count_email:15
}
}
How can i access each branch and sub branch for processing. How to know the keys of this json format

Your Json is in a wrong format :
Before anything, validate it with a tool like JsonLint.com.
It should look something like that :
data = {
"x": [{
"a": {
"ff": 30,
"fff": 2500000,
"fff": 25
},
"b": {
"ff": 30,
"fff": 2500000,
"fff": 25
}
}],
"y": [{
"a": {
"ff": 30,
"fff": 2500000,
"fff": 25
},
"b": {
"ff": 30,
"fff": 2500000,
"fff": 25
}
}]
};
You could iterate into your object like that :
Employee = [];
for (x in data) {
// Access to the first level
for (y in x) {
//Access to the second level
console.log(data[x][y]);
// Here you could store each of your object into a new tab that you could use in d3.js
Employee.push(data[x][y]);
}
}

Nothing special in D3 to do this.
You can use simple javascript to deal with this case.
Something like this:
d3.json("my.json", function(error, json) { //load json using d3
if (error) return console.warn(error);
var keys = Object.keys(json); //get all the keys
console.log(keys, "Branch") //print on console
keys.forEach(function(key){
var subBranch = Object.keys(json[key]); //get all subbranch for key
console.log(subBranch, "SubBranch of " + key); //print subbranch and key
})
});
will produce output like this:
["x", "y", "z"] "Branch"
["a", "b"] "SubBranch of x"
["c"] "SubBranch of y"
["d", "e", "f"] "SubBranch of z"
working code here

Related

How to read from a JSON with two keys

I have a json that I need to import and then return a certain value. The json has two keys, like
{
"NUM_High_Objects": {
"abseta_pt": {
"field1:[0.0,0.9]": {
"field2:[15,20]": {
"tagIso": 0.00012,
"value": 0.99
},
"field2:[20,25]": {
"tagIso": 0.00035,
"value": 0.98
}
},
"field1:[0.91,1.2]": {
"field2:[15,20]": {
"tagIso": 0.00013,
"value": 0.991
},
"field2:[20,25]": {
"tagIso": 0.00036,
"value": 0.975
}
},
"binning": [
{
"binning": [
0.0,
0.9,
1.2,
2.1,
2.4
],
"variable": "abseta"
},
{
"binning": [
15,
20,
25,
30,
40,
50,
60,
120
],
"variable": "pt"
}
]
}
},
What I need is to search if a pair of values is within the range of "field1" and "field2" and return the corresponding "value"
I tried following this Search nested json / dict for multiple key values matching specified keys but could not make it to work...
I ve tried something like
class checkJSON() :
def __init__(self,filein) :
self.good, self.bad = 0, 0
print 'inside json function : will use the JSON', filein
input_file = open (filein)
self.json_array = json.load(input_file)
def checkJSON(self,LS,run) :
try :
LSlist = self.json_array[str(run)]
for LSrange in LSlist :print LSrange, run
except KeyError :
pass
self.bad += 1
return False
CJ=''
CJ=checkJSON(filein='test.json')
isInJSON = CJ.checkJSON("0.5", "20")
print isInJSON
but this does not work as I am not sure how to loop inside the keys
If I am understanding your question correctly then the relevant portion of your JSON is:
{
"field1:[0.0,0.9]": {
"field2:[15,20]": {
"tagIso": 0.00012,
"value": 0.99
},
"field2:[20,25]": {
"tagIso": 0.00035,
"value": 0.98
}
},
"field1:[0.91,1.2]": {
"field2:[15,20]": {
"tagIso": 0.00013,
"value": 0.991
},
"field2:[20,25]": {
"tagIso": 0.00036,
"value": 0.975
}
},
"binning": [
{
"binning": [
0.0,
0.9,
1.2,
2.1,
2.4
],
"variable": "abseta"
},
{
"binning": [
15,
20,
25,
30,
40,
50,
60,
120
],
"variable": "pt"
}
]
}
Then the following code should do what you are trying to achieve. It doesn't look like you need to search for nested keys, you simply need to parse your field1[...] and field2[...]. The code below is a quick implementation of what I understand you are trying to achieve. It will return the value if the first parameter is in the range of a field1[...] and the second parameter is in the range of a field2[...]. Otherwise, it will return None.
import json
def check_json(jsondict, l1val, l2val):
def parse_key(keystr):
level, lrange = keystr.split(':')
return level, eval(lrange)
for l1key, l2dict in jsondict.items():
if 'field' in l1key:
l1, l1range = parse_key(l1key)
if l1val >= l1range[0] and l1val <= l1range[1]:
for l2key, vals in l2dict.items():
l2, l2range = parse_key(l2key)
if l2val >= l2range[0] and l2val <= l2range[1]:
return vals['value']
return None
Here is a driver code to test the implementation above.
if __name__ == '__main__':
with open('data.json', 'r') as f:
myjson = json.load(f)
print(check_json(myjson, 0.5, 20))

Modify nested arrays in JSON (Groovy)

I'm trying to parse and mofidy JSON with Groovy. Source JSON from REST API looks like:
[
{
"id":27858,
"type":"ad",
"stats":[
{
"day":"2021-01-21",
"sex":[
{
"impressions_rate":0.349,
"value":"f"
},
{
"impressions_rate":0.621,
"value":"m",
"clicks_rate":0.22
}
],
"age":[
{
"impressions_rate":0.217,
"value":"18-21"
}
]
},
{
"day":"2021-02-25",
"sex":[
{
"impressions_rate":0.349,
"value":"f"
},
{
"impressions_rate":0.651,
"value":"m"
}
],
"age":[
{
"impressions_rate":0.217,
"value":"18-21"
}
]
}
]
},
{
"id":565291,
"type":"ad",
"stats":[
{
"day":"2021-03-21",
"sex":[
{
"impressions_rate":0.78,
"value":"f",
"clicks_rate":0.33
},
{
"impressions_rate":0.551,
"value":"m"
}
],
"age":[
{
"impressions_rate":0.17,
"value":"18-21"
}
]
}
]
}
]
It's an array with some ids and data for them. I want to grab id, day inside stats array and elements from sex array. After all manipulations my JSON should be like this:
[
{
"id": 27858,
"day": "2021-01-21",
"impression_rate": 0.349,
"value": "f"
},
{
"id": 27858,
"day": "2021-01-21",
"impression_rate": 0.621,
"value": "f",
"clicks_rate": 0.22
},
{
"id": 27858,
"day": "2021-02-25",
"impressions_rate":0.349,
"value":"f"
},
{
"id": 27858,
"day": "2021-02-25",
"impressions_rate":0.651,
"value":"m"
},
{
"id": 565291,
"day": "2021-03-21",
"impressions_rate":0.78,
"value":"f",
"clicks_rate":0.33
},
{
"id": 565291,
"day": "2021-03-21",
"impressions_rate":0.78,
"value":"f",
"clicks_rate":0.33
}
]
So, the main goal is - loop through all ids -> elements in sex array (for each id) and add to these elements day and id mapped fields. I tried to start with empty map with inject, but after 1 hour of debugging i still can't achieve desired output, so maybe better to loop through existed values in array? But I can't even reach sex array.
import groovy.json.*
def json = new JsonSlurper().parseText '''...'''
List expected = json.inject([]){ r, e ->
Map ids = e.findAll {
k, v -> k == "id"
}
e.each{ k, v ->
if( (v.any{ it.sex } )
v.each{ r << ids + it }
}
return r
}
If you have nested structures, that contain again nested structures,
a good option, to get a flat result, is to use collectMany; like
collect it transforms each item of the iterated container, but the
results gets concated.
E.g. you can collectMany on your outer data, then again on the
stats, and finally just collect over sex.
def data = new groovy.json.JsonSlurper().parse("data.json" as File)
println data.collectMany{ o ->
o.stats.collectMany{ i ->
i.sex.collect{ it + [id: o.id, day: i.day] }
}
}
// [[impressions_rate:0.349, value:f, id:27858, day:2021-01-21],
// [impressions_rate:0.621, value:m, clicks_rate:0.22, id:27858, day:2021-01-21],
// [impressions_rate:0.349, value:f, id:27858, day:2021-02-25],
// [impressions_rate:0.651, value:m, id:27858, day:2021-02-25],
// [impressions_rate:0.78, value:f, clicks_rate:0.33, id:565291, day:2021-03-21],
// [impressions_rate:0.551, value:m, id:565291, day:2021-03-21]]

Representing a graph in JSON

Inspired by this question, I'm trying to represent a DAG in JSON. My case includes edges and nodes that contain some data (rather than just strings as in this example). I was thinking of a spec like this:
{
"graph": {
"a": ["b", "c"],
"b": ["c"]
"c"
},
"nodes": {
"a": {
"name": "Adam"
},
"b": {
"name": "Bob"
},
"c": {
"name": "Caillou"
}
},
"edges": {
// how to do the same for edges?
// ie: how to query edges ?
}
}
One idea I had was to make the keys of the edges be the concatenation of the two vertex ids that it connects. For example, ab, ac, and bc are the three edges in this graph. I want to know if there's a more standard way of doing this.
EDIT: This is what I'm thinking of now
{
"graph": {
"a": {
"data": {
// a's vertex data
},
"neighbors": {
"b": {
"data": {
// data in edge ab
}
},
"c": {
"data": {
// data in edge ac
}
}
}
},
"b": {
"data": {
// b's vertex data
},
"neighbors": {
"c": {
"data": {
// data in edge bc
}
}
}
},
"c": {
"data": {
// c's vertex data
}
}
}
}
Since the DAG's edges hold data, they better have their own identifiers, just like the nodes. That is, the json representation should be composed of three components:
Node records: mapping each node identifier to the node's data.
Edge records: mapping each edge identifier to the edge's data.
Adjacency lists: mapping each node identifier to an array of edge identifiers, each corresponds to an edge going out of the node.
DAG = {
"adjacency": {
"a": ["1", "2"],
"b": ["3"]
},
"nodes": {
"a": {
// data
},
"b": {
// data
},
"c": {
// data
}
},
"edges": {
"1": {
"from": "a", "to": "b",
"data": {
// data
}
},
"2": {
"from": "a", "to": "b",
"data": {
// data
}
},
"3": {
"from": "b", "to": "c",
"data": {
// data
}
}
}
}
Turns out there are standards that are trying to emerge for this sort of thing. I recently had to look these up for a project of my own. You might be interested in http://jsongraphformat.info/ for example, or one of the peer projects it references on its website. Goals include trying to represent in JSON anything you can represent in the DOT language (https://en.wikipedia.org/wiki/DOT_(graph_description_language)).
json-ld was made for this. It has a semi-steep learning curve, but it is a robust way to represent graph data in json.

Put Data in mutlple branch of Array : Json Transformer ,Scala Play

i want to add values to all the arrays in json object.
For eg:
value array [4,2.5,2.5,1.5]
json =
{
"items": [
{
"id": 1,
"name": "one",
"price": {}
},
{
"id": 2,
"name": "two"
},
{
"id": 3,
"name": "three",
"price": {}
},
{
"id": 4,
"name": "four",
"price": {
"value": 1.5
}
}
]
}
i want to transform the above json in
{
"items": [
{
"id": 1,
"name": "one",
"price": {
"value": 4
}
},
{
"id": 2,
"name": "two",
"price": {
"value": 2.5
}
},
{
"id": 3,
"name": "three",
"price": {
"value": 2.5
}
},
{
"id": 4,
"name": "four",
"price": {
"value": 1.5
}
}
]
}
Any suggestions on how do i achieve this. My goal is to put values inside the specific fields of json array. I am using play json library throughout my application. What other options do i have instead of using json transformers.
You may use simple transformation like
val prices = List[Double](4,2.5,2.5,1.5).map(price => Json.obj("price" -> Json.obj("value" -> price)))
val t = (__ \ "items").json.update(
of[List[JsObject]]
.map(_.zip(prices).map(o => _._1 ++ _._2))
.map(JsArray)
)
res5: play.api.libs.json.JsResult[play.api.libs.json.JsObject] = JsSuccess({"items":[{"id":1,"name":"one","price":{"value":4}},{"id":2,"name":"two","price":{"value":2.5}},{"id":3,"name":"three","price":{"value":2.5}},{"id":4,"name":"four","price":{"value":1.5}}]},/items)
I suggest using classes, but not sure this fits to your project because it's hard to guess how your whole codes look like.
I put new Item manually for simplicity. You can create items using Json library :)
class Price(val value:Double) {
override def toString = s"{value:${value}}"
}
class Item(val id: Int, val name: String, val price: Price) {
def this(id: Int, name: String) {
this(id, name, null)
}
override def toString = s"{id:${id}, name:${name}, price:${price}}"
}
val price = Array(4, 2.5, 2.5, 1.5)
/** You might convert Json data to List[Item] using Json library instead. */
val items: List[Item] = List(
new Item(1, "one"),
new Item(2, "two"),
new Item(3, "three"),
new Item(4, "four", new Price(1.5))
)
val valueMappedItems = items.zipWithIndex.map{case (item, index) =>
if (item.price == null) {
new Item(item.id, item.name, new Price(price(index)))
} else {
item
}
}

Using QUERY URL to group data before sending to Google Apps Script dashboard

I have a Google Spreadsheet, with say a key 'ABCKEY' and would like to perform the QUERY (SQL) function on the data before using the data in a Google Apps Script dashboard.
var ss = SpreadsheetApp.openById('ABCKEY');
var mydata = ss.getDataRange();
This article explains how one can use the QUERY feature on the data in the spreadsheet to produce grouped data.
The following query produces the correct grouped data I would like to use as the data source of my Google Apps Script dashboard:
https://spreadsheets.google.com/a/mybusinessappdomain.com/tq?key=ABCKEY&tq=select%20A%2CC%2Csum(F)%2Csum(G)%20group%20by%20A%2C%20C
I would therefore essentially like to populate the mydata variable above with the result from the above SQL query, which produces a JSON output string.
How can this be accomplished?
The approach I propose is this:
Use UrlFetchApp.fetch() to get the results of the query uri into a variable in your script. The query URI returns javascript to set results for the google visualization service.
Remove any extraneous content in the result, leaving only the JSON representation of the query results. A simple regex extraction can do this, and then we can parse the extracted string into a JSON object.
Decode the JSON object into a two-dimensional array, mydata. This requires some understanding of how the table is represented as a JSON object in the visualization query.
The JSON query result is structured like this:
{
"version": "0.6",
"status": "ok",
"sig": "862651648",
"table": {
"cols": [
{
"id": "A",
"label": "",
"type": "string",
"pattern": ""
},
{
"id": "D",
"label": "Population Density",
"type": "number",
"pattern": "#0.###############"
}
],
"rows": [
{
"c": [
{
"v": "Indonesia"
},
{
"v": 117,
"f": "117"
}
]
},
{
"c": [
{
"v": "China"
},
{
"v": 137,
"f": "137"
}
]
},
{
"c": [
{
"v": "Nigeria"
},
{
"v": 142,
"f": "142"
}
]
},
{
"c": [
{
"v": "Pakistan"
},
{
"v": 198,
"f": "198"
}
]
},
{
"c": [
{
"v": "India"
},
{
"v": 336,
"f": "336"
}
]
},
{
"c": [
{
"v": "Japan"
},
{
"v": 339,
"f": "339"
}
]
},
{
"c": [
{
"v": "Bangladesh"
},
{
"v": 1045,
"f": "1045"
}
]
}
]
}
}
You'll notice that the table object consists of an array of cols objects that describe the columns in the table. For your array, the portion that you're interested in is the label for the column.
After that, the table object contains an array of rows objects, each with an array of c objects with the data for each column in the row. For your array, it's the v or value that you're interested in. (f contains a formatted version of the same data)
So our parser will iterate through the column headers first, then through each row of the table, pushing the values-of-interest into a two-dimensional array, mydata.
For this example, I'm accessing the public spreadsheet used in the Interactive Code Sample provided in the Query Language Reference, and also using their sample query. I've written the example so it can be easily modified to access your own spreadsheet with your own query. Here's the code:
// Specify the spreadsheet key and the query to be retrieved
var ssKey = 'pCQbetd-CptGXxxQIG7VFIQ';
var query = encodeURIComponent('SELECT A,D WHERE D > 100 ORDER BY D');
// Build url to peform query
var url = 'http://spreadsheets.google.com/tq?key=%KEY%&tq=%QUERY%'
.replace('%KEY%',ssKey)
.replace('%QUERY%',query);
// Use UrlFetchApp to get the results of the query as a string.
var response = UrlFetchApp.fetch(url);
var content = response.getContentText();
//Logger.log(content);
// Extract the JSON object from the response. Note that the response contains
// multiple lines of Javascript, and that it's the second line that has our
// data table in it.
var regex = /.*google.visualization.Query.setResponse\((.*)\)/g
var jsonContent = regex.exec(content)[1];
Logger.log(jsonContent);
var objectContent = Utilities.jsonParse(jsonContent);
var numCols = objectContent.table.cols.length;
var numRows = objectContent.table.rows.length;
// Decode objectContent into a two-dimensional array.
var mydata = []
// Start with the header row.
mydata[0] = [];
for (var col = 0; col < numCols; col++ ) {
mydata[0].push(objectContent.table.cols[col].label);
}
// Then data rows
for (var row = 0; row < numRows; row++) {
mydata[row+1] = [];
for (var col = 0; col < numCols; col++ ) {
mydata[row+1].push(objectContent.table.rows[row].c[col].v);
}
}
// Done - mydata is now a two-dimensional array with the results of the query
debugger; // If debugging, pause to examine results
Depending on what you're planning to use the data for in your dashboard, you may just want to use the table object after the call to jsonParse().
I do not think the json parser var objectContent = Utilities.jsonParse(jsonContent) would work with those visualization query response having date as one of the cell value such as the below example
{
"v": newDate(2013,
11,
31),
"f": "31-Dec-2013",
"p": {
"style": "color: rgb(0, 0, 0);font-family:Dialog;"
}
}