graphology-metrics
Advanced tools
Comparing version 1.14.3 to 1.15.0
@@ -7,11 +7,14 @@ import Graph from 'graphology-types'; | ||
attributes?: { | ||
centrality?: string, | ||
weight?: string | ||
}, | ||
normalized?: boolean, | ||
weighted?: boolean | ||
centrality?: string; | ||
weight?: string; | ||
}; | ||
normalized?: boolean; | ||
weighted?: boolean; | ||
}; | ||
interface IBetweennessCentrality { | ||
(graph: Graph, options?: BetweennessCentralityOptions): BetweennessCentralityMapping; | ||
( | ||
graph: Graph, | ||
options?: BetweennessCentralityOptions | ||
): BetweennessCentralityMapping; | ||
assign(graph: Graph, options?: BetweennessCentralityOptions): void; | ||
@@ -18,0 +21,0 @@ } |
@@ -8,7 +8,7 @@ /** | ||
var isGraph = require('graphology-utils/is-graph'), | ||
lib = require('graphology-shortest-path/indexed-brandes'), | ||
defaults = require('lodash/defaults'); | ||
lib = require('graphology-shortest-path/indexed-brandes'), | ||
defaults = require('lodash/defaults'); | ||
var createUnweightedIndexedBrandes = lib.createUnweightedIndexedBrandes, | ||
createDijkstraIndexedBrandes = lib.createDijkstraIndexedBrandes; | ||
createDijkstraIndexedBrandes = lib.createDijkstraIndexedBrandes; | ||
@@ -42,3 +42,5 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-centrality/beetweenness-centrality: the given graph is not a valid graphology instance.' | ||
); | ||
@@ -48,26 +50,17 @@ // Solving options | ||
var weightAttribute = options.attributes.weight, | ||
centralityAttribute = options.attributes.centrality, | ||
normalized = options.normalized, | ||
weighted = options.weighted; | ||
var weightAttribute = options.attributes.weight; | ||
var centralityAttribute = options.attributes.centrality; | ||
var normalized = options.normalized; | ||
var weighted = options.weighted; | ||
var brandes = weighted ? | ||
createDijkstraIndexedBrandes(graph, weightAttribute) : | ||
createUnweightedIndexedBrandes(graph); | ||
var brandes = weighted | ||
? createDijkstraIndexedBrandes(graph, weightAttribute) | ||
: createUnweightedIndexedBrandes(graph); | ||
var N = graph.order; | ||
var result, | ||
S, | ||
P, | ||
sigma, | ||
coefficient, | ||
i, | ||
j, | ||
m, | ||
v, | ||
w; | ||
var result, S, P, sigma, coefficient, i, j, m, v, w; | ||
var delta = new Float64Array(N), | ||
centralities = new Float64Array(N); | ||
var delta = new Float64Array(N); | ||
var centralities = new Float64Array(N); | ||
@@ -85,4 +78,3 @@ // Iterating over each node | ||
while (j--) | ||
delta[S.items[S.size - j]] = 0; | ||
while (j--) delta[S.items[S.size - j]] = 0; | ||
@@ -98,4 +90,3 @@ while (S.size !== 0) { | ||
if (w !== i) | ||
centralities[w] += delta[w]; | ||
if (w !== i) centralities[w] += delta[w]; | ||
} | ||
@@ -107,14 +98,10 @@ } | ||
if (normalized) | ||
scale = N <= 2 ? null : (1 / ((N - 1) * (N - 2))); | ||
else | ||
scale = graph.type === 'undirected' ? 0.5 : null; | ||
if (normalized) scale = N <= 2 ? null : 1 / ((N - 1) * (N - 2)); | ||
else scale = graph.type === 'undirected' ? 0.5 : null; | ||
if (scale !== null) { | ||
for (i = 0; i < N; i++) | ||
centralities[i] *= scale; | ||
for (i = 0; i < N; i++) centralities[i] *= scale; | ||
} | ||
if (assign) | ||
return brandes.index.assign(centralityAttribute, centralities); | ||
if (assign) return brandes.index.assign(centralityAttribute, centralities); | ||
@@ -121,0 +108,0 @@ return brandes.index.collect(centralities); |
@@ -5,4 +5,4 @@ import Graph from 'graphology-types'; | ||
attributes?: { | ||
centrality?: string | ||
} | ||
centrality?: string; | ||
}; | ||
}; | ||
@@ -18,5 +18,5 @@ | ||
interface IDegreeCentrality extends IDegreeCentralityBase { | ||
degreeCentrality: IDegreeCentralityBase, | ||
inDegreeCentrality: IDegreeCentralityBase, | ||
outDegreeCentrality: IDegreeCentralityBase | ||
degreeCentrality: IDegreeCentralityBase; | ||
inDegreeCentrality: IDegreeCentralityBase; | ||
outDegreeCentrality: IDegreeCentralityBase; | ||
} | ||
@@ -23,0 +23,0 @@ |
@@ -27,6 +27,16 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-centrality/' + name + ': the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-centrality/' + | ||
name + | ||
': the given graph is not a valid graphology instance.' | ||
); | ||
if (method !== 'degree' && graph.type === 'undirected') | ||
throw new Error('graphology-centrality/' + name + ': cannot compute ' + method + ' centrality on an undirected graph.'); | ||
throw new Error( | ||
'graphology-centrality/' + | ||
name + | ||
': cannot compute ' + | ||
method + | ||
' centrality on an undirected graph.' | ||
); | ||
@@ -42,8 +52,7 @@ // Solving options | ||
var order = graph.order, | ||
nodes = graph.nodes(), | ||
getDegree = graph[method].bind(graph), | ||
centralities = {}; | ||
nodes = graph.nodes(), | ||
getDegree = graph[method].bind(graph), | ||
centralities = {}; | ||
if (order === 0) | ||
return assign ? undefined : centralities; | ||
if (order === 0) return assign ? undefined : centralities; | ||
@@ -53,5 +62,3 @@ var s = 1 / (order - 1); | ||
// Iteration variables | ||
var node, | ||
centrality, | ||
i; | ||
var node, centrality, i; | ||
@@ -62,6 +69,4 @@ for (i = 0; i < order; i++) { | ||
if (assign) | ||
graph.setNodeAttribute(node, centralityAttribute, centrality); | ||
else | ||
centralities[node] = centrality; | ||
if (assign) graph.setNodeAttribute(node, centralityAttribute, centrality); | ||
else centralities[node] = centrality; | ||
} | ||
@@ -76,8 +81,16 @@ | ||
var degreeCentrality = abstractDegreeCentrality.bind(null, false, 'degree'), | ||
inDegreeCentrality = abstractDegreeCentrality.bind(null, false, 'inDegree'), | ||
outDegreeCentrality = abstractDegreeCentrality.bind(null, false, 'outDegree'); | ||
inDegreeCentrality = abstractDegreeCentrality.bind(null, false, 'inDegree'), | ||
outDegreeCentrality = abstractDegreeCentrality.bind(null, false, 'outDegree'); | ||
degreeCentrality.assign = abstractDegreeCentrality.bind(null, true, 'degree'); | ||
inDegreeCentrality.assign = abstractDegreeCentrality.bind(null, true, 'inDegree'); | ||
outDegreeCentrality.assign = abstractDegreeCentrality.bind(null, true, 'outDegree'); | ||
inDegreeCentrality.assign = abstractDegreeCentrality.bind( | ||
null, | ||
true, | ||
'inDegree' | ||
); | ||
outDegreeCentrality.assign = abstractDegreeCentrality.bind( | ||
null, | ||
true, | ||
'outDegree' | ||
); | ||
@@ -84,0 +97,0 @@ /** |
@@ -18,5 +18,15 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/' + callee + ': given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/' + | ||
callee + | ||
': given graph is not a valid graphology instance.' | ||
); | ||
if (graph.type === type) { | ||
throw new Error('graphology-metrics/' + callee + ': can not be calculated for ' + type + ' graphs.'); | ||
throw new Error( | ||
'graphology-metrics/' + | ||
callee + | ||
': can not be calculated for ' + | ||
type + | ||
' graphs.' | ||
); | ||
} | ||
@@ -26,3 +36,7 @@ var nodes = graph.nodes(); | ||
if (assign) { | ||
var attributes = Object.assign({}, DEFAULT_ATTRIBUTES, options && options.attributes); | ||
var attributes = Object.assign( | ||
{}, | ||
DEFAULT_ATTRIBUTES, | ||
options && options.attributes | ||
); | ||
for (i = 0; i < nodes.length; i++) { | ||
@@ -46,4 +60,10 @@ graph.setNodeAttribute( | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/degree: given graph is not a valid graphology instance.'); | ||
var attributes = Object.assign({}, DEFAULT_ATTRIBUTES, options && options.attributes); | ||
throw new Error( | ||
'graphology-metrics/degree: given graph is not a valid graphology instance.' | ||
); | ||
var attributes = Object.assign( | ||
{}, | ||
DEFAULT_ATTRIBUTES, | ||
options && options.attributes | ||
); | ||
var nodes = graph.nodes(); | ||
@@ -63,7 +83,6 @@ var types; | ||
if (options && options.types && options.types.length) { | ||
types = defaultTypes.filter(function(type) { | ||
types = defaultTypes.filter(function (type) { | ||
return options.types.indexOf(type) > -1; | ||
}); | ||
} | ||
else { | ||
} else { | ||
types = defaultTypes; | ||
@@ -83,4 +102,3 @@ } | ||
} | ||
} | ||
else { | ||
} else { | ||
var hashmap = {}; | ||
@@ -87,0 +105,0 @@ for (i = 0; i < nodes.length; i++) { |
@@ -17,3 +17,3 @@ /** | ||
function undirectedDensity(order, size) { | ||
return 2 * size / (order * (order - 1)); | ||
return (2 * size) / (order * (order - 1)); | ||
} | ||
@@ -40,8 +40,5 @@ | ||
function mixedDensity(order, size) { | ||
var d = (order * (order - 1)); | ||
var d = order * (order - 1); | ||
return ( | ||
size / | ||
(d + d / 2) | ||
); | ||
return size / (d + d / 2); | ||
} | ||
@@ -57,5 +54,5 @@ | ||
var nodes = graph.nodes(), | ||
size = 0, | ||
i, | ||
l; | ||
size = 0, | ||
i, | ||
l; | ||
@@ -87,4 +84,3 @@ for (i = 0, l = nodes.length; i < l; i++) { | ||
function abstractDensity(type, multi, graph) { | ||
var order, | ||
size; | ||
var order, size; | ||
@@ -97,11 +93,15 @@ // Retrieving order & size | ||
if (typeof order !== 'number') | ||
throw new Error('graphology-metrics/density: given order is not a number.'); | ||
throw new Error( | ||
'graphology-metrics/density: given order is not a number.' | ||
); | ||
if (typeof size !== 'number') | ||
throw new Error('graphology-metrics/density: given size is not a number.'); | ||
} | ||
else { | ||
throw new Error( | ||
'graphology-metrics/density: given size is not a number.' | ||
); | ||
} else { | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/density: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/density: given graph is not a valid graphology instance.' | ||
); | ||
@@ -111,15 +111,11 @@ order = graph.order; | ||
if (graph.multi && multi === false) | ||
size = simpleSizeForMultiGraphs(graph); | ||
if (graph.multi && multi === false) size = simpleSizeForMultiGraphs(graph); | ||
} | ||
// When the graph has only one node, its density is 0 | ||
if (order < 2) | ||
return 0; | ||
if (order < 2) return 0; | ||
// Guessing type & multi | ||
if (type === null) | ||
type = graph.type; | ||
if (multi === null) | ||
multi = graph.multi; | ||
if (type === null) type = graph.type; | ||
if (multi === null) multi = graph.multi; | ||
@@ -129,8 +125,5 @@ // Getting the correct function | ||
if (type === 'undirected') | ||
fn = undirectedDensity; | ||
else if (type === 'directed') | ||
fn = directedDensity; | ||
else | ||
fn = mixedDensity; | ||
if (type === 'undirected') fn = undirectedDensity; | ||
else if (type === 'directed') fn = directedDensity; | ||
else fn = mixedDensity; | ||
@@ -137,0 +130,0 @@ // Applying the function |
@@ -12,19 +12,19 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/diameter: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/diameter: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.size === 0) | ||
return Infinity; | ||
if (graph.size === 0) return Infinity; | ||
var diameter = -Infinity, ecc = 0; | ||
var nodes = graph.nodes() | ||
var D = -Infinity, | ||
ecc = 0; | ||
var nodes = graph.nodes(); | ||
for (var i = 0, l = nodes.length; i < l ; i++) { | ||
for (var i = 0, l = nodes.length; i < l; i++) { | ||
ecc = eccentricity(graph, nodes[i]); | ||
if (ecc > diameter) | ||
diameter = ecc; | ||
if (diameter === Infinity) | ||
break; | ||
if (ecc > D) D = ecc; | ||
if (D === Infinity) break; | ||
} | ||
return diameter; | ||
return D; | ||
}; |
@@ -8,10 +8,12 @@ /** | ||
var isGraph = require('graphology-utils/is-graph'); | ||
var singleSourceLength = require('graphology-shortest-path/unweighted').singleSourceLength; | ||
var singleSourceLength = | ||
require('graphology-shortest-path/unweighted').singleSourceLength; | ||
module.exports = function eccentricity(graph, node) { | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/eccentricity: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/eccentricity: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.size === 0) | ||
return Infinity; | ||
if (graph.size === 0) return Infinity; | ||
@@ -24,3 +26,4 @@ var ecc = -Infinity; | ||
var pathLength, l = 0; | ||
var pathLength, | ||
l = 0; | ||
@@ -30,4 +33,3 @@ for (otherNode in lengths) { | ||
if (pathLength > ecc) | ||
ecc = pathLength; | ||
if (pathLength > ecc) ecc = pathLength; | ||
@@ -37,6 +39,5 @@ l++; | ||
if (l < graph.order) | ||
return Infinity; | ||
if (l < graph.order) return Infinity; | ||
return ecc; | ||
}; |
@@ -18,9 +18,9 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/extent: the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/extent: the given graph is not a valid graphology instance.' | ||
); | ||
var attributes = [].concat(attribute); | ||
var value, | ||
key, | ||
a; | ||
var value, key, a; | ||
@@ -35,3 +35,3 @@ var results = {}; | ||
graph.forEachNode(function(node, data) { | ||
graph.forEachNode(function (node, data) { | ||
for (a = 0; a < attributes.length; a++) { | ||
@@ -41,7 +41,5 @@ key = attributes[a]; | ||
if (value < results[key][0]) | ||
results[key][0] = value; | ||
if (value < results[key][0]) results[key][0] = value; | ||
if (value > results[key][1]) | ||
results[key][1] = value; | ||
if (value > results[key][1]) results[key][1] = value; | ||
} | ||
@@ -62,9 +60,9 @@ }); | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/extent: the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/extent: the given graph is not a valid graphology instance.' | ||
); | ||
var attributes = [].concat(attribute); | ||
var value, | ||
key, | ||
a; | ||
var value, key, a; | ||
@@ -79,3 +77,3 @@ var results = {}; | ||
graph.forEachEdge(function(edge, data) { | ||
graph.forEachEdge(function (edge, data) { | ||
for (a = 0; a < attributes.length; a++) { | ||
@@ -85,7 +83,5 @@ key = attributes[a]; | ||
if (value < results[key][0]) | ||
results[key][0] = value; | ||
if (value < results[key][0]) results[key][0] = value; | ||
if (value > results[key][1]) | ||
results[key][1] = value; | ||
if (value > results[key][1]) results[key][1] = value; | ||
} | ||
@@ -92,0 +88,0 @@ }); |
@@ -16,6 +16,3 @@ /** | ||
function euclideanDistance(a, b) { | ||
return Math.sqrt( | ||
Math.pow(a.x - b.x, 2) + | ||
Math.pow(a.y - b.y, 2) | ||
); | ||
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); | ||
} | ||
@@ -25,14 +22,22 @@ | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/layout-quality/edge-uniformity: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/layout-quality/edge-uniformity: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.size === 0) | ||
return 0; | ||
if (graph.size === 0) return 0; | ||
var sum = 0, | ||
i = 0, | ||
l; | ||
i = 0, | ||
l; | ||
var lengths = new Float64Array(graph.size); | ||
graph.forEachEdge(function(edge, attr, source, target, sourceAttr, targetAttr) { | ||
graph.forEachEdge(function ( | ||
edge, | ||
attr, | ||
source, | ||
target, | ||
sourceAttr, | ||
targetAttr | ||
) { | ||
var edgeLength = euclideanDistance(sourceAttr, targetAttr); | ||
@@ -39,0 +44,0 @@ |
@@ -15,19 +15,22 @@ /** | ||
var isGraph = require('graphology-utils/is-graph'), | ||
KDTree = require('mnemonist/kd-tree'), | ||
intersectionSize = require('mnemonist/set').intersectionSize; | ||
KDTree = require('mnemonist/kd-tree'), | ||
intersectionSize = require('mnemonist/set').intersectionSize; | ||
module.exports = function neighborhoodPreservation(graph) { | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/layout-quality/neighborhood-preservation: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/layout-quality/neighborhood-preservation: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.order === 0) | ||
throw new Error('graphology-metrics/layout-quality/neighborhood-preservation: cannot compute stress for a null graph.'); | ||
throw new Error( | ||
'graphology-metrics/layout-quality/neighborhood-preservation: cannot compute stress for a null graph.' | ||
); | ||
if (graph.size === 0) | ||
return 0; | ||
if (graph.size === 0) return 0; | ||
var axes = [new Float64Array(graph.order), new Float64Array(graph.order)], | ||
i = 0; | ||
i = 0; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
axes[0][i] = attr.x; | ||
@@ -41,3 +44,3 @@ axes[1][i++] = attr.y; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
var neighbors = new Set(graph.neighbors(node)); | ||
@@ -44,0 +47,0 @@ |
@@ -15,9 +15,7 @@ /** | ||
var isGraph = require('graphology-utils/is-graph'), | ||
undirectedSingleSourceLength = require('graphology-shortest-path/unweighted').undirectedSingleSourceLength; | ||
undirectedSingleSourceLength = | ||
require('graphology-shortest-path/unweighted').undirectedSingleSourceLength; | ||
function euclideanDistance(a, b) { | ||
return Math.sqrt( | ||
Math.pow(a.x - b.x, 2) + | ||
Math.pow(a.y - b.y, 2) | ||
); | ||
return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); | ||
} | ||
@@ -27,10 +25,14 @@ | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/layout-quality/stress: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/layout-quality/stress: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.order === 0) | ||
throw new Error('graphology-metrics/layout-quality/stress: cannot compute stress for a null graph.'); | ||
throw new Error( | ||
'graphology-metrics/layout-quality/stress: cannot compute stress for a null graph.' | ||
); | ||
var nodes = new Array(graph.order), | ||
entries = new Array(graph.order), | ||
i = 0; | ||
entries = new Array(graph.order), | ||
i = 0; | ||
@@ -43,3 +45,3 @@ // We choose an arbitrary large distance for when two nodes cannot be | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
nodes[i] = node; | ||
@@ -65,4 +67,3 @@ entries[i++] = attr; | ||
// Target is in another castle | ||
if (typeof dij === 'undefined') | ||
dij = maxDistance; | ||
if (typeof dij === 'undefined') dij = maxDistance; | ||
@@ -69,0 +70,0 @@ cicj = euclideanDistance(p1, p2); |
@@ -11,13 +11,9 @@ /** | ||
function isEmpty(obj) { | ||
// null and undefined are "empty" | ||
if (!obj) | ||
return true; | ||
if (!obj) return true; | ||
// Assume if it has a length property with a non-zero value | ||
// that that property is correct. | ||
if (obj.length > 0) | ||
return false; | ||
if (obj.length === 0) | ||
return true; | ||
if (obj.length > 0) return false; | ||
if (obj.length === 0) return true; | ||
@@ -27,4 +23,3 @@ // If it isn't an object at this point | ||
// Is it empty? Depends on your application. | ||
if (typeof obj !== 'object') | ||
return true; | ||
if (typeof obj !== 'object') return true; | ||
@@ -48,3 +43,3 @@ // Otherwise, does it have any properties of its own? | ||
inboundEdges: 0, | ||
outboundEdges: 0, | ||
outboundEdges: 0 | ||
}; | ||
@@ -55,3 +50,5 @@ } | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/modality: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/modality: given graph is not a valid graphology instance.' | ||
); | ||
if (!attributes || (attributes && attributes.length === 0)) { | ||
@@ -61,4 +58,7 @@ throw new Error('graphology-metrics/modality: no attributes where given.'); | ||
if (!Array.isArray(attributes)) { | ||
if (typeof(attributes) !== 'string') { | ||
throw new Error('graphology-metrics/modality: Attributes must be a string or an array of strings. typeof attributes = ' + typeof(attributes)); | ||
if (typeof attributes !== 'string') { | ||
throw new Error( | ||
'graphology-metrics/modality: Attributes must be a string or an array of strings. typeof attributes = ' + | ||
typeof attributes | ||
); | ||
} | ||
@@ -76,3 +76,10 @@ attributes = [attributes]; | ||
function modalitiesCreator(type) { | ||
return function(key, edgeAttributes, source, target, sourceAttributes, targetAttributes) { | ||
return function ( | ||
key, | ||
edgeAttributes, | ||
source, | ||
target, | ||
sourceAttributes, | ||
targetAttributes | ||
) { | ||
for (i = 0; i < attributes.length; i++) { | ||
@@ -85,3 +92,6 @@ var attribute = attributes[i]; | ||
// If attribute is not in source or target attributes we can exit the iteration. | ||
if (!(attribute in sourceAttributes) || !(attribute in targetAttributes)) { | ||
if ( | ||
!(attribute in sourceAttributes) || | ||
!(attribute in targetAttributes) | ||
) { | ||
return; | ||
@@ -100,4 +110,3 @@ } | ||
mapForSourceValue.internalEdges++; | ||
} | ||
else { | ||
} else { | ||
if (type === 'directed') { | ||
@@ -112,4 +121,3 @@ // Directed graphs only have in/out edges | ||
mapForTargetValue.externalEdges++; | ||
} | ||
else { | ||
} else { | ||
// externalEdges are all the edges going in OR out of a category. | ||
@@ -133,24 +141,14 @@ // So any link where source !== target. | ||
if (graph.type === 'directed') { | ||
graph.forEachEdge( | ||
modalitiesCreator(graph.type) | ||
); | ||
graph.forEachEdge(modalitiesCreator(graph.type)); | ||
densityFn = density.directedDensity; | ||
} | ||
else if (graph.type === 'undirected') { | ||
graph.forEachEdge( | ||
modalitiesCreator(graph.type) | ||
); | ||
} else if (graph.type === 'undirected') { | ||
graph.forEachEdge(modalitiesCreator(graph.type)); | ||
densityFn = density.undirectedDensity; | ||
} | ||
else { | ||
graph.forEachDirectedEdge( | ||
modalitiesCreator('directed') | ||
); | ||
graph.forEachUndirectedEdge( | ||
modalitiesCreator(graph.type) | ||
); | ||
} else { | ||
graph.forEachDirectedEdge(modalitiesCreator('directed')); | ||
graph.forEachUndirectedEdge(modalitiesCreator(graph.type)); | ||
densityFn = density.mixedDensity; | ||
} | ||
graph.forEachNode(function(node, nodeAttributes) { | ||
graph.forEachNode(function (node, nodeAttributes) { | ||
for (i = 0; i < attributes.length; i++) { | ||
@@ -164,3 +162,7 @@ hashmap[attributes[i]][nodeAttributes[attributes[i]]].nodes++; | ||
if (isEmpty(hashmap[attribute])) { | ||
throw new Error('graphology-metrics/modality: Attribute ' + attribute + ' provided not found in any node attributes.'); | ||
throw new Error( | ||
'graphology-metrics/modality: Attribute ' + | ||
attribute + | ||
' provided not found in any node attributes.' | ||
); | ||
} | ||
@@ -167,0 +169,0 @@ var valuesForAttribute = hashmap[attribute]; |
@@ -7,7 +7,7 @@ import Graph from 'graphology-types'; | ||
attributes?: { | ||
community?: string, | ||
weight?: string | ||
}, | ||
communities?: CommunityMapping, | ||
weighted?: boolean | ||
community?: string; | ||
weight?: string; | ||
}; | ||
communities?: CommunityMapping; | ||
weighted?: boolean; | ||
}; | ||
@@ -14,0 +14,0 @@ |
@@ -145,4 +145,4 @@ /** | ||
var defaults = require('lodash/defaultsDeep'), | ||
isGraph = require('graphology-utils/is-graph'), | ||
inferType = require('graphology-utils/infer-type'); | ||
isGraph = require('graphology-utils/is-graph'), | ||
inferType = require('graphology-utils/infer-type'); | ||
@@ -159,14 +159,11 @@ var DEFAULTS = { | ||
function createWeightGetter(weighted, weightAttribute) { | ||
return function(attr) { | ||
if (!attr) | ||
return 0; | ||
function createWeightGetter(weighted, weightAttribute) { | ||
return function (attr) { | ||
if (!attr) return 0; | ||
if (!weighted) | ||
return 1; | ||
if (!weighted) return 1; | ||
var w = attr[weightAttribute]; | ||
if (typeof w !== 'number') | ||
w = 1; | ||
if (typeof w !== 'number') w = 1; | ||
@@ -179,20 +176,23 @@ return w; | ||
var communities = new Array(graph.order), | ||
weightedDegrees = new Float64Array(graph.order), | ||
M = 0; | ||
weightedDegrees = new Float64Array(graph.order), | ||
M = 0; | ||
var ids = {}; | ||
var getWeight = createWeightGetter(options.weighted, options.attributes.weight); | ||
var getWeight = createWeightGetter( | ||
options.weighted, | ||
options.attributes.weight | ||
); | ||
// Collecting communities | ||
var i = 0; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
ids[node] = i; | ||
communities[i++] = options.communities ? | ||
options.communities[node] : | ||
attr[options.attributes.community]; | ||
communities[i++] = options.communities | ||
? options.communities[node] | ||
: attr[options.attributes.community]; | ||
}); | ||
// Collecting weights | ||
graph.forEachUndirectedEdge(function(edge, attr, source, target) { | ||
graph.forEachUndirectedEdge(function (edge, attr, source, target) { | ||
var weight = getWeight(attr); | ||
@@ -205,4 +205,3 @@ | ||
// NOTE: we double degree only if we don't have a loop | ||
if (source !== target) | ||
weightedDegrees[ids[target]] += weight; | ||
if (source !== target) weightedDegrees[ids[target]] += weight; | ||
}); | ||
@@ -220,21 +219,24 @@ | ||
var communities = new Array(graph.order), | ||
weightedInDegrees = new Float64Array(graph.order), | ||
weightedOutDegrees = new Float64Array(graph.order), | ||
M = 0; | ||
weightedInDegrees = new Float64Array(graph.order), | ||
weightedOutDegrees = new Float64Array(graph.order), | ||
M = 0; | ||
var ids = {}; | ||
var getWeight = createWeightGetter(options.weighted, options.attributes.weight); | ||
var getWeight = createWeightGetter( | ||
options.weighted, | ||
options.attributes.weight | ||
); | ||
// Collecting communities | ||
var i = 0; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
ids[node] = i; | ||
communities[i++] = options.communities ? | ||
options.communities[node] : | ||
attr[options.attributes.community]; | ||
communities[i++] = options.communities | ||
? options.communities[node] | ||
: attr[options.attributes.community]; | ||
}); | ||
// Collecting weights | ||
graph.forEachDirectedEdge(function(edge, attr, source, target) { | ||
graph.forEachDirectedEdge(function (edge, attr, source, target) { | ||
var weight = getWeight(attr); | ||
@@ -262,4 +264,4 @@ | ||
var communities = result.communities, | ||
weightedDegrees = result.weightedDegrees; | ||
var communities = result.communities; | ||
var weightedDegrees = result.weightedDegrees; | ||
@@ -270,3 +272,3 @@ var M = result.M; | ||
var i, j, l, Aij, didj; | ||
var i, j, l, Aij, didj, edgeAttributes; | ||
@@ -278,3 +280,2 @@ var S = 0; | ||
for (i = 0, l = graph.order; i < l; i++) { | ||
// NOTE: it is important to parse the whole matrix here, diagonal and | ||
@@ -284,7 +285,5 @@ // lower part included. A lot of implementation differ here because | ||
for (j = 0; j < l; j++) { | ||
// NOTE: Kronecker's delta | ||
// NOTE: we could go from O(n^2) to O(avg.C^2) | ||
if (communities[i] !== communities[j]) | ||
continue; | ||
if (communities[i] !== communities[j]) continue; | ||
@@ -299,4 +298,3 @@ edgeAttributes = graph.undirectedEdge(nodes[i], nodes[j]); | ||
S += (Aij - (didj / M2) * resolution) * 2; | ||
else | ||
S += (Aij - (didj / M2) * resolution); | ||
else S += Aij - (didj / M2) * resolution; | ||
} | ||
@@ -313,5 +311,5 @@ } | ||
var communities = result.communities, | ||
weightedInDegrees = result.weightedInDegrees, | ||
weightedOutDegrees = result.weightedOutDegrees; | ||
var communities = result.communities; | ||
var weightedInDegrees = result.weightedInDegrees; | ||
var weightedOutDegrees = result.weightedOutDegrees; | ||
@@ -322,3 +320,3 @@ var M = result.M; | ||
var i, j, l, Aij, didj; | ||
var i, j, l, Aij, didj, edgeAttributes; | ||
@@ -328,3 +326,2 @@ var S = 0; | ||
for (i = 0, l = graph.order; i < l; i++) { | ||
// NOTE: it is important to parse the whole matrix here, diagonal and | ||
@@ -334,7 +331,5 @@ // lower part included. A lot of implementation differ here because | ||
for (j = 0; j < l; j++) { | ||
// NOTE: Kronecker's delta | ||
// NOTE: we could go from O(n^2) to O(avg.C^2) | ||
if (communities[i] !== communities[j]) | ||
continue; | ||
if (communities[i] !== communities[j]) continue; | ||
@@ -356,9 +351,8 @@ edgeAttributes = graph.directedEdge(nodes[i], nodes[j]); | ||
var communities = {}, | ||
totalWeights = {}, | ||
internalWeights = {}; | ||
totalWeights = {}, | ||
internalWeights = {}; | ||
if (options.communities) | ||
communities = options.communities; | ||
if (options.communities) communities = options.communities; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
var community; | ||
@@ -369,4 +363,3 @@ | ||
communities[node] = community; | ||
} | ||
else { | ||
} else { | ||
community = communities[node]; | ||
@@ -376,3 +369,7 @@ } | ||
if (typeof community === 'undefined') | ||
throw new Error('graphology-metrics/modularity: the "' + node + '" node is not in the partition.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: the "' + | ||
node + | ||
'" node is not in the partition.' | ||
); | ||
@@ -392,10 +389,9 @@ totalWeights[community] = 0; | ||
var communities = {}, | ||
totalInWeights = {}, | ||
totalOutWeights = {}, | ||
internalWeights = {}; | ||
totalInWeights = {}, | ||
totalOutWeights = {}, | ||
internalWeights = {}; | ||
if (options.communities) | ||
communities = options.communities; | ||
if (options.communities) communities = options.communities; | ||
graph.forEachNode(function(node, attr) { | ||
graph.forEachNode(function (node, attr) { | ||
var community; | ||
@@ -406,4 +402,3 @@ | ||
communities[node] = community; | ||
} | ||
else { | ||
} else { | ||
community = communities[node]; | ||
@@ -413,3 +408,7 @@ } | ||
if (typeof community === 'undefined') | ||
throw new Error('graphology-metrics/modularity: the "' + node + '" node is not in the partition.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: the "' + | ||
node + | ||
'" node is not in the partition.' | ||
); | ||
@@ -437,8 +436,11 @@ totalInWeights[community] = 0; | ||
var totalWeights = result.totalWeights, | ||
internalWeights = result.internalWeights, | ||
communities = result.communities; | ||
internalWeights = result.internalWeights, | ||
communities = result.communities; | ||
var getWeight = createWeightGetter(options.weighted, options.attributes.weight); | ||
var getWeight = createWeightGetter( | ||
options.weighted, | ||
options.attributes.weight | ||
); | ||
graph.forEachUndirectedEdge(function(edge, edgeAttr, source, target, sourceAttr, targetAttr) { | ||
graph.forEachUndirectedEdge(function (edge, edgeAttr, source, target) { | ||
var weight = getWeight(edgeAttr); | ||
@@ -454,4 +456,3 @@ | ||
if (sourceCommunity !== targetCommunity) | ||
return; | ||
if (sourceCommunity !== targetCommunity) return; | ||
@@ -462,6 +463,7 @@ internalWeights[sourceCommunity] += weight * 2; | ||
var Q = 0, | ||
M2 = M * 2; | ||
M2 = M * 2; | ||
for (var C in internalWeights) | ||
Q += internalWeights[C] / M2 - Math.pow(totalWeights[C] / M2, 2) * resolution; | ||
Q += | ||
internalWeights[C] / M2 - Math.pow(totalWeights[C] / M2, 2) * resolution; | ||
@@ -479,9 +481,12 @@ return Q; | ||
var totalInWeights = result.totalInWeights, | ||
totalOutWeights = result.totalOutWeights, | ||
internalWeights = result.internalWeights, | ||
communities = result.communities; | ||
totalOutWeights = result.totalOutWeights, | ||
internalWeights = result.internalWeights, | ||
communities = result.communities; | ||
var getWeight = createWeightGetter(options.weighted, options.attributes.weight); | ||
var getWeight = createWeightGetter( | ||
options.weighted, | ||
options.attributes.weight | ||
); | ||
graph.forEachDirectedEdge(function(edge, edgeAttr, source, target, sourceAttr, targetAttr) { | ||
graph.forEachDirectedEdge(function (edge, edgeAttr, source, target) { | ||
var weight = getWeight(edgeAttr); | ||
@@ -497,4 +502,3 @@ | ||
if (sourceCommunity !== targetCommunity) | ||
return; | ||
if (sourceCommunity !== targetCommunity) return; | ||
@@ -507,3 +511,5 @@ internalWeights[sourceCommunity] += weight; | ||
for (var C in internalWeights) | ||
Q += (internalWeights[C] / M) - (totalInWeights[C] * totalOutWeights[C] / Math.pow(M, 2)) * resolution; | ||
Q += | ||
internalWeights[C] / M - | ||
((totalInWeights[C] * totalOutWeights[C]) / Math.pow(M, 2)) * resolution; | ||
@@ -515,18 +521,27 @@ return Q; | ||
// given as the edges count * 2 | ||
function undirectedModularityDelta(M, communityTotalWeight, nodeDegree, nodeCommunityDegree) { | ||
function undirectedModularityDelta( | ||
M, | ||
communityTotalWeight, | ||
nodeDegree, | ||
nodeCommunityDegree | ||
) { | ||
return ( | ||
(nodeCommunityDegree / (2 * M)) - | ||
( | ||
(communityTotalWeight * nodeDegree) / (2 * (M * M)) | ||
) | ||
nodeCommunityDegree / (2 * M) - | ||
(communityTotalWeight * nodeDegree) / (2 * (M * M)) | ||
); | ||
} | ||
function directedModularityDelta(M, communityTotalInWeight, communityTotalOutWeight, nodeInDegree, nodeOutDegree, nodeCommunityDegree) { | ||
function directedModularityDelta( | ||
M, | ||
communityTotalInWeight, | ||
communityTotalOutWeight, | ||
nodeInDegree, | ||
nodeOutDegree, | ||
nodeCommunityDegree | ||
) { | ||
return ( | ||
(nodeCommunityDegree / M) - | ||
( | ||
((nodeOutDegree * communityTotalInWeight) + (nodeInDegree * communityTotalOutWeight)) / | ||
nodeCommunityDegree / M - | ||
(nodeOutDegree * communityTotalInWeight + | ||
nodeInDegree * communityTotalOutWeight) / | ||
(M * M) | ||
) | ||
); | ||
@@ -537,9 +552,15 @@ } | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/modularity: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.size === 0) | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of an empty graph.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of an empty graph.' | ||
); | ||
if (graph.multi) | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.' | ||
); | ||
@@ -549,8 +570,9 @@ var trueType = inferType(graph); | ||
if (trueType === 'mixed') | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of a mixed graph.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of a mixed graph.' | ||
); | ||
options = defaults({}, options || {}, DEFAULTS); | ||
if (trueType === 'directed') | ||
return directedDenseModularity(graph, options); | ||
if (trueType === 'directed') return directedDenseModularity(graph, options); | ||
@@ -562,9 +584,15 @@ return undirectedDenseModularity(graph, options); | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/modularity: given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: given graph is not a valid graphology instance.' | ||
); | ||
if (graph.size === 0) | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of an empty graph.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of an empty graph.' | ||
); | ||
if (graph.multi) | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of a multi graph. Cast it to a simple one beforehand.' | ||
); | ||
@@ -574,8 +602,9 @@ var trueType = inferType(graph); | ||
if (trueType === 'mixed') | ||
throw new Error('graphology-metrics/modularity: cannot compute modularity of a mixed graph.'); | ||
throw new Error( | ||
'graphology-metrics/modularity: cannot compute modularity of a mixed graph.' | ||
); | ||
options = defaults({}, options || {}, DEFAULTS); | ||
if (trueType === 'directed') | ||
return directedSparseModularity(graph, options); | ||
if (trueType === 'directed') return directedSparseModularity(graph, options); | ||
@@ -582,0 +611,0 @@ return undirectedSparseModularity(graph, options); |
{ | ||
"name": "graphology-metrics", | ||
"version": "1.14.3", | ||
"version": "1.15.0", | ||
"description": "Miscellaneous graph metrics for graphology.", | ||
@@ -13,4 +13,3 @@ "main": "index.js", | ||
"scripts": { | ||
"lint": "eslint **/*.js", | ||
"prepublishOnly": "npm run lint && npm test", | ||
"prepublishOnly": "npm test", | ||
"test": "mocha --recursive test" | ||
@@ -20,3 +19,3 @@ }, | ||
"type": "git", | ||
"url": "git+https://github.com/graphology/graphology-metrics.git" | ||
"url": "git+https://github.com/graphology/graphology.git" | ||
}, | ||
@@ -51,14 +50,11 @@ "keywords": [ | ||
"bugs": { | ||
"url": "https://github.com/graphology/graphology-metrics/issues" | ||
"url": "https://github.com/graphology/graphology/issues" | ||
}, | ||
"homepage": "https://github.com/graphology/graphology-metrics#readme", | ||
"homepage": "https://github.com/graphology/graphology#readme", | ||
"peerDependencies": { | ||
"graphology-types": ">=0.20.0" | ||
}, | ||
"eslintConfig": { | ||
"extends": "@yomguithereal/eslint-config" | ||
}, | ||
"dependencies": { | ||
"graphology-shortest-path": "^1.4.1", | ||
"graphology-utils": "^2.1.1", | ||
"graphology-shortest-path": "^1.5.0", | ||
"graphology-utils": "^2.1.2", | ||
"lodash": "^4.17.21", | ||
@@ -65,0 +61,0 @@ "mnemonist": "^0.38.3" |
168
README.md
@@ -1,3 +0,1 @@ | ||
[![Build Status](https://travis-ci.org/graphology/graphology-metrics.svg)](https://travis-ci.org/graphology/graphology-metrics) | ||
# Graphology metrics | ||
@@ -15,28 +13,28 @@ | ||
*Graph metrics* | ||
_Graph metrics_ | ||
* [Density](#density) | ||
* [Diameter](#diameter) | ||
* [Extent](#extent) | ||
* [Modularity](#modularity) | ||
* [Weighted size](#weighted-size) | ||
- [Density](#density) | ||
- [Diameter](#diameter) | ||
- [Extent](#extent) | ||
- [Modularity](#modularity) | ||
- [Weighted size](#weighted-size) | ||
*Node metrics* | ||
_Node metrics_ | ||
* [Centrality](#centrality) | ||
- [Centrality](#centrality) | ||
- [Betweenness centrality](#betweenness-centrality) | ||
- [Degree centrality](#degree-centrality) | ||
* [Degree](#degree) | ||
* [Eccentricity](#eccentricity) | ||
* [Weighted degree](#weighted-degree) | ||
- [Degree](#degree) | ||
- [Eccentricity](#eccentricity) | ||
- [Weighted degree](#weighted-degree) | ||
*Attributes metrics* | ||
_Attributes metrics_ | ||
* [Modalities](#modalities) | ||
- [Modalities](#modalities) | ||
*Layout quality metrics* | ||
_Layout quality metrics_ | ||
* [Edge Uniformity](#edge-uniformity) | ||
* [Neighborhood Preservation](#neighborhood-preservation) | ||
* [Stress](#stress) | ||
- [Edge Uniformity](#edge-uniformity) | ||
- [Neighborhood Preservation](#neighborhood-preservation) | ||
- [Stress](#stress) | ||
@@ -70,12 +68,12 @@ ### Density | ||
*Arguments* | ||
_Arguments_ | ||
Either: | ||
* **graph** *Graph*: target graph. | ||
- **graph** _Graph_: target graph. | ||
Or: | ||
* **order** *number*: number of nodes in the graph. | ||
* **size** *number*: number of edges in the graph. | ||
- **order** _number_: number of nodes in the graph. | ||
- **size** _number_: number of edges in the graph. | ||
@@ -102,6 +100,7 @@ ### Diameter | ||
``` | ||
*Arguments* | ||
* **graph** *Graph*: target graph. | ||
_Arguments_ | ||
- **graph** _Graph_: target graph. | ||
### Extent | ||
@@ -127,6 +126,6 @@ | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **attributes** *string|array*: single attribute names or array of attribute names. | ||
- **graph** _Graph_: target graph. | ||
- **attributes** _string|array_: single attribute names or array of attribute names. | ||
@@ -147,16 +146,16 @@ ### Modularity | ||
const Q = modularity(graph, { | ||
communities: {'1': 0, '2': 0, '3': 1, '4': 1, '5': 1} | ||
communities: {1: 0, 2: 0, 3: 1, 4: 1, 5: 1} | ||
}); | ||
``` | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **options** *?object*: options: | ||
* **attributes** *?object*: attributes' names: | ||
* **community** *?string* [`community`]: name of the nodes' community attribute in case we need to read them from the graph itself. | ||
* **weight** *?string* [`weight`]: name of the edges' weight attribute. | ||
* **communities** *?object*: object mapping nodes to their respective communities. | ||
* **resolution** *?number*: resolution parameter (`γ`). | ||
* **weighted** *?boolean* [`true`]: whether to compute weighted modularity or not. | ||
- **graph** _Graph_: target graph. | ||
- **options** _?object_: options: | ||
- **attributes** _?object_: attributes' names: | ||
- **community** _?string_ [`community`]: name of the nodes' community attribute in case we need to read them from the graph itself. | ||
- **weight** _?string_ [`weight`]: name of the edges' weight attribute. | ||
- **communities** _?object_: object mapping nodes to their respective communities. | ||
- **resolution** _?number_: resolution parameter (`γ`). | ||
- **weighted** _?boolean_ [`true`]: whether to compute weighted modularity or not. | ||
@@ -185,6 +184,6 @@ ### Weighted size | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **weightAttribute** *?string* [`weight`]: name of the weight attribute. | ||
- **graph** _Graph_: target graph. | ||
- **weightAttribute** _?string_ [`weight`]: name of the weight attribute. | ||
@@ -213,11 +212,11 @@ ### Centrality | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **options** *?object*: options: | ||
* **attributes** *?object*: Custom attribute names: | ||
- **centrality** *?string* [`betweennessCentrality`]: Name of the centrality attribute to assign. | ||
- **weight** *?string*: Name of the weight attribute. | ||
* **normalized** *?boolean* [`true`]: should the result be normalized? | ||
* **weighted** *?boolean* [`false`]: should we compute the weighted betweenness centrality? | ||
- **graph** _Graph_: target graph. | ||
- **options** _?object_: options: | ||
- **attributes** _?object_: Custom attribute names: | ||
- **centrality** _?string_ [`betweennessCentrality`]: Name of the centrality attribute to assign. | ||
- **weight** _?string_: Name of the weight attribute. | ||
- **normalized** _?boolean_ [`true`]: should the result be normalized? | ||
- **weighted** _?boolean_ [`false`]: should we compute the weighted betweenness centrality? | ||
@@ -247,8 +246,8 @@ #### Degree centrality | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **options** *?object*: options: | ||
* **attributes** *?object*: custom attribute names: | ||
* **centrality** *?string* [`degreeCentrality`]: name of the centrality attribute to assign. | ||
- **graph** _Graph_: target graph. | ||
- **options** _?object_: options: | ||
- **attributes** _?object_: custom attribute names: | ||
- **centrality** _?string_ [`degreeCentrality`]: name of the centrality attribute to assign. | ||
@@ -282,20 +281,20 @@ ### Weighted degree | ||
*Arguments* | ||
_Arguments_ | ||
To compute the weighted degree of a single node: | ||
* **graph** *Graph*: target graph. | ||
* **node** *any*: desired node. | ||
* **options** *?object*: options. See below. | ||
- **graph** _Graph_: target graph. | ||
- **node** _any_: desired node. | ||
- **options** _?object_: options. See below. | ||
To compute the weighted degree of every node: | ||
* **graph** *Graph*: target graph. | ||
* **options** *?object*: options. See below. | ||
- **graph** _Graph_: target graph. | ||
- **options** _?object_: options. See below. | ||
*Options* | ||
_Options_ | ||
* **attributes** *?object*: custom attribute names: | ||
- **weight** *?string* [`weight`]: name of the weight attribute. | ||
- **weightedDegree** *?string* [`weightedDegree`]: name of the attribute to assign. | ||
- **attributes** _?object_: custom attribute names: | ||
- **weight** _?string_ [`weight`]: name of the weight attribute. | ||
- **weightedDegree** _?string_ [`weightedDegree`]: name of the attribute to assign. | ||
@@ -359,13 +358,13 @@ ### Degree | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **options** *?object*: options: | ||
- **attributes** *?object*: Custom attribute names: | ||
+ **degree** *?string*: Name of the mixed degree attribute. | ||
+ **inDegree** *?string*: Name of the mixed inDegree attribute. | ||
+ **outDegree** *?string*: Name of the mixed outDegree attribute. | ||
+ **undirectedDegree** *?string*: Name of the mixed undirectedDegree attribute. | ||
+ **directedDegree** *?string*: Name of the mixed directedDegree attribute. | ||
- **types** *?array*: List of degree types to extract. | ||
- **graph** _Graph_: target graph. | ||
- **options** _?object_: options: | ||
- **attributes** _?object_: Custom attribute names: | ||
- **degree** _?string_: Name of the mixed degree attribute. | ||
- **inDegree** _?string_: Name of the mixed inDegree attribute. | ||
- **outDegree** _?string_: Name of the mixed outDegree attribute. | ||
- **undirectedDegree** _?string_: Name of the mixed undirectedDegree attribute. | ||
- **directedDegree** _?string_: Name of the mixed directedDegree attribute. | ||
- **types** _?array_: List of degree types to extract. | ||
@@ -390,12 +389,10 @@ ### Eccentricity | ||
eccentricity(graph, 3) | ||
>> 1 | ||
eccentricity(graph, 3) >> 1; | ||
``` | ||
_Arguments_ | ||
``` | ||
*Arguments* | ||
- **graph** _Graph_: target graph. | ||
- **node** _any_: desired node. | ||
* **graph** *Graph*: target graph. | ||
* **node** *any*: desired node. | ||
### Modalities | ||
@@ -433,6 +430,6 @@ | ||
*Arguments* | ||
_Arguments_ | ||
* **graph** *Graph*: target graph. | ||
* **attribute** *string|array*: target categorical attribute or array of categorical attributes. | ||
- **graph** _Graph_: target graph. | ||
- **attribute** _string|array_: target categorical attribute or array of categorical attributes. | ||
@@ -454,3 +451,3 @@ ### Edge Uniformity | ||
Computes the "neighborhood preservation" layout quality metric from the given graph having `x` and `y` positions attached to its nodes. Neighborhood preservation is the average proportion of node neighborhood being the same both in the graph's topology and its 2d layout space. The metric is therefore comprised between `0` and `1`, `1` being the best, meaning that every node keeps its neighborhood perfectly intact within the layout space. | ||
Computes the "neighborhood preservation" layout quality metric from the given graph having `x` and `y` positions attached to its nodes. Neighborhood preservation is the average proportion of node neighborhood being the same both in the graph's topology and its 2d layout space. The metric is therefore comprised between `0` and `1`, `1` being the best, meaning that every node keeps its neighborhood perfectly intact within the layout space. | ||
@@ -466,3 +463,2 @@ Runs in approximately `O(N * log(N))`. | ||
### Stress | ||
@@ -469,0 +465,0 @@ |
@@ -5,5 +5,5 @@ import Graph from 'graphology-types'; | ||
attributes?: { | ||
weight?: string, | ||
weightedDegree?: string | ||
} | ||
weight?: string; | ||
weightedDegree?: string; | ||
}; | ||
}; | ||
@@ -22,5 +22,5 @@ | ||
interface IWeightedDegree extends IWeightedDegreeBase { | ||
weightedDegree: IWeightedDegreeBase, | ||
weightedInDegree: IWeightedDegreeBase, | ||
weightedOutDegree: IWeightedDegreeBase | ||
weightedDegree: IWeightedDegreeBase; | ||
weightedInDegree: IWeightedDegreeBase; | ||
weightedOutDegree: IWeightedDegreeBase; | ||
} | ||
@@ -27,0 +27,0 @@ |
@@ -45,6 +45,16 @@ /** | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/' + name + ': the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/' + | ||
name + | ||
': the given graph is not a valid graphology instance.' | ||
); | ||
if (edgeGetter !== 'edges' && graph.type === 'undirected') | ||
throw new Error('graphology-metrics/' + name + ': cannot compute ' + name + ' on an undirected graph.'); | ||
throw new Error( | ||
'graphology-metrics/' + | ||
name + | ||
': cannot compute ' + | ||
name + | ||
' on an undirected graph.' | ||
); | ||
@@ -56,4 +66,3 @@ var singleNode = null; | ||
singleNode = arguments[4]; | ||
} | ||
else if (arguments.length === 6) { | ||
} else if (arguments.length === 6) { | ||
singleNode = arguments[4]; | ||
@@ -69,9 +78,5 @@ options = arguments[5]; | ||
var weightAttribute = attributes.weight || DEFAULT_WEIGHT_ATTRIBUTE, | ||
weightedDegreeAttribute = attributes.weightedDegree || name; | ||
weightedDegreeAttribute = attributes.weightedDegree || name; | ||
var edges, | ||
d, | ||
w, | ||
i, | ||
l; | ||
var edges, d, w, i, l; | ||
@@ -86,4 +91,3 @@ // Computing weighted degree for a single node | ||
if (typeof w === 'number') | ||
d += w; | ||
if (typeof w === 'number') d += w; | ||
} | ||
@@ -94,4 +98,3 @@ | ||
return; | ||
} | ||
else { | ||
} else { | ||
return d; | ||
@@ -104,6 +107,6 @@ } | ||
var nodes = graph.nodes(), | ||
node, | ||
weightedDegrees = {}, | ||
j, | ||
m; | ||
node, | ||
weightedDegrees = {}, | ||
j, | ||
m; | ||
@@ -118,14 +121,10 @@ for (i = 0, l = nodes.length; i < l; i++) { | ||
if (typeof w === 'number') | ||
d += w; | ||
if (typeof w === 'number') d += w; | ||
} | ||
if (assign) | ||
graph.setNodeAttribute(node, weightedDegreeAttribute, d); | ||
else | ||
weightedDegrees[node] = d; | ||
if (assign) graph.setNodeAttribute(node, weightedDegreeAttribute, d); | ||
else weightedDegrees[node] = d; | ||
} | ||
if (!assign) | ||
return weightedDegrees; | ||
if (!assign) return weightedDegrees; | ||
} | ||
@@ -136,9 +135,39 @@ | ||
*/ | ||
var weightedDegree = abstractWeightedDegree.bind(null, 'weightedDegree', false, 'edges'), | ||
weightedInDegree = abstractWeightedDegree.bind(null, 'weightedInDegree', false, 'inEdges'), | ||
weightedOutDegree = abstractWeightedDegree.bind(null, 'weightedOutDegree', false, 'outEdges'); | ||
var weightedDegree = abstractWeightedDegree.bind( | ||
null, | ||
'weightedDegree', | ||
false, | ||
'edges' | ||
), | ||
weightedInDegree = abstractWeightedDegree.bind( | ||
null, | ||
'weightedInDegree', | ||
false, | ||
'inEdges' | ||
), | ||
weightedOutDegree = abstractWeightedDegree.bind( | ||
null, | ||
'weightedOutDegree', | ||
false, | ||
'outEdges' | ||
); | ||
weightedDegree.assign = abstractWeightedDegree.bind(null, 'weightedDegree', true, 'edges'); | ||
weightedInDegree.assign = abstractWeightedDegree.bind(null, 'weightedInDegree', true, 'inEdges'); | ||
weightedOutDegree.assign = abstractWeightedDegree.bind(null, 'weightedOutDegree', true, 'outEdges'); | ||
weightedDegree.assign = abstractWeightedDegree.bind( | ||
null, | ||
'weightedDegree', | ||
true, | ||
'edges' | ||
); | ||
weightedInDegree.assign = abstractWeightedDegree.bind( | ||
null, | ||
'weightedInDegree', | ||
true, | ||
'inEdges' | ||
); | ||
weightedOutDegree.assign = abstractWeightedDegree.bind( | ||
null, | ||
'weightedOutDegree', | ||
true, | ||
'outEdges' | ||
); | ||
@@ -145,0 +174,0 @@ /** |
import Graph from 'graphology-types'; | ||
export default function weightedSize(graph: Graph, weightAttribute?: string): number; | ||
export default function weightedSize( | ||
graph: Graph, | ||
weightAttribute?: string | ||
): number; |
@@ -22,6 +22,7 @@ /** | ||
module.exports = function weightedSize(graph, weightAttribute) { | ||
// Handling errors | ||
if (!isGraph(graph)) | ||
throw new Error('graphology-metrics/weighted-size: the given graph is not a valid graphology instance.'); | ||
throw new Error( | ||
'graphology-metrics/weighted-size: the given graph is not a valid graphology instance.' | ||
); | ||
@@ -31,6 +32,6 @@ weightAttribute = weightAttribute || DEFAULT_WEIGHT_ATTRIBUTE; | ||
var edges = graph.edges(), | ||
W = 0, | ||
w, | ||
i, | ||
l; | ||
W = 0, | ||
w, | ||
i, | ||
l; | ||
@@ -40,4 +41,3 @@ for (i = 0, l = edges.length; i < l; i++) { | ||
if (typeof w === 'number') | ||
W += w; | ||
if (typeof w === 'number') W += w; | ||
} | ||
@@ -44,0 +44,0 @@ |
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
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
71999
1710
0
0
466
+ Addedgraphology-types@0.24.7(transitive)
- Removedgraphology-types@0.24.8(transitive)
Updatedgraphology-utils@^2.1.2