Reputation: 193
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):
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!
Upvotes: 7
Views: 9426
Reputation: 12402
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:
Upvotes: 11
Reputation: 56576
Using graphviz, you'll most certainly have to use HTML-like labels.
Tips:
PORT="portname"
)Upvotes: 1