graphology-gexf
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -0,1 +1,2 @@ | ||
/* eslint no-self-compare: 0 */ | ||
/** | ||
@@ -10,3 +11,2 @@ * Graphology Common GEXF Writer | ||
// TODO: options => prettyPrint, nodeModel, edgeModel | ||
// TODO: handle object in color, position with object for viz | ||
@@ -20,18 +20,2 @@ | ||
var DEFAULTS = { | ||
encoding: 'UTF-8', | ||
pretty: true | ||
}; | ||
// var VALID_GEXF_TYPES = new Set([ | ||
// 'integer', | ||
// 'long', | ||
// 'double', | ||
// 'float', | ||
// 'boolean', | ||
// 'liststring', | ||
// 'string', | ||
// 'anyURI' | ||
// ]); | ||
var VIZ_RESERVED_NAMES = new Set([ | ||
@@ -96,7 +80,8 @@ 'color', | ||
* | ||
* @param {string} type - The element's type | ||
* @param {string} type - The element's type. | ||
* @param {string} key - The element's key. | ||
* @param {object} attributes - The element's attributes. | ||
* @return {object} | ||
*/ | ||
function DEFAULT_ELEMENT_REDUCER(type, attributes) { | ||
function DEFAULT_ELEMENT_FORMATTER(type, key, attributes) { | ||
var output = {}, | ||
@@ -125,4 +110,4 @@ name; | ||
var DEFAULT_NODE_REDUCER = DEFAULT_ELEMENT_REDUCER.bind(null, 'node'), | ||
DEFAULT_EDGE_REDUCER = DEFAULT_ELEMENT_REDUCER.bind(null, 'edge'); | ||
var DEFAULT_NODE_FORMATTER = DEFAULT_ELEMENT_FORMATTER.bind(null, 'node'), | ||
DEFAULT_EDGE_FORMATTER = DEFAULT_ELEMENT_FORMATTER.bind(null, 'edge'); | ||
@@ -140,2 +125,17 @@ /** | ||
/** | ||
* Function used to check whether the given value is "empty". | ||
* | ||
* @param {any} value - Target value. | ||
* @return {boolean} | ||
*/ | ||
function isEmptyValue(value) { | ||
return ( | ||
typeof value === 'undefined' || | ||
value === null || | ||
value === '' || | ||
value !== value | ||
); | ||
} | ||
/** | ||
* Function used to detect a JavaScript's value type in the GEXF model. | ||
@@ -147,6 +147,12 @@ * | ||
function detectValueType(value) { | ||
if (isEmptyValue(value)) | ||
return 'empty'; | ||
if (Array.isArray(value)) | ||
return 'liststring'; | ||
if (typeof value === 'boolean') | ||
return 'boolean'; | ||
if (typeof value === 'object') | ||
@@ -189,12 +195,14 @@ return 'string'; | ||
* @param {Graph} graph - Target graph. | ||
* @param {function} reducer - Function reducing the nodes attributes. | ||
* @param {function} format - Function formatting the nodes attributes. | ||
* @return {array} | ||
*/ | ||
function collectNodeData(graph, reducer) { | ||
function collectNodeData(graph, format) { | ||
var nodes = graph.nodes(), | ||
node, | ||
data; | ||
for (var i = 0, l = nodes.length; i < l; i++) { | ||
data = reducer(graph.getNodeAttributes(nodes[i])); | ||
data.key = nodes[i]; | ||
node = nodes[i]; | ||
data = format(node, graph.getNodeAttributes(node)); | ||
data.key = node; | ||
nodes[i] = data; | ||
@@ -215,10 +223,12 @@ } | ||
var edges = graph.edges(), | ||
edge, | ||
data; | ||
for (var i = 0, l = edges.length; i < l; i++) { | ||
data = reducer(graph.getEdgeAttributes(edges[i])); | ||
data.key = edges[i]; | ||
data.source = graph.source(edges[i]); | ||
data.target = graph.target(edges[i]); | ||
data.undirected = graph.undirected(edges[i]); | ||
edge = edges[i]; | ||
data = reducer(edge, graph.getEdgeAttributes(edge)); | ||
data.key = edge; | ||
data.source = graph.source(edge); | ||
data.target = graph.target(edge); | ||
data.undirected = graph.undirected(edge); | ||
edges[i] = data; | ||
@@ -236,2 +246,4 @@ } | ||
*/ | ||
// TODO: on large graph, we could also sample or let the user indicate the types | ||
function inferModel(elements) { | ||
@@ -253,2 +265,5 @@ var model = {}, | ||
if (type === 'empty') | ||
continue; | ||
if (!model[k]) | ||
@@ -301,4 +316,6 @@ model[k] = type; | ||
color, | ||
value, | ||
edgeType, | ||
attributes, | ||
weight, | ||
viz, | ||
@@ -328,3 +345,5 @@ k, | ||
if ('weight' in element) | ||
weight = element.weight; | ||
if ((typeof weight === 'number' && !isNaN(weight)) || typeof weight === 'string') | ||
writer.writeAttribute('weight', element.weight); | ||
@@ -341,5 +360,10 @@ } | ||
if (name in attributes) { | ||
value = attributes[name]; | ||
if (isEmptyValue(value)) | ||
continue; | ||
writer.startElement('attvalue'); | ||
writer.writeAttribute('for', name); | ||
writer.writeAttribute('value', cast(model[name], attributes[name])); | ||
writer.writeAttribute('value', cast(model[name], value)); | ||
writer.endElement(); | ||
@@ -411,2 +435,12 @@ } | ||
/** | ||
* Defaults. | ||
*/ | ||
var DEFAULTS = { | ||
encoding: 'UTF-8', | ||
pretty: true, | ||
formatNode: DEFAULT_NODE_FORMATTER, | ||
formatEdge: DEFAULT_EDGE_FORMATTER | ||
}; | ||
/** | ||
* Function taking a graphology instance & outputting a gexf string. | ||
@@ -417,3 +451,5 @@ * | ||
* @param {string} [encoding] - Character encoding. | ||
* @paral {boolean} [pretty] - Whether to pretty print output. | ||
* @param {boolean} [pretty] - Whether to pretty print output. | ||
* @param {function} [formatNode] - Function formatting nodes' output. | ||
* @param {function} [formatEdge] - Function formatting edges' output. | ||
* @return {string} - GEXF string. | ||
@@ -429,2 +465,5 @@ */ | ||
var formatNode = options.formatNode || DEFAULTS.formatNode, | ||
formatEdge = options.formatEdge || DEFAULTS.formatEdge; | ||
var writer = new XMLWriter(indent); | ||
@@ -464,4 +503,4 @@ | ||
// Processing model | ||
var nodes = collectNodeData(graph, DEFAULT_NODE_REDUCER), | ||
edges = collectEdgeData(graph, DEFAULT_EDGE_REDUCER); | ||
var nodes = collectNodeData(graph, formatNode), | ||
edges = collectEdgeData(graph, formatEdge); | ||
@@ -468,0 +507,0 @@ var nodeModel = inferModel(nodes); |
{ | ||
"name": "graphology-gexf", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "GEXF parser & writer for graphology.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -49,2 +49,38 @@ [![Build Status](https://travis-ci.org/graphology/graphology-gexf.svg)](https://travis-ci.org/graphology/graphology-gexf) | ||
var gexfString = gexf.write(graph); | ||
// Using custom formatting for nodes & edges | ||
var gexfString = gexf.write(graph, { | ||
formatNode: function(key, attributes) { | ||
return { | ||
label: attributes.label, | ||
attributes: { | ||
age: attributes.age, | ||
name: attributes.name | ||
}, | ||
viz: { | ||
color: '#FF0', | ||
x: attributes.x, | ||
y: attributes.y, | ||
shape: 'circle', | ||
size: 20 | ||
} | ||
}; | ||
}, | ||
formatEdge: function(key, attributes) { | ||
return { | ||
label: attributes.label, | ||
attributes: { | ||
number: attributes.number | ||
}, | ||
weight: attributes.weight, | ||
viz: { | ||
color: '#FF0', | ||
x: attributes.x, | ||
y: attributes.y, | ||
shape: 'dotted', | ||
thickness: 20 | ||
} | ||
}; | ||
} | ||
}); | ||
``` | ||
@@ -55,1 +91,6 @@ | ||
* **graph** *Graph*: graphology instance to write. | ||
* **options** *?object*: Options: | ||
- **encoding** *?string* [`UTF-8`]: encoding declaration. | ||
- **formatNode** *?function*: function returning the node's data to write. | ||
- **formatEdge** *?function*: function returning the edge's data to write. | ||
- **pretty** *?boolean* [`true`]: pretty-print output? |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27849
765
95