Gabis Gabis - 6 months ago 38
JSON Question

Automatic visualization of json

I am looking for an automated way to generate a visualization of a specific type of json I am constructing.
The json I am constructing is an array of elements, each can contain either simple fields (say strings and numbers) or a reference to another such object in the array.

This is an example of desired output for a two element json array (created with libre office):

an example of desired visualization

I am familiar with the graphviz language, and tried toying a little to get to the result iv'e shown, and it seems that producing a dot file won't be trivial.

Do you have any tips on how to produce such visualizations?
Doesn't have to be in graphviz, whatever works.

Thank you very much!

m01 m01
Answer

I wrote a simple script to generate this graph with node.js:

'use strict';

var _ = require('lodash');
var dataMock = require('./somewhere/myDataMock.json');

var nodeCounter = 1;

function formatEllipsizedText(text, maxLength) {
    if (text.length > maxLength - 1) {
        return text.substring(0, maxLength - 1) + '…';
    } else {
        return text;
    }
}

function json2gvLabel(obj) {
    return _.map(_.keys(obj), function (key) { return '<' + key + '> ' + key; }).join('|');
}

var edges = [];
var nodes = [];

function recurse(parentNode, obj) {
    var myId = nodeCounter++;
    edges.push({from: parentNode, to: myId});
    if (_.isArray(obj)) {
        nodes.push({id: myId, label: 'array'});
        recurse(myId, obj[0]);
    } else if (!_.isObject(obj)) {
        nodes.push({id: myId, label: formatEllipsizedText('' + obj, 50)});
    } else {
        nodes.push({id: myId, label: json2gvLabel(obj)});
        _.each(obj, function (v, k) {
            recurse(myId + ':' + k, v);
        });
    }
}

recurse('root', dataMock);

console.log('digraph g {');
console.log('graph [rankdir = "LR", nodesep=0.1, ranksep=0.3];');
console.log('node [fontsize = "16", shape = "record", height=0.1, color=lightblue2];');
console.log('edge [];');

_.map(nodes, function (n) {
    console.log(n.id + '[label="' + n.label + '"];');
});
_.map(edges, function (e) {
    console.log(e.from + '->' + e.to + ';');
});

console.log('}');

Note that in my script, I collapse arrays to just one item to visualize the structure rather then show all the data.

Then, to generate the PDF, I pipe output of this script (gv format) to graphviz's dot:

node makeGraph.js | dot -Tpdf > ~/Desktop/a.pdf

The end result looks like this:

enter image description here