|
import * as is from '../../is'; |
|
import * as util from '../../util'; |
|
|
|
const defaults = util.defaults({ |
|
root: null, |
|
weight: edge => 1, |
|
directed: false, |
|
alpha: 0 |
|
}); |
|
|
|
let elesfn = ({ |
|
degreeCentralityNormalized: function( options ){ |
|
options = defaults( options ); |
|
|
|
let cy = this.cy(); |
|
let nodes = this.nodes(); |
|
let numNodes = nodes.length; |
|
|
|
if( !options.directed ){ |
|
let degrees = {}; |
|
let maxDegree = 0; |
|
|
|
for( let i = 0; i < numNodes; i++ ){ |
|
let node = nodes[ i ]; |
|
|
|
|
|
options.root = node; |
|
|
|
let currDegree = this.degreeCentrality( options ); |
|
|
|
if( maxDegree < currDegree.degree ){ |
|
maxDegree = currDegree.degree; |
|
} |
|
|
|
degrees[ node.id() ] = currDegree.degree; |
|
} |
|
|
|
return { |
|
degree: function( node ){ |
|
if( maxDegree === 0 ){ return 0; } |
|
|
|
if( is.string( node ) ){ |
|
|
|
node = cy.filter( node ); |
|
} |
|
|
|
return degrees[ node.id() ] / maxDegree; |
|
} |
|
}; |
|
} else { |
|
let indegrees = {}; |
|
let outdegrees = {}; |
|
let maxIndegree = 0; |
|
let maxOutdegree = 0; |
|
|
|
for( let i = 0; i < numNodes; i++ ){ |
|
let node = nodes[ i ]; |
|
let id = node.id(); |
|
|
|
|
|
options.root = node; |
|
|
|
let currDegree = this.degreeCentrality( options ); |
|
|
|
if( maxIndegree < currDegree.indegree ) |
|
maxIndegree = currDegree.indegree; |
|
|
|
if( maxOutdegree < currDegree.outdegree ) |
|
maxOutdegree = currDegree.outdegree; |
|
|
|
indegrees[ id ] = currDegree.indegree; |
|
outdegrees[ id ] = currDegree.outdegree; |
|
} |
|
|
|
return { |
|
indegree: function( node ){ |
|
if ( maxIndegree == 0 ){ return 0; } |
|
|
|
if( is.string( node ) ){ |
|
|
|
node = cy.filter( node ); |
|
} |
|
|
|
return indegrees[ node.id() ] / maxIndegree; |
|
}, |
|
outdegree: function( node ){ |
|
if ( maxOutdegree === 0 ){ return 0; } |
|
|
|
if( is.string( node ) ){ |
|
|
|
node = cy.filter( node ); |
|
} |
|
|
|
return outdegrees[ node.id() ] / maxOutdegree; |
|
} |
|
|
|
}; |
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
degreeCentrality: function( options ){ |
|
options = defaults( options ); |
|
|
|
let cy = this.cy(); |
|
let callingEles = this; |
|
let { root, weight, directed, alpha } = options; |
|
|
|
root = cy.collection(root)[0]; |
|
|
|
if( !directed ){ |
|
let connEdges = root.connectedEdges().intersection( callingEles ); |
|
let k = connEdges.length; |
|
let s = 0; |
|
|
|
|
|
for( let i = 0; i < connEdges.length; i++ ){ |
|
s += weight( connEdges[i] ); |
|
} |
|
|
|
return { |
|
degree: Math.pow( k, 1 - alpha ) * Math.pow( s, alpha ) |
|
}; |
|
} else { |
|
let edges = root.connectedEdges(); |
|
let incoming = edges.filter( edge => edge.target().same(root) && callingEles.has(edge) ); |
|
let outgoing = edges.filter( edge => edge.source().same(root) && callingEles.has(edge) ); |
|
let k_in = incoming.length; |
|
let k_out = outgoing.length; |
|
let s_in = 0; |
|
let s_out = 0; |
|
|
|
|
|
for( let i = 0; i < incoming.length; i++ ){ |
|
s_in += weight( incoming[i] ); |
|
} |
|
|
|
|
|
for( let i = 0; i < outgoing.length; i++ ){ |
|
s_out += weight( outgoing[i] ); |
|
} |
|
|
|
return { |
|
indegree: Math.pow( k_in, 1 - alpha ) * Math.pow( s_in, alpha ), |
|
outdegree: Math.pow( k_out, 1 - alpha ) * Math.pow( s_out, alpha ) |
|
}; |
|
} |
|
} |
|
|
|
}); |
|
|
|
|
|
elesfn.dc = elesfn.degreeCentrality; |
|
elesfn.dcn = elesfn.degreeCentralityNormalised = elesfn.degreeCentralityNormalized; |
|
|
|
export default elesfn; |
|
|