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!

Était-ce utile?

La 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

Autres conseils

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")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top