From 23b9a9174006e341a507539b7da897816f4d739e Mon Sep 17 00:00:00 2001 From: jos Date: Thu, 21 May 2015 16:05:52 +0200 Subject: [PATCH] Implemented attribute mapping for DOT language attributes --- .../dotLanguage/data/cellular_automata.gv.txt | 2 +- .../dotLanguage/data/computer_network.gv.txt | 4 +- .../data/dotLanguage/dotPlayground.html | 12 ++- lib/network/dotparser.js | 76 ++++++++++++++++++- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/examples/network/categories/data/dotLanguage/data/cellular_automata.gv.txt b/examples/network/categories/data/dotLanguage/data/cellular_automata.gv.txt index 495d7db7..5e48093f 100644 --- a/examples/network/categories/data/dotLanguage/data/cellular_automata.gv.txt +++ b/examples/network/categories/data/dotLanguage/data/cellular_automata.gv.txt @@ -3,7 +3,7 @@ digraph G { // unrecognized attributes are ignored node[width=.25,height=.375,fontsize=15] - node [shape=filled fillcolor=#F1AAF0] + node [shape=filled color=#FF00FF fillcolor=#F1AAF0] 0-> 0 ; 1-> 1 ; 2-> 2 ; diff --git a/examples/network/categories/data/dotLanguage/data/computer_network.gv.txt b/examples/network/categories/data/dotLanguage/data/computer_network.gv.txt index 03f631a2..cd49095c 100644 --- a/examples/network/categories/data/dotLanguage/data/computer_network.gv.txt +++ b/examples/network/categories/data/dotLanguage/data/computer_network.gv.txt @@ -1,7 +1,7 @@ digraph topology { - node[shape=circle fontSize=12] - edge[length=170 fontSize=12] + node[shape=circle fontsize=12] + edge[length=170 fontsize=12] "10.0.255.1" -> "10.0.255.3"[label="1.000"]; "10.0.255.1" -> "10.0.255.2"[label="1.000"]; "10.0.255.1" -> "10.0.255.2"[label="1.000"]; diff --git a/examples/network/categories/data/dotLanguage/dotPlayground.html b/examples/network/categories/data/dotLanguage/dotPlayground.html index a4c002dc..f9b08652 100644 --- a/examples/network/categories/data/dotLanguage/dotPlayground.html +++ b/examples/network/categories/data/dotLanguage/dotPlayground.html @@ -10,6 +10,7 @@ @@ -101,11 +111,9 @@ The examples marked with a star (*) come straight from the GraphViz gallery.

-
-
diff --git a/lib/network/dotparser.js b/lib/network/dotparser.js index 647ff63b..2e4c461a 100644 --- a/lib/network/dotparser.js +++ b/lib/network/dotparser.js @@ -16,6 +16,18 @@ function parseDOT (data) { return parseGraph(); } +// mapping of attributes from DOT (the keys) to vis.js (the values) +var ATTR_MAPPING = { + 'fontsize': 'font.size', + 'fontcolor': 'font.color', + 'labelfontcolor': 'font.color', + 'fontname': 'font.face', + 'color': ['color.border', 'color.background'], + 'fillcolor': 'color.background', + 'tooltip': 'title', + 'labeltooltip': 'title' +}; + // token types enumeration var TOKENTYPE = { NULL : 0, @@ -726,6 +738,63 @@ function forEach2(array1, array2, fn) { } } +/** + * Set a nested property on an object + * When nested objects are missing, they will be created. + * For example setProp({}, 'font.color', 'red') will return {font: {color: 'red'}} + * @param {Object} object + * @param {string} path A dot separated string like 'font.color' + * @param {*} value Value for the property + * @return {Object} Returns the original object, allows for chaining. + */ +function setProp(object, path, value) { + var names = path.split('.'); + var prop = names.pop(); + + // traverse over the nested objects + var obj = object; + for (var i = 0; i < names.length; i++) { + var name = names[i]; + if (!(name in obj)) { + obj[name] = {}; + } + obj = obj[name]; + } + + // set the property value + obj[prop] = value; + + return object; +} + +/** + * Convert an object with DOT attributes to their vis.js equivalents. + * @param {Object} attr Object with DOT attributes + * @return {Object} Returns an object with vis.js attributes + */ +function convertAttr (attr) { + var converted = {}; + + for (var prop in attr) { + if (attr.hasOwnProperty(prop)) { + var mapping = ATTR_MAPPING[prop]; + if (Array.isArray(mapping)) { + mapping.forEach(function (mapping_i) { + setProp(converted, mapping_i, attr[prop]); + }) + } + else if (typeof mapping === 'string') { + setProp(converted, mapping, attr[prop]); + } + else { + setProp(converted, prop, attr[prop]); + } + } + } + + return converted; +} + /** * Convert a string containing a graph in DOT language into a map containing * with nodes and edges in the format of graph. @@ -748,7 +817,7 @@ function DOTToGraph (data) { id: dotNode.id, label: String(dotNode.label || dotNode.id) }; - merge(graphNode, dotNode.attr); + merge(graphNode, convertAttr(dotNode.attr)); if (graphNode.image) { graphNode.shape = 'image'; } @@ -768,7 +837,7 @@ function DOTToGraph (data) { from: dotEdge.from, to: dotEdge.to }; - merge(graphEdge, dotEdge.attr); + merge(graphEdge, convertAttr(dotEdge.attr)); graphEdge.arrows = (dotEdge.type === '->') ? 'to' : undefined; return graphEdge; @@ -785,6 +854,9 @@ function DOTToGraph (data) { } } + // TODO: support of solid/dotted/dashed edges (attr = 'style') + // TODO: support for attributes 'dir' and 'arrowhead' (edge arrows) + if (dotEdge.to instanceof Object) { to = dotEdge.to.nodes; }