Question

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!

Was it helpful?

Solution

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

OTHER TIPS

Using graphviz, you'll most certainly have to use HTML-like labels.

Tips:

  • Ensure alignment and borders by nesting tables
  • Create edges originating from within a node using the port attribute (PORT="portname")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top