|
|
@ -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; |
|
|
|
} |
|
|
|