flow like the river
This commit is contained in:
commit
013fe673f3
42435 changed files with 5764238 additions and 0 deletions
2
VISUALIZACION/node_modules/ngraph.graph/.eslintignore
generated
vendored
Executable file
2
VISUALIZACION/node_modules/ngraph.graph/.eslintignore
generated
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
dist
|
||||
demo/dist
|
||||
18
VISUALIZACION/node_modules/ngraph.graph/.eslintrc.json
generated
vendored
Executable file
18
VISUALIZACION/node_modules/ngraph.graph/.eslintrc.json
generated
vendored
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"semi": "error",
|
||||
"no-undef": "error",
|
||||
"no-unused-vars": "error",
|
||||
"no-shadow": "error"
|
||||
}
|
||||
}
|
||||
26
VISUALIZACION/node_modules/ngraph.graph/.github/workflows/tests.yaml
generated
vendored
Executable file
26
VISUALIZACION/node_modules/ngraph.graph/.github/workflows/tests.yaml
generated
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x, 14.x, 15.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
- run: npm run build --if-present
|
||||
- run: npm test
|
||||
39
VISUALIZACION/node_modules/ngraph.graph/CHANGELOG.md
generated
vendored
Executable file
39
VISUALIZACION/node_modules/ngraph.graph/CHANGELOG.md
generated
vendored
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
# v20.0.0
|
||||
|
||||
The changelog is introduced. Justification for it is that there is a breaking change
|
||||
in the library, and I wanted to call it out here.
|
||||
|
||||
### getLink(fromId, toId) / getLinks(nodeId)
|
||||
|
||||
`graph.getLinks(nodeId)` now returns a `Set` object. Previous version of the method
|
||||
returned an `Array`.
|
||||
|
||||
Pre `v20.0.0` library versions, `getLink(fromId, toId)` operation had `O(deg(fromId))` time performance.
|
||||
|
||||
In `v20.0.0` the links are manged via sets, driving the `getLink()` performance down to `O(1)`.
|
||||
|
||||
#### How to update?
|
||||
|
||||
If your library used `graph.getLinks(fromId).length` constructs, you'll need to change that to
|
||||
`graph.getLinks(fromId).size`
|
||||
|
||||
### addLink(fromId, toId, data)
|
||||
|
||||
For non-multigraphs, this method will now act similar to `addNode(nodeId, data)`. If link is
|
||||
already present in the graph it will replace old `link.data` with new `data`. Otherwise a new link will be created.
|
||||
|
||||
Prior versions of the library always create a new link and clients were required to check link
|
||||
presence to avoid duplicates.
|
||||
|
||||
```
|
||||
// this code is no longer necessary:
|
||||
if (graph.hasLink(fromId, toId) || graph.hasLink(toId, fromId)) {
|
||||
graph.addLink(fromId, toId, 42);
|
||||
}
|
||||
|
||||
// In version v20.0.0 it is equivalent to:
|
||||
graph.addLink(fromId, toId, 42);
|
||||
```
|
||||
|
||||
For multigraphs this method will act the same way as before - a new link will always be created.
|
||||
|
||||
27
VISUALIZACION/node_modules/ngraph.graph/LICENSE
generated
vendored
Executable file
27
VISUALIZACION/node_modules/ngraph.graph/LICENSE
generated
vendored
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2013 - 2022, Andrei Kashcha
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
Neither the name of the Andrei Kashcha nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
198
VISUALIZACION/node_modules/ngraph.graph/README.md
generated
vendored
Executable file
198
VISUALIZACION/node_modules/ngraph.graph/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,198 @@
|
|||
ngraph.graph
|
||||
============
|
||||
|
||||
[Graph](http://en.wikipedia.org/wiki/Graph_\(mathematics\)) data structure for
|
||||
javascript. This library belongs to a family of javascript graph packages called [ngraph](https://github.com/anvaka/ngraph).
|
||||
|
||||
[](https://github.com/anvaka/ngraph.graph/actions/workflows/tests.yaml)
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
With [npm](http://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install ngraph.graph
|
||||
```
|
||||
|
||||
Or download from CDN:
|
||||
|
||||
``` html
|
||||
<script src='https://unpkg.com/ngraph.graph@20.0.1/dist/ngraph.graph.min.js'></script>
|
||||
```
|
||||
|
||||
If you download from CDN the library will be available under `createGraph` global name.
|
||||
|
||||
## Creating a graph
|
||||
Create a graph with no edges and no nodes:
|
||||
|
||||
``` js
|
||||
var createGraph = require('ngraph.graph');
|
||||
var g = createGraph();
|
||||
```
|
||||
|
||||
## Growing a graph
|
||||
The graph `g` can be grown in two ways. You can add one node at a time:
|
||||
|
||||
``` js
|
||||
g.addNode('hello');
|
||||
g.addNode('world');
|
||||
```
|
||||
|
||||
Now graph `g` contains two nodes: `hello` and `world`. You can also use `addLink()`
|
||||
method to grow a graph. Calling this method with nodes which are not present in
|
||||
the graph creates them:
|
||||
|
||||
``` js
|
||||
g.addLink('space', 'bar'); // now graph 'g' has two new nodes: 'space' and 'bar'
|
||||
```
|
||||
|
||||
If nodes already present in the graph 'addLink()' makes them connected:
|
||||
|
||||
``` js
|
||||
// Only a link between 'hello' and 'world' is created. No new nodes.
|
||||
g.addLink('hello', 'world');
|
||||
```
|
||||
|
||||
### What to use as nodes and edges?
|
||||
The most common and convenient choices are numbers and strings. You can
|
||||
associate arbitrary data with node via optional second argument of `addNode()`
|
||||
method:
|
||||
|
||||
``` js
|
||||
// Node 'world' is associated with a string object 'custom data'
|
||||
g.addNode('world', 'custom data');
|
||||
|
||||
// You can associate arbitrary objects with node:
|
||||
g.addNode('server', {
|
||||
status: 'on',
|
||||
ip: '127.0.0.1'
|
||||
});
|
||||
|
||||
// to get data back use `data` property of node:
|
||||
var server = g.getNode('server');
|
||||
console.log(server.data); // prints associated object
|
||||
```
|
||||
|
||||
You can also associate arbitrary object with a link using third optional
|
||||
argument of `addLink()` method:
|
||||
|
||||
``` js
|
||||
// A link between nodes '1' and '2' is now associated with object 'x'
|
||||
g.addLink(1, 2, x);
|
||||
```
|
||||
|
||||
### Enumerating nodes and links
|
||||
After you created a graph one of the most common things to do is to enumerate
|
||||
its nodes/links to perform an operation.
|
||||
|
||||
``` js
|
||||
g.forEachNode(function(node){
|
||||
console.log(node.id, node.data);
|
||||
});
|
||||
```
|
||||
|
||||
The function takes callback which accepts current node. Node object may contain
|
||||
internal information. `node.id` and `node.data` represent parameters passed to
|
||||
the `g.addNode(id, data)` method and they are guaranteed to be present in future
|
||||
versions of the library.
|
||||
|
||||
To enumerate all links in the graph use `forEachLink()` method:
|
||||
|
||||
``` js
|
||||
g.forEachLink(function(link) {
|
||||
console.dir(link);
|
||||
});
|
||||
```
|
||||
|
||||
To enumerate all links for a specific node use `forEachLinkedNode()` method:
|
||||
``` js
|
||||
g.forEachLinkedNode('hello', function(linkedNode, link){
|
||||
console.log("Connected node: ", linkedNode.id, linkedNode.data);
|
||||
console.dir(link); // link object itself
|
||||
});
|
||||
```
|
||||
|
||||
This method always enumerates both inbound and outbound links. If you want to
|
||||
get only outbound links, pass third optional argument:
|
||||
``` js
|
||||
g.forEachLinkedNode('hello',
|
||||
function(linkedNode, link) { /* ... */ },
|
||||
true // enumerate only outbound links
|
||||
);
|
||||
```
|
||||
|
||||
To get a particular node object use `getNode()` method. E.g.:
|
||||
|
||||
``` js
|
||||
var world = g.getNode('world'); // returns 'world' node
|
||||
console.log(world.id, world.data);
|
||||
```
|
||||
|
||||
To get a particular link object use `getLink()` method:
|
||||
|
||||
``` js
|
||||
var helloWorldLink = g.getLink('hello', 'world'); // returns a link from 'hello' to 'world'
|
||||
console.log(helloWorldLink);
|
||||
```
|
||||
|
||||
To remove a node or a link from a graph use `removeNode()` or `removeLink()`
|
||||
correspondingly:
|
||||
|
||||
``` js
|
||||
g.removeNode('space');
|
||||
// Removing link is a bit harder, since method requires actual link object:
|
||||
g.forEachLinkedNode('hello', function(linkedNode, link){
|
||||
g.removeLink(link);
|
||||
});
|
||||
```
|
||||
|
||||
You can also remove all nodes and links by calling
|
||||
|
||||
``` js
|
||||
g.clear();
|
||||
```
|
||||
|
||||
## Listening to Events
|
||||
Whenever someone changes your graph you can listen to notifications:
|
||||
|
||||
``` js
|
||||
g.on('changed', function(changes) {
|
||||
console.dir(changes); // prints array of change records
|
||||
});
|
||||
|
||||
g.add(42); // this will trigger 'changed event'
|
||||
```
|
||||
|
||||
Each change record holds information:
|
||||
|
||||
```
|
||||
ChangeRecord = {
|
||||
changeType: add|remove|update - describes type of this change
|
||||
node: - only present when this record reflects a node change, represents actual node
|
||||
link: - only present when this record reflects a link change, represents actual link
|
||||
}
|
||||
```
|
||||
|
||||
Sometimes it is desirable to react only on bulk changes. ngraph.graph supports
|
||||
this via `beginUpdate()`/`endUpdate()` methods:
|
||||
|
||||
``` js
|
||||
g.beginUpdate();
|
||||
for(var i = 0; i < 100; ++i) {
|
||||
g.addLink(i, i + 1); // no events are triggered here
|
||||
}
|
||||
g.endUpdate(); // this triggers all listeners of 'changed' event
|
||||
```
|
||||
|
||||
If you want to stop listen to events use `off()` method:
|
||||
``` js
|
||||
g.off('changed', yourHandler); // no longer interested in changes from graph
|
||||
```
|
||||
|
||||
For more information about events, please follow to [ngraph.events](https://github.com/anvaka/ngraph.events)
|
||||
|
||||
|
||||
License
|
||||
=======
|
||||
BSD 3-clause
|
||||
674
VISUALIZACION/node_modules/ngraph.graph/dist/ngraph.graph.js
generated
vendored
Executable file
674
VISUALIZACION/node_modules/ngraph.graph/dist/ngraph.graph.js
generated
vendored
Executable file
|
|
@ -0,0 +1,674 @@
|
|||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.createGraph = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
/**
|
||||
* @fileOverview Contains definition of the core graph object.
|
||||
*/
|
||||
|
||||
// TODO: need to change storage layer:
|
||||
// 1. Be able to get all nodes O(1)
|
||||
// 2. Be able to get number of links O(1)
|
||||
|
||||
/**
|
||||
* @example
|
||||
* var graph = require('ngraph.graph')();
|
||||
* graph.addNode(1); // graph has one node.
|
||||
* graph.addLink(2, 3); // now graph contains three nodes and one link.
|
||||
*
|
||||
*/
|
||||
module.exports = createGraph;
|
||||
|
||||
var eventify = require('ngraph.events');
|
||||
|
||||
/**
|
||||
* Creates a new graph
|
||||
*/
|
||||
function createGraph(options) {
|
||||
// Graph structure is maintained as dictionary of nodes
|
||||
// and array of links. Each node has 'links' property which
|
||||
// hold all links related to that node. And general links
|
||||
// array is used to speed up all links enumeration. This is inefficient
|
||||
// in terms of memory, but simplifies coding.
|
||||
options = options || {};
|
||||
if ('uniqueLinkId' in options) {
|
||||
console.warn(
|
||||
'ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\n' +
|
||||
'Use `multigraph` option instead\n',
|
||||
'\n',
|
||||
'Note: there is also change in default behavior: From now on each graph\n'+
|
||||
'is considered to be not a multigraph by default (each edge is unique).'
|
||||
);
|
||||
|
||||
options.multigraph = options.uniqueLinkId;
|
||||
}
|
||||
|
||||
// Dear reader, the non-multigraphs do not guarantee that there is only
|
||||
// one link for a given pair of node. When this option is set to false
|
||||
// we can save some memory and CPU (18% faster for non-multigraph);
|
||||
if (options.multigraph === undefined) options.multigraph = false;
|
||||
|
||||
if (typeof Map !== 'function') {
|
||||
// TODO: Should we polyfill it ourselves? We don't use much operations there..
|
||||
throw new Error('ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph');
|
||||
}
|
||||
|
||||
var nodes = new Map(); // nodeId => Node
|
||||
var links = new Map(); // linkId => Link
|
||||
// Hash of multi-edges. Used to track ids of edges between same nodes
|
||||
var multiEdges = {};
|
||||
var suspendEvents = 0;
|
||||
|
||||
var createLink = options.multigraph ? createUniqueLink : createSingleLink,
|
||||
|
||||
// Our graph API provides means to listen to graph changes. Users can subscribe
|
||||
// to be notified about changes in the graph by using `on` method. However
|
||||
// in some cases they don't use it. To avoid unnecessary memory consumption
|
||||
// we will not record graph changes until we have at least one subscriber.
|
||||
// Code below supports this optimization.
|
||||
//
|
||||
// Accumulates all changes made during graph updates.
|
||||
// Each change element contains:
|
||||
// changeType - one of the strings: 'add', 'remove' or 'update';
|
||||
// node - if change is related to node this property is set to changed graph's node;
|
||||
// link - if change is related to link this property is set to changed graph's link;
|
||||
changes = [],
|
||||
recordLinkChange = noop,
|
||||
recordNodeChange = noop,
|
||||
enterModification = noop,
|
||||
exitModification = noop;
|
||||
|
||||
// this is our public API:
|
||||
var graphPart = {
|
||||
/**
|
||||
* Sometimes duck typing could be slow. Giving clients a hint about data structure
|
||||
* via explicit version number here:
|
||||
*/
|
||||
version: 20.0,
|
||||
|
||||
/**
|
||||
* Adds node to the graph. If node with given id already exists in the graph
|
||||
* its data is extended with whatever comes in 'data' argument.
|
||||
*
|
||||
* @param nodeId the node's identifier. A string or number is preferred.
|
||||
* @param [data] additional data for the node being added. If node already
|
||||
* exists its data object is augmented with the new one.
|
||||
*
|
||||
* @return {node} The newly added node or node with given id if it already exists.
|
||||
*/
|
||||
addNode: addNode,
|
||||
|
||||
/**
|
||||
* Adds a link to the graph. The function always create a new
|
||||
* link between two nodes. If one of the nodes does not exists
|
||||
* a new node is created.
|
||||
*
|
||||
* @param fromId link start node id;
|
||||
* @param toId link end node id;
|
||||
* @param [data] additional data to be set on the new link;
|
||||
*
|
||||
* @return {link} The newly created link
|
||||
*/
|
||||
addLink: addLink,
|
||||
|
||||
/**
|
||||
* Removes link from the graph. If link does not exist does nothing.
|
||||
*
|
||||
* @param link - object returned by addLink() or getLinks() methods.
|
||||
*
|
||||
* @returns true if link was removed; false otherwise.
|
||||
*/
|
||||
removeLink: removeLink,
|
||||
|
||||
/**
|
||||
* Removes node with given id from the graph. If node does not exist in the graph
|
||||
* does nothing.
|
||||
*
|
||||
* @param nodeId node's identifier passed to addNode() function.
|
||||
*
|
||||
* @returns true if node was removed; false otherwise.
|
||||
*/
|
||||
removeNode: removeNode,
|
||||
|
||||
/**
|
||||
* Gets node with given identifier. If node does not exist undefined value is returned.
|
||||
*
|
||||
* @param nodeId requested node identifier;
|
||||
*
|
||||
* @return {node} in with requested identifier or undefined if no such node exists.
|
||||
*/
|
||||
getNode: getNode,
|
||||
|
||||
/**
|
||||
* Gets number of nodes in this graph.
|
||||
*
|
||||
* @return number of nodes in the graph.
|
||||
*/
|
||||
getNodeCount: getNodeCount,
|
||||
|
||||
/**
|
||||
* Gets total number of links in the graph.
|
||||
*/
|
||||
getLinkCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Gets total number of links in the graph.
|
||||
*/
|
||||
getEdgeCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Synonym for `getLinkCount()`
|
||||
*/
|
||||
getLinksCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Synonym for `getNodeCount()`
|
||||
*/
|
||||
getNodesCount: getNodeCount,
|
||||
|
||||
/**
|
||||
* Gets all links (inbound and outbound) from the node with given id.
|
||||
* If node with given id is not found null is returned.
|
||||
*
|
||||
* @param nodeId requested node identifier.
|
||||
*
|
||||
* @return Set of links from and to requested node if such node exists;
|
||||
* otherwise null is returned.
|
||||
*/
|
||||
getLinks: getLinks,
|
||||
|
||||
/**
|
||||
* Invokes callback on each node of the graph.
|
||||
*
|
||||
* @param {Function(node)} callback Function to be invoked. The function
|
||||
* is passed one argument: visited node.
|
||||
*/
|
||||
forEachNode: forEachNode,
|
||||
|
||||
/**
|
||||
* Invokes callback on every linked (adjacent) node to the given one.
|
||||
*
|
||||
* @param nodeId Identifier of the requested node.
|
||||
* @param {Function(node, link)} callback Function to be called on all linked nodes.
|
||||
* The function is passed two parameters: adjacent node and link object itself.
|
||||
* @param oriented if true graph treated as oriented.
|
||||
*/
|
||||
forEachLinkedNode: forEachLinkedNode,
|
||||
|
||||
/**
|
||||
* Enumerates all links in the graph
|
||||
*
|
||||
* @param {Function(link)} callback Function to be called on all links in the graph.
|
||||
* The function is passed one parameter: graph's link object.
|
||||
*
|
||||
* Link object contains at least the following fields:
|
||||
* fromId - node id where link starts;
|
||||
* toId - node id where link ends,
|
||||
* data - additional data passed to graph.addLink() method.
|
||||
*/
|
||||
forEachLink: forEachLink,
|
||||
|
||||
/**
|
||||
* Suspend all notifications about graph changes until
|
||||
* endUpdate is called.
|
||||
*/
|
||||
beginUpdate: enterModification,
|
||||
|
||||
/**
|
||||
* Resumes all notifications about graph changes and fires
|
||||
* graph 'changed' event in case there are any pending changes.
|
||||
*/
|
||||
endUpdate: exitModification,
|
||||
|
||||
/**
|
||||
* Removes all nodes and links from the graph.
|
||||
*/
|
||||
clear: clear,
|
||||
|
||||
/**
|
||||
* Detects whether there is a link between two nodes.
|
||||
* Operation complexity is O(n) where n - number of links of a node.
|
||||
* NOTE: this function is synonym for getLink()
|
||||
*
|
||||
* @returns link if there is one. null otherwise.
|
||||
*/
|
||||
hasLink: getLink,
|
||||
|
||||
/**
|
||||
* Detects whether there is a node with given id
|
||||
*
|
||||
* Operation complexity is O(1)
|
||||
* NOTE: this function is synonym for getNode()
|
||||
*
|
||||
* @returns node if there is one; Falsy value otherwise.
|
||||
*/
|
||||
hasNode: getNode,
|
||||
|
||||
/**
|
||||
* Gets an edge between two nodes.
|
||||
* Operation complexity is O(n) where n - number of links of a node.
|
||||
*
|
||||
* @param {string} fromId link start identifier
|
||||
* @param {string} toId link end identifier
|
||||
*
|
||||
* @returns link if there is one; undefined otherwise.
|
||||
*/
|
||||
getLink: getLink
|
||||
};
|
||||
|
||||
// this will add `on()` and `fire()` methods.
|
||||
eventify(graphPart);
|
||||
|
||||
monitorSubscribers();
|
||||
|
||||
return graphPart;
|
||||
|
||||
function monitorSubscribers() {
|
||||
var realOn = graphPart.on;
|
||||
|
||||
// replace real `on` with our temporary on, which will trigger change
|
||||
// modification monitoring:
|
||||
graphPart.on = on;
|
||||
|
||||
function on() {
|
||||
// now it's time to start tracking stuff:
|
||||
graphPart.beginUpdate = enterModification = enterModificationReal;
|
||||
graphPart.endUpdate = exitModification = exitModificationReal;
|
||||
recordLinkChange = recordLinkChangeReal;
|
||||
recordNodeChange = recordNodeChangeReal;
|
||||
|
||||
// this will replace current `on` method with real pub/sub from `eventify`.
|
||||
graphPart.on = realOn;
|
||||
// delegate to real `on` handler:
|
||||
return realOn.apply(graphPart, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
function recordLinkChangeReal(link, changeType) {
|
||||
changes.push({
|
||||
link: link,
|
||||
changeType: changeType
|
||||
});
|
||||
}
|
||||
|
||||
function recordNodeChangeReal(node, changeType) {
|
||||
changes.push({
|
||||
node: node,
|
||||
changeType: changeType
|
||||
});
|
||||
}
|
||||
|
||||
function addNode(nodeId, data) {
|
||||
if (nodeId === undefined) {
|
||||
throw new Error('Invalid node identifier');
|
||||
}
|
||||
|
||||
enterModification();
|
||||
|
||||
var node = getNode(nodeId);
|
||||
if (!node) {
|
||||
node = new Node(nodeId, data);
|
||||
recordNodeChange(node, 'add');
|
||||
} else {
|
||||
node.data = data;
|
||||
recordNodeChange(node, 'update');
|
||||
}
|
||||
|
||||
nodes.set(nodeId, node);
|
||||
|
||||
exitModification();
|
||||
return node;
|
||||
}
|
||||
|
||||
function getNode(nodeId) {
|
||||
return nodes.get(nodeId);
|
||||
}
|
||||
|
||||
function removeNode(nodeId) {
|
||||
var node = getNode(nodeId);
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enterModification();
|
||||
|
||||
var prevLinks = node.links;
|
||||
if (prevLinks) {
|
||||
prevLinks.forEach(removeLinkInstance);
|
||||
node.links = null;
|
||||
}
|
||||
|
||||
nodes.delete(nodeId);
|
||||
|
||||
recordNodeChange(node, 'remove');
|
||||
|
||||
exitModification();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function addLink(fromId, toId, data) {
|
||||
enterModification();
|
||||
|
||||
var fromNode = getNode(fromId) || addNode(fromId);
|
||||
var toNode = getNode(toId) || addNode(toId);
|
||||
|
||||
var link = createLink(fromId, toId, data);
|
||||
var isUpdate = links.has(link.id);
|
||||
|
||||
links.set(link.id, link);
|
||||
|
||||
// TODO: this is not cool. On large graphs potentially would consume more memory.
|
||||
addLinkToNode(fromNode, link);
|
||||
if (fromId !== toId) {
|
||||
// make sure we are not duplicating links for self-loops
|
||||
addLinkToNode(toNode, link);
|
||||
}
|
||||
|
||||
recordLinkChange(link, isUpdate ? 'update' : 'add');
|
||||
|
||||
exitModification();
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
function createSingleLink(fromId, toId, data) {
|
||||
var linkId = makeLinkId(fromId, toId);
|
||||
var prevLink = links.get(linkId);
|
||||
if (prevLink) {
|
||||
prevLink.data = data;
|
||||
return prevLink;
|
||||
}
|
||||
|
||||
return new Link(fromId, toId, data, linkId);
|
||||
}
|
||||
|
||||
function createUniqueLink(fromId, toId, data) {
|
||||
// TODO: Find a better/faster way to store multigraphs
|
||||
var linkId = makeLinkId(fromId, toId);
|
||||
var isMultiEdge = multiEdges.hasOwnProperty(linkId);
|
||||
if (isMultiEdge || getLink(fromId, toId)) {
|
||||
if (!isMultiEdge) {
|
||||
multiEdges[linkId] = 0;
|
||||
}
|
||||
var suffix = '@' + (++multiEdges[linkId]);
|
||||
linkId = makeLinkId(fromId + suffix, toId + suffix);
|
||||
}
|
||||
|
||||
return new Link(fromId, toId, data, linkId);
|
||||
}
|
||||
|
||||
function getNodeCount() {
|
||||
return nodes.size;
|
||||
}
|
||||
|
||||
function getLinkCount() {
|
||||
return links.size;
|
||||
}
|
||||
|
||||
function getLinks(nodeId) {
|
||||
var node = getNode(nodeId);
|
||||
return node ? node.links : null;
|
||||
}
|
||||
|
||||
function removeLink(link, otherId) {
|
||||
if (otherId !== undefined) {
|
||||
link = getLink(link, otherId);
|
||||
}
|
||||
return removeLinkInstance(link);
|
||||
}
|
||||
|
||||
function removeLinkInstance(link) {
|
||||
if (!link) {
|
||||
return false;
|
||||
}
|
||||
if (!links.get(link.id)) return false;
|
||||
|
||||
enterModification();
|
||||
|
||||
links.delete(link.id);
|
||||
|
||||
var fromNode = getNode(link.fromId);
|
||||
var toNode = getNode(link.toId);
|
||||
|
||||
if (fromNode) {
|
||||
fromNode.links.delete(link);
|
||||
}
|
||||
|
||||
if (toNode) {
|
||||
toNode.links.delete(link);
|
||||
}
|
||||
|
||||
recordLinkChange(link, 'remove');
|
||||
|
||||
exitModification();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLink(fromNodeId, toNodeId) {
|
||||
if (fromNodeId === undefined || toNodeId === undefined) return undefined;
|
||||
return links.get(makeLinkId(fromNodeId, toNodeId));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
enterModification();
|
||||
forEachNode(function(node) {
|
||||
removeNode(node.id);
|
||||
});
|
||||
exitModification();
|
||||
}
|
||||
|
||||
function forEachLink(callback) {
|
||||
if (typeof callback === 'function') {
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
if (callback(nextValue.value)) {
|
||||
return true; // client doesn't want to proceed. Return.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function forEachLinkedNode(nodeId, callback, oriented) {
|
||||
var node = getNode(nodeId);
|
||||
|
||||
if (node && node.links && typeof callback === 'function') {
|
||||
if (oriented) {
|
||||
return forEachOrientedLink(node.links, nodeId, callback);
|
||||
} else {
|
||||
return forEachNonOrientedLink(node.links, nodeId, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function forEachNonOrientedLink(links, nodeId, callback) {
|
||||
var quitFast;
|
||||
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
var link = nextValue.value;
|
||||
var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId;
|
||||
quitFast = callback(nodes.get(linkedNodeId), link);
|
||||
if (quitFast) {
|
||||
return true; // Client does not need more iterations. Break now.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function forEachOrientedLink(links, nodeId, callback) {
|
||||
var quitFast;
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
var link = nextValue.value;
|
||||
if (link.fromId === nodeId) {
|
||||
quitFast = callback(nodes.get(link.toId), link);
|
||||
if (quitFast) {
|
||||
return true; // Client does not need more iterations. Break now.
|
||||
}
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
// we will not fire anything until users of this library explicitly call `on()`
|
||||
// method.
|
||||
function noop() {}
|
||||
|
||||
// Enter, Exit modification allows bulk graph updates without firing events.
|
||||
function enterModificationReal() {
|
||||
suspendEvents += 1;
|
||||
}
|
||||
|
||||
function exitModificationReal() {
|
||||
suspendEvents -= 1;
|
||||
if (suspendEvents === 0 && changes.length > 0) {
|
||||
graphPart.fire('changed', changes);
|
||||
changes.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function forEachNode(callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('Function is expected to iterate over graph nodes. You passed ' + callback);
|
||||
}
|
||||
|
||||
var valuesIterator = nodes.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
if (callback(nextValue.value)) {
|
||||
return true; // client doesn't want to proceed. Return.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure to represent node;
|
||||
*/
|
||||
function Node(id, data) {
|
||||
this.id = id;
|
||||
this.links = null;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
function addLinkToNode(node, link) {
|
||||
if (node.links) {
|
||||
node.links.add(link);
|
||||
} else {
|
||||
node.links = new Set([link]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure to represent links;
|
||||
*/
|
||||
function Link(fromId, toId, data, id) {
|
||||
this.fromId = fromId;
|
||||
this.toId = toId;
|
||||
this.data = data;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
function makeLinkId(fromId, toId) {
|
||||
return fromId.toString() + '👉 ' + toId.toString();
|
||||
}
|
||||
|
||||
},{"ngraph.events":2}],2:[function(require,module,exports){
|
||||
module.exports = function eventify(subject) {
|
||||
validateSubject(subject);
|
||||
|
||||
var eventsStorage = createEventsStorage(subject);
|
||||
subject.on = eventsStorage.on;
|
||||
subject.off = eventsStorage.off;
|
||||
subject.fire = eventsStorage.fire;
|
||||
return subject;
|
||||
};
|
||||
|
||||
function createEventsStorage(subject) {
|
||||
// Store all event listeners to this hash. Key is event name, value is array
|
||||
// of callback records.
|
||||
//
|
||||
// A callback record consists of callback function and its optional context:
|
||||
// { 'eventName' => [{callback: function, ctx: object}] }
|
||||
var registeredEvents = Object.create(null);
|
||||
|
||||
return {
|
||||
on: function (eventName, callback, ctx) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('callback is expected to be a function');
|
||||
}
|
||||
var handlers = registeredEvents[eventName];
|
||||
if (!handlers) {
|
||||
handlers = registeredEvents[eventName] = [];
|
||||
}
|
||||
handlers.push({callback: callback, ctx: ctx});
|
||||
|
||||
return subject;
|
||||
},
|
||||
|
||||
off: function (eventName, callback) {
|
||||
var wantToRemoveAll = (typeof eventName === 'undefined');
|
||||
if (wantToRemoveAll) {
|
||||
// Killing old events storage should be enough in this case:
|
||||
registeredEvents = Object.create(null);
|
||||
return subject;
|
||||
}
|
||||
|
||||
if (registeredEvents[eventName]) {
|
||||
var deleteAllCallbacksForEvent = (typeof callback !== 'function');
|
||||
if (deleteAllCallbacksForEvent) {
|
||||
delete registeredEvents[eventName];
|
||||
} else {
|
||||
var callbacks = registeredEvents[eventName];
|
||||
for (var i = 0; i < callbacks.length; ++i) {
|
||||
if (callbacks[i].callback === callback) {
|
||||
callbacks.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return subject;
|
||||
},
|
||||
|
||||
fire: function (eventName) {
|
||||
var callbacks = registeredEvents[eventName];
|
||||
if (!callbacks) {
|
||||
return subject;
|
||||
}
|
||||
|
||||
var fireArguments;
|
||||
if (arguments.length > 1) {
|
||||
fireArguments = Array.prototype.splice.call(arguments, 1);
|
||||
}
|
||||
for(var i = 0; i < callbacks.length; ++i) {
|
||||
var callbackInfo = callbacks[i];
|
||||
callbackInfo.callback.apply(callbackInfo.ctx, fireArguments);
|
||||
}
|
||||
|
||||
return subject;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function validateSubject(subject) {
|
||||
if (!subject) {
|
||||
throw new Error('Eventify cannot use falsy object as events subject');
|
||||
}
|
||||
var reservedWords = ['on', 'fire', 'off'];
|
||||
for (var i = 0; i < reservedWords.length; ++i) {
|
||||
if (subject.hasOwnProperty(reservedWords[i])) {
|
||||
throw new Error("Subject cannot be eventified, since it already has property '" + reservedWords[i] + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},{}]},{},[1])(1)
|
||||
});
|
||||
1
VISUALIZACION/node_modules/ngraph.graph/dist/ngraph.graph.min.js
generated
vendored
Executable file
1
VISUALIZACION/node_modules/ngraph.graph/dist/ngraph.graph.min.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
49
VISUALIZACION/node_modules/ngraph.graph/examples/findConnectedComponents.js
generated
vendored
Executable file
49
VISUALIZACION/node_modules/ngraph.graph/examples/findConnectedComponents.js
generated
vendored
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* This examples shows how to find all connected components of a graph.
|
||||
*
|
||||
* Created in response to https://github.com/anvaka/ngraph.graph/issues/18
|
||||
*/
|
||||
module.exports = function findConnectedComponents(graph) {
|
||||
var nodeIdToComponentId = new Map();
|
||||
|
||||
var connectedComponents = [];
|
||||
var lastComponentId = 0;
|
||||
|
||||
graph.forEachNode(function(node) {
|
||||
if (nodeIdToComponentId.has(node.id)) {
|
||||
// we already seen this cluster. Ignore it.
|
||||
return;
|
||||
}
|
||||
|
||||
// We found a new connected component:
|
||||
nodeIdToComponentId.set(node.id, lastComponentId);
|
||||
var currentComponent = [node.id];
|
||||
connectedComponents.push(currentComponent);
|
||||
|
||||
// Let's find what other nodes belong to this component
|
||||
dfs(graph, node.id, otherNode => {
|
||||
let componentId = nodeIdToComponentId.get(otherNode.id);
|
||||
if (componentId !== undefined && componentId === lastComponentId) {
|
||||
// this is possible when we have a loop. Just ignore the node.
|
||||
return false;
|
||||
} else if (componentId !== undefined) {
|
||||
throw new Error('Reached a component from another component. DFS is broken?');
|
||||
}
|
||||
|
||||
currentComponent.push(otherNode.id);
|
||||
nodeIdToComponentId.set(otherNode.id, lastComponentId);
|
||||
|
||||
return true; // let's visit neighbors
|
||||
});
|
||||
|
||||
lastComponentId += 1;
|
||||
});
|
||||
|
||||
return connectedComponents;
|
||||
};
|
||||
|
||||
function dfs(graph, startFromNodeId, visitor) {
|
||||
graph.forEachLinkedNode(startFromNodeId, function(otherNode) {
|
||||
if (visitor(otherNode)) dfs(graph, otherNode.id, visitor);
|
||||
});
|
||||
}
|
||||
182
VISUALIZACION/node_modules/ngraph.graph/index.d.ts
generated
vendored
Executable file
182
VISUALIZACION/node_modules/ngraph.graph/index.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,182 @@
|
|||
// Type definitions for ngraph.graph v20.0.0
|
||||
// Project: https://github.com/anvaka/ngraph.graph
|
||||
// Definitions by: Nathan Westlake <https://github.com/CorayThan> and Anvaka <https://github.com/anvaka>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/**
|
||||
* A graph data structure for javascript.
|
||||
*/
|
||||
declare module "ngraph.graph" {
|
||||
import { EventedType } from 'ngraph.events'
|
||||
|
||||
export type NodeId = string | number
|
||||
export type LinkId = string
|
||||
|
||||
/**
|
||||
* A single link (edge) of the graph
|
||||
*/
|
||||
export interface Link<Data = any> {
|
||||
/**
|
||||
* Unique identifier of this link
|
||||
*/
|
||||
id: LinkId,
|
||||
|
||||
/**
|
||||
* Node identifier where this links starts
|
||||
*/
|
||||
fromId: NodeId,
|
||||
|
||||
/**
|
||||
* Node identifier where this link points to
|
||||
*/
|
||||
toId: NodeId,
|
||||
/**
|
||||
* Arbitrary data associated with this link
|
||||
*/
|
||||
data: Data
|
||||
}
|
||||
|
||||
/**
|
||||
* A single node of a graph.
|
||||
*/
|
||||
export interface Node<Data = any> {
|
||||
/**
|
||||
* Unique identifier of this node
|
||||
*/
|
||||
id: NodeId,
|
||||
|
||||
/**
|
||||
* Set of incoming/outgoing links (edges) to/from this node.
|
||||
*
|
||||
* For the sake of memory consumption preservation, this property
|
||||
* is null when this node has no links.
|
||||
*
|
||||
* Link instance is referentially equal throughout the API.
|
||||
*/
|
||||
links: Set<Link<any>> | null,
|
||||
|
||||
/**
|
||||
* Associated data connected to this node.
|
||||
*/
|
||||
data: Data
|
||||
}
|
||||
|
||||
/**
|
||||
* A graph data structure
|
||||
*/
|
||||
export interface Graph<NodeData = any, LinkData = any> {
|
||||
/**
|
||||
* Adds a new node to the graph. If node with such id already exists
|
||||
* its data is overwritten with the new data
|
||||
*/
|
||||
addNode: (node: NodeId, data?: NodeData) => Node<NodeData>
|
||||
|
||||
/**
|
||||
* Adds a new link to the graph. If link already exists and the graph
|
||||
* is not a multigraph, then link's data is overwritten with a new data.
|
||||
*
|
||||
* When graph is a multigraph, then a new link is always added between the
|
||||
* nodes.
|
||||
*/
|
||||
addLink: (from: NodeId, to: NodeId, data?: LinkData) => Link<LinkData>
|
||||
|
||||
/**
|
||||
* Removes a link from the graph. You'll need to pass an actual link instance
|
||||
* to remove it. If you pass two arguments, the function assumes they represent
|
||||
* from/to node ids, and removes the corresponding link.
|
||||
*
|
||||
* Returns true if link is found and removed. False otherwise.
|
||||
*/
|
||||
removeLink: (link: Link<LinkData>) => boolean
|
||||
|
||||
/**
|
||||
* Removes node by node id. Returns true if node was removed,
|
||||
* false otherwise (e.g. no such node exists in the graph)
|
||||
*/
|
||||
removeNode: (nodeId: NodeId) => boolean
|
||||
|
||||
/**
|
||||
* Returns a node by its identifier. Undefined value is returned if node
|
||||
* with such identifer does not exist.
|
||||
*/
|
||||
getNode: (nodeId: NodeId) => Node<NodeData> | undefined
|
||||
|
||||
/**
|
||||
* Checks whether given node exists in the graph. Return the node
|
||||
* or undefined if no such node exist.
|
||||
*/
|
||||
hasNode: (nodeId: NodeId) => Node<NodeData> | undefined
|
||||
|
||||
/**
|
||||
* Returns a link between two nodes
|
||||
*/
|
||||
getLink: (fromNodeId: NodeId, toNodeId: NodeId) => Link<LinkData> | undefined
|
||||
|
||||
/**
|
||||
* Checks if link is present in the graph
|
||||
*/
|
||||
hasLink: (fromNodeId: NodeId, toNodeId: NodeId) => Link<LinkData> | undefined
|
||||
|
||||
/**
|
||||
* Returns number of nodes in the graph
|
||||
*/
|
||||
getNodesCount: () => number
|
||||
|
||||
/**
|
||||
* Returns number of nodes in the graph
|
||||
*/
|
||||
getNodeCount: () => number
|
||||
|
||||
/**
|
||||
* Returns number of links (edges) in the graph
|
||||
*/
|
||||
getLinksCount: () => number
|
||||
|
||||
/**
|
||||
* Returns number of links (edges) in the graph
|
||||
*/
|
||||
getLinkCount: () => number
|
||||
|
||||
/**
|
||||
* Returns all links associated with this node
|
||||
*/
|
||||
getLinks: (nodeId: NodeId) => Set<Link<LinkData>> | null
|
||||
|
||||
/**
|
||||
* Iterates over every single node in the graph, passing the node to a callback.
|
||||
*
|
||||
* If callback function returns "true"-like value, enumeration stops.
|
||||
**/
|
||||
forEachNode: (callbackPerNode: (node: Node<NodeData>) => void | undefined | null | boolean) => void
|
||||
|
||||
/**
|
||||
* Iterates over every single link in the graph, passing the link to a callback.
|
||||
* If callback function returns "true"-like value, enumeration stops.
|
||||
*/
|
||||
forEachLink: (callbackPerLink: (link: Link<LinkData>) => void | undefined | boolean) => void
|
||||
|
||||
forEachLinkedNode: (nodeId: NodeId, callbackPerNode: (node: Node<NodeData>, link: Link<LinkData>) => void, oriented: boolean) => void
|
||||
/**
|
||||
* Suspend all notifications about graph changes until
|
||||
* endUpdate is called.
|
||||
*/
|
||||
beginUpdate: () => void
|
||||
|
||||
/**
|
||||
* Resumes all notifications about graph changes and fires
|
||||
* graph 'changed' event in case there are any pending changes.
|
||||
*/
|
||||
endUpdate: () => void
|
||||
|
||||
/**
|
||||
* Removes all nodes and links from the graph.
|
||||
*/
|
||||
clear: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of a graph.
|
||||
*/
|
||||
export default function createGraph<NodeData = any, LinkData = any>(options?: { multigraph: boolean }): Graph<NodeData, LinkData> & EventedType
|
||||
|
||||
}
|
||||
580
VISUALIZACION/node_modules/ngraph.graph/index.js
generated
vendored
Executable file
580
VISUALIZACION/node_modules/ngraph.graph/index.js
generated
vendored
Executable file
|
|
@ -0,0 +1,580 @@
|
|||
/**
|
||||
* @fileOverview Contains definition of the core graph object.
|
||||
*/
|
||||
|
||||
// TODO: need to change storage layer:
|
||||
// 1. Be able to get all nodes O(1)
|
||||
// 2. Be able to get number of links O(1)
|
||||
|
||||
/**
|
||||
* @example
|
||||
* var graph = require('ngraph.graph')();
|
||||
* graph.addNode(1); // graph has one node.
|
||||
* graph.addLink(2, 3); // now graph contains three nodes and one link.
|
||||
*
|
||||
*/
|
||||
module.exports = createGraph;
|
||||
|
||||
var eventify = require('ngraph.events');
|
||||
|
||||
/**
|
||||
* Creates a new graph
|
||||
*/
|
||||
function createGraph(options) {
|
||||
// Graph structure is maintained as dictionary of nodes
|
||||
// and array of links. Each node has 'links' property which
|
||||
// hold all links related to that node. And general links
|
||||
// array is used to speed up all links enumeration. This is inefficient
|
||||
// in terms of memory, but simplifies coding.
|
||||
options = options || {};
|
||||
if ('uniqueLinkId' in options) {
|
||||
console.warn(
|
||||
'ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\n' +
|
||||
'Use `multigraph` option instead\n',
|
||||
'\n',
|
||||
'Note: there is also change in default behavior: From now on each graph\n'+
|
||||
'is considered to be not a multigraph by default (each edge is unique).'
|
||||
);
|
||||
|
||||
options.multigraph = options.uniqueLinkId;
|
||||
}
|
||||
|
||||
// Dear reader, the non-multigraphs do not guarantee that there is only
|
||||
// one link for a given pair of node. When this option is set to false
|
||||
// we can save some memory and CPU (18% faster for non-multigraph);
|
||||
if (options.multigraph === undefined) options.multigraph = false;
|
||||
|
||||
if (typeof Map !== 'function') {
|
||||
// TODO: Should we polyfill it ourselves? We don't use much operations there..
|
||||
throw new Error('ngraph.graph requires `Map` to be defined. Please polyfill it before using ngraph');
|
||||
}
|
||||
|
||||
var nodes = new Map(); // nodeId => Node
|
||||
var links = new Map(); // linkId => Link
|
||||
// Hash of multi-edges. Used to track ids of edges between same nodes
|
||||
var multiEdges = {};
|
||||
var suspendEvents = 0;
|
||||
|
||||
var createLink = options.multigraph ? createUniqueLink : createSingleLink,
|
||||
|
||||
// Our graph API provides means to listen to graph changes. Users can subscribe
|
||||
// to be notified about changes in the graph by using `on` method. However
|
||||
// in some cases they don't use it. To avoid unnecessary memory consumption
|
||||
// we will not record graph changes until we have at least one subscriber.
|
||||
// Code below supports this optimization.
|
||||
//
|
||||
// Accumulates all changes made during graph updates.
|
||||
// Each change element contains:
|
||||
// changeType - one of the strings: 'add', 'remove' or 'update';
|
||||
// node - if change is related to node this property is set to changed graph's node;
|
||||
// link - if change is related to link this property is set to changed graph's link;
|
||||
changes = [],
|
||||
recordLinkChange = noop,
|
||||
recordNodeChange = noop,
|
||||
enterModification = noop,
|
||||
exitModification = noop;
|
||||
|
||||
// this is our public API:
|
||||
var graphPart = {
|
||||
/**
|
||||
* Sometimes duck typing could be slow. Giving clients a hint about data structure
|
||||
* via explicit version number here:
|
||||
*/
|
||||
version: 20.0,
|
||||
|
||||
/**
|
||||
* Adds node to the graph. If node with given id already exists in the graph
|
||||
* its data is extended with whatever comes in 'data' argument.
|
||||
*
|
||||
* @param nodeId the node's identifier. A string or number is preferred.
|
||||
* @param [data] additional data for the node being added. If node already
|
||||
* exists its data object is augmented with the new one.
|
||||
*
|
||||
* @return {node} The newly added node or node with given id if it already exists.
|
||||
*/
|
||||
addNode: addNode,
|
||||
|
||||
/**
|
||||
* Adds a link to the graph. The function always create a new
|
||||
* link between two nodes. If one of the nodes does not exists
|
||||
* a new node is created.
|
||||
*
|
||||
* @param fromId link start node id;
|
||||
* @param toId link end node id;
|
||||
* @param [data] additional data to be set on the new link;
|
||||
*
|
||||
* @return {link} The newly created link
|
||||
*/
|
||||
addLink: addLink,
|
||||
|
||||
/**
|
||||
* Removes link from the graph. If link does not exist does nothing.
|
||||
*
|
||||
* @param link - object returned by addLink() or getLinks() methods.
|
||||
*
|
||||
* @returns true if link was removed; false otherwise.
|
||||
*/
|
||||
removeLink: removeLink,
|
||||
|
||||
/**
|
||||
* Removes node with given id from the graph. If node does not exist in the graph
|
||||
* does nothing.
|
||||
*
|
||||
* @param nodeId node's identifier passed to addNode() function.
|
||||
*
|
||||
* @returns true if node was removed; false otherwise.
|
||||
*/
|
||||
removeNode: removeNode,
|
||||
|
||||
/**
|
||||
* Gets node with given identifier. If node does not exist undefined value is returned.
|
||||
*
|
||||
* @param nodeId requested node identifier;
|
||||
*
|
||||
* @return {node} in with requested identifier or undefined if no such node exists.
|
||||
*/
|
||||
getNode: getNode,
|
||||
|
||||
/**
|
||||
* Gets number of nodes in this graph.
|
||||
*
|
||||
* @return number of nodes in the graph.
|
||||
*/
|
||||
getNodeCount: getNodeCount,
|
||||
|
||||
/**
|
||||
* Gets total number of links in the graph.
|
||||
*/
|
||||
getLinkCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Gets total number of links in the graph.
|
||||
*/
|
||||
getEdgeCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Synonym for `getLinkCount()`
|
||||
*/
|
||||
getLinksCount: getLinkCount,
|
||||
|
||||
/**
|
||||
* Synonym for `getNodeCount()`
|
||||
*/
|
||||
getNodesCount: getNodeCount,
|
||||
|
||||
/**
|
||||
* Gets all links (inbound and outbound) from the node with given id.
|
||||
* If node with given id is not found null is returned.
|
||||
*
|
||||
* @param nodeId requested node identifier.
|
||||
*
|
||||
* @return Set of links from and to requested node if such node exists;
|
||||
* otherwise null is returned.
|
||||
*/
|
||||
getLinks: getLinks,
|
||||
|
||||
/**
|
||||
* Invokes callback on each node of the graph.
|
||||
*
|
||||
* @param {Function(node)} callback Function to be invoked. The function
|
||||
* is passed one argument: visited node.
|
||||
*/
|
||||
forEachNode: forEachNode,
|
||||
|
||||
/**
|
||||
* Invokes callback on every linked (adjacent) node to the given one.
|
||||
*
|
||||
* @param nodeId Identifier of the requested node.
|
||||
* @param {Function(node, link)} callback Function to be called on all linked nodes.
|
||||
* The function is passed two parameters: adjacent node and link object itself.
|
||||
* @param oriented if true graph treated as oriented.
|
||||
*/
|
||||
forEachLinkedNode: forEachLinkedNode,
|
||||
|
||||
/**
|
||||
* Enumerates all links in the graph
|
||||
*
|
||||
* @param {Function(link)} callback Function to be called on all links in the graph.
|
||||
* The function is passed one parameter: graph's link object.
|
||||
*
|
||||
* Link object contains at least the following fields:
|
||||
* fromId - node id where link starts;
|
||||
* toId - node id where link ends,
|
||||
* data - additional data passed to graph.addLink() method.
|
||||
*/
|
||||
forEachLink: forEachLink,
|
||||
|
||||
/**
|
||||
* Suspend all notifications about graph changes until
|
||||
* endUpdate is called.
|
||||
*/
|
||||
beginUpdate: enterModification,
|
||||
|
||||
/**
|
||||
* Resumes all notifications about graph changes and fires
|
||||
* graph 'changed' event in case there are any pending changes.
|
||||
*/
|
||||
endUpdate: exitModification,
|
||||
|
||||
/**
|
||||
* Removes all nodes and links from the graph.
|
||||
*/
|
||||
clear: clear,
|
||||
|
||||
/**
|
||||
* Detects whether there is a link between two nodes.
|
||||
* Operation complexity is O(n) where n - number of links of a node.
|
||||
* NOTE: this function is synonym for getLink()
|
||||
*
|
||||
* @returns link if there is one. null otherwise.
|
||||
*/
|
||||
hasLink: getLink,
|
||||
|
||||
/**
|
||||
* Detects whether there is a node with given id
|
||||
*
|
||||
* Operation complexity is O(1)
|
||||
* NOTE: this function is synonym for getNode()
|
||||
*
|
||||
* @returns node if there is one; Falsy value otherwise.
|
||||
*/
|
||||
hasNode: getNode,
|
||||
|
||||
/**
|
||||
* Gets an edge between two nodes.
|
||||
* Operation complexity is O(n) where n - number of links of a node.
|
||||
*
|
||||
* @param {string} fromId link start identifier
|
||||
* @param {string} toId link end identifier
|
||||
*
|
||||
* @returns link if there is one; undefined otherwise.
|
||||
*/
|
||||
getLink: getLink
|
||||
};
|
||||
|
||||
// this will add `on()` and `fire()` methods.
|
||||
eventify(graphPart);
|
||||
|
||||
monitorSubscribers();
|
||||
|
||||
return graphPart;
|
||||
|
||||
function monitorSubscribers() {
|
||||
var realOn = graphPart.on;
|
||||
|
||||
// replace real `on` with our temporary on, which will trigger change
|
||||
// modification monitoring:
|
||||
graphPart.on = on;
|
||||
|
||||
function on() {
|
||||
// now it's time to start tracking stuff:
|
||||
graphPart.beginUpdate = enterModification = enterModificationReal;
|
||||
graphPart.endUpdate = exitModification = exitModificationReal;
|
||||
recordLinkChange = recordLinkChangeReal;
|
||||
recordNodeChange = recordNodeChangeReal;
|
||||
|
||||
// this will replace current `on` method with real pub/sub from `eventify`.
|
||||
graphPart.on = realOn;
|
||||
// delegate to real `on` handler:
|
||||
return realOn.apply(graphPart, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
function recordLinkChangeReal(link, changeType) {
|
||||
changes.push({
|
||||
link: link,
|
||||
changeType: changeType
|
||||
});
|
||||
}
|
||||
|
||||
function recordNodeChangeReal(node, changeType) {
|
||||
changes.push({
|
||||
node: node,
|
||||
changeType: changeType
|
||||
});
|
||||
}
|
||||
|
||||
function addNode(nodeId, data) {
|
||||
if (nodeId === undefined) {
|
||||
throw new Error('Invalid node identifier');
|
||||
}
|
||||
|
||||
enterModification();
|
||||
|
||||
var node = getNode(nodeId);
|
||||
if (!node) {
|
||||
node = new Node(nodeId, data);
|
||||
recordNodeChange(node, 'add');
|
||||
} else {
|
||||
node.data = data;
|
||||
recordNodeChange(node, 'update');
|
||||
}
|
||||
|
||||
nodes.set(nodeId, node);
|
||||
|
||||
exitModification();
|
||||
return node;
|
||||
}
|
||||
|
||||
function getNode(nodeId) {
|
||||
return nodes.get(nodeId);
|
||||
}
|
||||
|
||||
function removeNode(nodeId) {
|
||||
var node = getNode(nodeId);
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enterModification();
|
||||
|
||||
var prevLinks = node.links;
|
||||
if (prevLinks) {
|
||||
prevLinks.forEach(removeLinkInstance);
|
||||
node.links = null;
|
||||
}
|
||||
|
||||
nodes.delete(nodeId);
|
||||
|
||||
recordNodeChange(node, 'remove');
|
||||
|
||||
exitModification();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function addLink(fromId, toId, data) {
|
||||
enterModification();
|
||||
|
||||
var fromNode = getNode(fromId) || addNode(fromId);
|
||||
var toNode = getNode(toId) || addNode(toId);
|
||||
|
||||
var link = createLink(fromId, toId, data);
|
||||
var isUpdate = links.has(link.id);
|
||||
|
||||
links.set(link.id, link);
|
||||
|
||||
// TODO: this is not cool. On large graphs potentially would consume more memory.
|
||||
addLinkToNode(fromNode, link);
|
||||
if (fromId !== toId) {
|
||||
// make sure we are not duplicating links for self-loops
|
||||
addLinkToNode(toNode, link);
|
||||
}
|
||||
|
||||
recordLinkChange(link, isUpdate ? 'update' : 'add');
|
||||
|
||||
exitModification();
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
function createSingleLink(fromId, toId, data) {
|
||||
var linkId = makeLinkId(fromId, toId);
|
||||
var prevLink = links.get(linkId);
|
||||
if (prevLink) {
|
||||
prevLink.data = data;
|
||||
return prevLink;
|
||||
}
|
||||
|
||||
return new Link(fromId, toId, data, linkId);
|
||||
}
|
||||
|
||||
function createUniqueLink(fromId, toId, data) {
|
||||
// TODO: Find a better/faster way to store multigraphs
|
||||
var linkId = makeLinkId(fromId, toId);
|
||||
var isMultiEdge = multiEdges.hasOwnProperty(linkId);
|
||||
if (isMultiEdge || getLink(fromId, toId)) {
|
||||
if (!isMultiEdge) {
|
||||
multiEdges[linkId] = 0;
|
||||
}
|
||||
var suffix = '@' + (++multiEdges[linkId]);
|
||||
linkId = makeLinkId(fromId + suffix, toId + suffix);
|
||||
}
|
||||
|
||||
return new Link(fromId, toId, data, linkId);
|
||||
}
|
||||
|
||||
function getNodeCount() {
|
||||
return nodes.size;
|
||||
}
|
||||
|
||||
function getLinkCount() {
|
||||
return links.size;
|
||||
}
|
||||
|
||||
function getLinks(nodeId) {
|
||||
var node = getNode(nodeId);
|
||||
return node ? node.links : null;
|
||||
}
|
||||
|
||||
function removeLink(link, otherId) {
|
||||
if (otherId !== undefined) {
|
||||
link = getLink(link, otherId);
|
||||
}
|
||||
return removeLinkInstance(link);
|
||||
}
|
||||
|
||||
function removeLinkInstance(link) {
|
||||
if (!link) {
|
||||
return false;
|
||||
}
|
||||
if (!links.get(link.id)) return false;
|
||||
|
||||
enterModification();
|
||||
|
||||
links.delete(link.id);
|
||||
|
||||
var fromNode = getNode(link.fromId);
|
||||
var toNode = getNode(link.toId);
|
||||
|
||||
if (fromNode) {
|
||||
fromNode.links.delete(link);
|
||||
}
|
||||
|
||||
if (toNode) {
|
||||
toNode.links.delete(link);
|
||||
}
|
||||
|
||||
recordLinkChange(link, 'remove');
|
||||
|
||||
exitModification();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLink(fromNodeId, toNodeId) {
|
||||
if (fromNodeId === undefined || toNodeId === undefined) return undefined;
|
||||
return links.get(makeLinkId(fromNodeId, toNodeId));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
enterModification();
|
||||
forEachNode(function(node) {
|
||||
removeNode(node.id);
|
||||
});
|
||||
exitModification();
|
||||
}
|
||||
|
||||
function forEachLink(callback) {
|
||||
if (typeof callback === 'function') {
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
if (callback(nextValue.value)) {
|
||||
return true; // client doesn't want to proceed. Return.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function forEachLinkedNode(nodeId, callback, oriented) {
|
||||
var node = getNode(nodeId);
|
||||
|
||||
if (node && node.links && typeof callback === 'function') {
|
||||
if (oriented) {
|
||||
return forEachOrientedLink(node.links, nodeId, callback);
|
||||
} else {
|
||||
return forEachNonOrientedLink(node.links, nodeId, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function forEachNonOrientedLink(links, nodeId, callback) {
|
||||
var quitFast;
|
||||
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
var link = nextValue.value;
|
||||
var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId;
|
||||
quitFast = callback(nodes.get(linkedNodeId), link);
|
||||
if (quitFast) {
|
||||
return true; // Client does not need more iterations. Break now.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function forEachOrientedLink(links, nodeId, callback) {
|
||||
var quitFast;
|
||||
var valuesIterator = links.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
var link = nextValue.value;
|
||||
if (link.fromId === nodeId) {
|
||||
quitFast = callback(nodes.get(link.toId), link);
|
||||
if (quitFast) {
|
||||
return true; // Client does not need more iterations. Break now.
|
||||
}
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
|
||||
// we will not fire anything until users of this library explicitly call `on()`
|
||||
// method.
|
||||
function noop() {}
|
||||
|
||||
// Enter, Exit modification allows bulk graph updates without firing events.
|
||||
function enterModificationReal() {
|
||||
suspendEvents += 1;
|
||||
}
|
||||
|
||||
function exitModificationReal() {
|
||||
suspendEvents -= 1;
|
||||
if (suspendEvents === 0 && changes.length > 0) {
|
||||
graphPart.fire('changed', changes);
|
||||
changes.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function forEachNode(callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
throw new Error('Function is expected to iterate over graph nodes. You passed ' + callback);
|
||||
}
|
||||
|
||||
var valuesIterator = nodes.values();
|
||||
var nextValue = valuesIterator.next();
|
||||
while (!nextValue.done) {
|
||||
if (callback(nextValue.value)) {
|
||||
return true; // client doesn't want to proceed. Return.
|
||||
}
|
||||
nextValue = valuesIterator.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure to represent node;
|
||||
*/
|
||||
function Node(id, data) {
|
||||
this.id = id;
|
||||
this.links = null;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
function addLinkToNode(node, link) {
|
||||
if (node.links) {
|
||||
node.links.add(link);
|
||||
} else {
|
||||
node.links = new Set([link]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure to represent links;
|
||||
*/
|
||||
function Link(fromId, toId, data, id) {
|
||||
this.fromId = fromId;
|
||||
this.toId = toId;
|
||||
this.data = data;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
function makeLinkId(fromId, toId) {
|
||||
return fromId.toString() + '👉 ' + toId.toString();
|
||||
}
|
||||
45
VISUALIZACION/node_modules/ngraph.graph/package.json
generated
vendored
Executable file
45
VISUALIZACION/node_modules/ngraph.graph/package.json
generated
vendored
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "ngraph.graph",
|
||||
"version": "20.0.1",
|
||||
"description": "graph data structure",
|
||||
"main": "index.js",
|
||||
"jsdelivr": "dist/ngraph.graph.min.js",
|
||||
"unpkg": "dist/ngraph.graph.min.js",
|
||||
"scripts": {
|
||||
"build": "browserify index.js -s createGraph -o dist/ngraph.graph.js && uglifyjs dist/ngraph.graph.js -o dist/ngraph.graph.min.js",
|
||||
"test": "tap --branches=90 --lines=90 --statements=90 --functions=90 test/*.js",
|
||||
"cover": "tap --branches=80 --lines=80 --statements=80 --functions=80 --coverage-report=html --no-browser test/*.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anvaka/ngraph.graph.git"
|
||||
},
|
||||
"keywords": [
|
||||
"graph",
|
||||
"graph theory",
|
||||
"edge",
|
||||
"vertex",
|
||||
"node",
|
||||
"network",
|
||||
"connection",
|
||||
"ngraph",
|
||||
"vivagraph",
|
||||
"ngraphjs"
|
||||
],
|
||||
"author": "Andrei Kashcha",
|
||||
"license": "BSD-3-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/anvaka/ngraph.graph/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"browserify": "^17.0.0",
|
||||
"eslint": "^7.25.0",
|
||||
"ngraph.random": "^1.1.0",
|
||||
"tap": "^16.0.1",
|
||||
"uglify-js": "^3.13.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"ngraph.events": "^1.2.1"
|
||||
}
|
||||
}
|
||||
53
VISUALIZACION/node_modules/ngraph.graph/perf/edge-iteration.js
generated
vendored
Executable file
53
VISUALIZACION/node_modules/ngraph.graph/perf/edge-iteration.js
generated
vendored
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
var createGraph = require('../');
|
||||
var randomAPI = require('ngraph.random').random;
|
||||
var Benchmark = require('benchmark');
|
||||
var suite = new Benchmark.Suite;
|
||||
|
||||
var edgeIterationSumWeight = 0;
|
||||
var edgeIterationMultigraph = 0;
|
||||
|
||||
suite.add('Edge iteration', function() {
|
||||
var graph = createGraph();
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 1000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
edgeIterationSumWeight = 0;
|
||||
for (var i = 0; i < 100; ++i) {
|
||||
graph.forEachLink(addUpWeight);
|
||||
}
|
||||
function addUpWeight(link) {
|
||||
edgeIterationSumWeight += link.data;
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Edge iteration for multigraph', function() {
|
||||
var graph = createGraph({multigraph: true});
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 1000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
edgeIterationMultigraph = 0;
|
||||
for (var i = 0; i < 100; ++i) {
|
||||
graph.forEachLink(addUpWeight);
|
||||
}
|
||||
function addUpWeight(link) {
|
||||
edgeIterationMultigraph += link.data;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
suite.on('cycle', function(event) {
|
||||
console.log(String(event.target));
|
||||
console.log('edge iteration sum weight', edgeIterationSumWeight);
|
||||
console.log('edge iteration multigraph weight', edgeIterationMultigraph);
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
|
||||
120
VISUALIZACION/node_modules/ngraph.graph/perf/graph-construction.js
generated
vendored
Executable file
120
VISUALIZACION/node_modules/ngraph.graph/perf/graph-construction.js
generated
vendored
Executable file
|
|
@ -0,0 +1,120 @@
|
|||
var createGraph = require('../');
|
||||
var randomAPI = require('ngraph.random').random;
|
||||
var Benchmark = require('benchmark');
|
||||
var suite = new Benchmark.Suite;
|
||||
|
||||
suite.add('Adding 5,000 edges', function() {
|
||||
var graph = createGraph();
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
graph.addLink(i, i - 1, i);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Adding 5,000 multigraph edges', function() {
|
||||
var graph = createGraph({multigraph: true});
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
graph.addLink(i, i - 1, i);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Adding 5,000 random edges', function() {
|
||||
var graph = createGraph();
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Adding 5,000 random edges to multigraph', function() {
|
||||
var graph = createGraph({multigraph: true});
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Adding 5,000 random edges and randomly removing them', function() {
|
||||
var graph = createGraph();
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
|
||||
for(var i = 1; i < 15000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.removeLink(fromId, toId);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Adding 5,000 random edges to multigraph and randomly removing them', function() {
|
||||
var graph = createGraph({multigraph: true});
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 15000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.removeLink(fromId, toId);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Removing all edges one by one from 5k graph', function() {
|
||||
var graph = createGraph();
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
var links = [];
|
||||
|
||||
graph.forEachLink(function (link) {
|
||||
links.push(link);
|
||||
});
|
||||
|
||||
for (var i = 0; i < links.length; ++i) {
|
||||
graph.removeLink(links[i]);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add('Removing all edges one by one from 5k multigraph graph', function() {
|
||||
var graph = createGraph({multigraph: true});
|
||||
var random = randomAPI(42);
|
||||
var maxEdgeId = 10000000;
|
||||
for(var i = 1; i < 5000; ++i) {
|
||||
var fromId = random.next(maxEdgeId);
|
||||
var toId = random.next(maxEdgeId);
|
||||
graph.addLink(fromId, toId, i);
|
||||
}
|
||||
var links = [];
|
||||
|
||||
graph.forEachLink(function (link) {
|
||||
links.push(link);
|
||||
});
|
||||
|
||||
for (var i = 0; i < links.length; ++i) {
|
||||
graph.removeLink(links[i]);
|
||||
}
|
||||
});
|
||||
|
||||
suite.on('cycle', function(event) {
|
||||
console.log(String(event.target));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
31
VISUALIZACION/node_modules/ngraph.graph/perf/node-iteration.js
generated
vendored
Executable file
31
VISUALIZACION/node_modules/ngraph.graph/perf/node-iteration.js
generated
vendored
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
var Benchmark = require('benchmark');
|
||||
|
||||
var createGraph = require('../'),
|
||||
numberOfNodes = 10000;
|
||||
|
||||
var suite = new Benchmark.Suite();
|
||||
|
||||
var graph = createGraph();
|
||||
for (var i = 0; i < numberOfNodes; ++i) {
|
||||
graph.addNode('hello' + i, i);
|
||||
}
|
||||
|
||||
var sum = 0;
|
||||
|
||||
// add tests
|
||||
suite.add('forEachNode', function() {
|
||||
var localSum = 0;
|
||||
graph.forEachNode(function (node) {
|
||||
localSum += node.data;
|
||||
});
|
||||
sum = localSum;
|
||||
})
|
||||
.on('cycle', function(event) {
|
||||
console.log(String(event.target));
|
||||
})
|
||||
.on('complete', function() {
|
||||
console.log(sum);
|
||||
console.log('Fastest is ' + this.filter('fastest').map("name"));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
20
VISUALIZACION/node_modules/ngraph.graph/perf/snapshot.txt
generated
vendored
Executable file
20
VISUALIZACION/node_modules/ngraph.graph/perf/snapshot.txt
generated
vendored
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
Node v12.4.0
|
||||
|
||||
> node perf/edge-iteration.js
|
||||
Edge iteration x 626 ops/sec ±1.36% (86 runs sampled)
|
||||
Edge iteration for multigraph x 568 ops/sec ±0.97% (87 runs sampled)
|
||||
|
||||
» node perf/graph-construction.js
|
||||
Adding 5,000 edges x 580 ops/sec ±1.40% (86 runs sampled)
|
||||
Adding 5,000 multigraph edges x 432 ops/sec ±1.08% (82 runs sampled)
|
||||
Adding 5,000 random edges x 219 ops/sec ±0.92% (81 runs sampled)
|
||||
Adding 5,000 random edges to multigraph x 179 ops/sec ±0.93% (78 runs sampled)
|
||||
Adding 5,000 random edges and randomly removing them x 7.83 ops/sec ±4.33% (24 runs sampled)
|
||||
Adding 5,000 random edges to multigraph and randomly removing them x 5.97 ops/sec ±4.07% (20 runs sampled)
|
||||
Removing all edges one by one from 5k graph x 126 ops/sec ±1.20% (76 runs sampled)
|
||||
Removing all edges one by one from 5k multigraph graph x 97.78 ops/sec ±4.15% (69 runs sampled)
|
||||
|
||||
» node perf/node-iteration.js
|
||||
graphWithOutMap x 572 ops/sec ±3.64% (71 runs sampled)
|
||||
graphWithMap x 5,744 ops/sec ±6.48% (69 runs sampled)
|
||||
Fastest is graphWithMap
|
||||
385
VISUALIZACION/node_modules/ngraph.graph/test/construction.js
generated
vendored
Executable file
385
VISUALIZACION/node_modules/ngraph.graph/test/construction.js
generated
vendored
Executable file
|
|
@ -0,0 +1,385 @@
|
|||
var test = require('tap').test,
|
||||
createGraph = require('..');
|
||||
|
||||
test('add node adds node', function(t) {
|
||||
var graph = createGraph();
|
||||
var customData = '31337';
|
||||
|
||||
var node = graph.addNode(1, customData);
|
||||
|
||||
t.equal(graph.getNodesCount(), 1, 'exactly one node');
|
||||
t.equal(graph.getLinksCount(), 0, 'no links');
|
||||
t.equal(graph.getNode(1), node, 'invalid node returned by addNode (or getNode)');
|
||||
t.equal(node.data, customData, 'data was not set properly');
|
||||
t.equal(node.id, 1, 'node id was not set properly');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('hasNode checks node', function(t) {
|
||||
var graph = createGraph();
|
||||
|
||||
graph.addNode(1);
|
||||
|
||||
t.ok(graph.hasNode(1), 'node is there');
|
||||
t.notOk(graph.hasNode(2), 'should not be here');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('hasLink checks links', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
var link12 = graph.hasLink(1, 2);
|
||||
t.ok(link12.fromId === 1 && link12.toId === 2, 'link is found');
|
||||
|
||||
// this is somewhat doubtful... has link will return null, but forEachLinkedNode
|
||||
// will actually iterate over this link. Not sure how to have consistency here
|
||||
// for now documenting behavior in the test:
|
||||
var noLink = graph.hasLink(2, 1);
|
||||
t.notOk(noLink, 'hasLink is always directional');
|
||||
|
||||
var obviousNo = graph.hasLink();
|
||||
t.notOk(obviousNo, 'No links there');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('hasLink is the same as getLink', function (t) {
|
||||
var graph = createGraph();
|
||||
|
||||
t.equal(graph.getLink, graph.hasLink, 'hasLink is synonym for getLink');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it considers uniqueLinkId as multigraph', function (t) {
|
||||
var options = {uniqueLinkId: true};
|
||||
createGraph(options);
|
||||
t.equal(options.multigraph, true, 'multigraph is set');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it throw if no node id is passed', function(t) {
|
||||
var graph = createGraph();
|
||||
t.throws(function() {
|
||||
graph.addNode(); // no id, should throw
|
||||
}, 'It throws on undefined node');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it fires update event when node is updated', function(t) {
|
||||
t.plan(3);
|
||||
var graph = createGraph();
|
||||
graph.addNode(1, 'hello');
|
||||
graph.on('changed', checkChangedEvent);
|
||||
graph.addNode(1, 'world');
|
||||
|
||||
t.end();
|
||||
|
||||
function checkChangedEvent(changes) {
|
||||
var change = changes[0];
|
||||
t.equal(change.node.id, 1);
|
||||
t.equal(change.node.data, 'world');
|
||||
t.equal(change.changeType, 'update');
|
||||
}
|
||||
});
|
||||
|
||||
test('it can add node with id similar to reserved prototype property', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addNode('constructor');
|
||||
graph.addLink('watch', 'constructor');
|
||||
|
||||
var iterated = 0;
|
||||
graph.forEachNode(function() {
|
||||
iterated += 1;
|
||||
});
|
||||
|
||||
t.ok(graph.hasLink('watch', 'constructor'));
|
||||
t.equal(graph.getLinksCount(), 1, 'one link');
|
||||
t.equal(iterated, 2, 'has two nodes');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('add link adds link', function(t) {
|
||||
var graph = createGraph();
|
||||
|
||||
var link = graph.addLink(1, 2),
|
||||
firstNodeLinks = graph.getLinks(1),
|
||||
secondNodeLinks = graph.getLinks(2);
|
||||
|
||||
t.equal(graph.getNodesCount(), 2, 'Two nodes');
|
||||
t.equal(graph.getLinksCount(), 1, 'One link');
|
||||
t.equal(firstNodeLinks.size, 1, 'number of links of the first node is wrong');
|
||||
t.equal(secondNodeLinks.size, 1, 'number of links of the second node is wrong');
|
||||
t.equal(link, Array.from(firstNodeLinks)[0], 'invalid link in the first node');
|
||||
t.equal(link, Array.from(secondNodeLinks)[0], 'invalid link in the second node');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can add multi-edges', function (t) {
|
||||
t.plan(5);
|
||||
var graph = createGraph({multigraph: true});
|
||||
graph.addLink(1, 2, 'first');
|
||||
graph.addLink(1, 2, 'second');
|
||||
graph.addLink(1, 2, 'third');
|
||||
|
||||
t.equal(graph.getLinksCount(), 3, 'three links!');
|
||||
t.equal(graph.getNodesCount(), 2, 'Two nodes');
|
||||
|
||||
graph.forEachLinkedNode(1, function (otherNode, link) {
|
||||
t.ok(link.data === 'first' || link.data === 'second' || link.data === 'third', 'Link is here');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can produce unique link ids', function (t) {
|
||||
// eslint-disable-next-line no-shadow
|
||||
t.test('by default links are de-duped', function (t) {
|
||||
var seen = {};
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2, 'first');
|
||||
graph.addLink(1, 2, 'second');
|
||||
graph.addLink(1, 2, 'third');
|
||||
graph.forEachLink(verifyLinksAreNotUnique);
|
||||
|
||||
var link = graph.getLink(1, 2);
|
||||
t.equal(seen[link.id], 1, 'Link 1->2 seen 1 time');
|
||||
t.equal(link.data, 'third', 'Last link wins');
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function verifyLinksAreNotUnique(link) {
|
||||
seen[link.id] = (seen[link.id] || 0) + 1;
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
t.test('You can create multigraph', function (t) {
|
||||
var graph = createGraph({
|
||||
multigraph: true
|
||||
});
|
||||
|
||||
var seen = {};
|
||||
graph.addLink(1, 2, 'first');
|
||||
graph.addLink(1, 2, 'second');
|
||||
graph.addLink(1, 2, 'third');
|
||||
graph.forEachLink(verifyLinkIsUnique);
|
||||
t.equal(graph.getLinksCount(), 3, 'All three links are here');
|
||||
t.end();
|
||||
|
||||
function verifyLinkIsUnique(link) {
|
||||
t.notOk(seen[link.id], link.id + ' is unique');
|
||||
seen[link.id] = true;
|
||||
}
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('add one node fires changed event', function(t) {
|
||||
t.plan(3);
|
||||
var graph = createGraph();
|
||||
var testNodeId = 'hello world';
|
||||
|
||||
graph.on('changed', function(changes) {
|
||||
t.ok(changes && changes.length === 1, "Only one change should be recorded");
|
||||
t.equal(changes[0].node.id, testNodeId, "Wrong node change notification");
|
||||
t.equal(changes[0].changeType, 'add', "Add change type expected.");
|
||||
});
|
||||
|
||||
graph.addNode(testNodeId);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('add link fires changed event', function(t) {
|
||||
t.plan(4);
|
||||
var graph = createGraph();
|
||||
var fromId = 1,
|
||||
toId = 2;
|
||||
|
||||
graph.on('changed', function(changes) {
|
||||
t.ok(changes && changes.length === 3, "Three change should be recorded: node, node and link");
|
||||
t.equal(changes[2].link.fromId, fromId, "Wrong link from Id");
|
||||
t.equal(changes[2].link.toId, toId, "Wrong link toId");
|
||||
t.equal(changes[2].changeType, 'add', "Add change type expected.");
|
||||
});
|
||||
|
||||
graph.addLink(fromId, toId);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove isolated node remove it', function(t) {
|
||||
var graph = createGraph();
|
||||
|
||||
graph.addNode(1);
|
||||
graph.removeNode(1);
|
||||
|
||||
t.equal(graph.getNodesCount(), 0, 'Remove operation failed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('supports plural methods', function(t) {
|
||||
var graph = createGraph();
|
||||
|
||||
graph.addLink(1, 2);
|
||||
|
||||
t.equal(graph.getNodeCount(), 2, 'two nodes are there');
|
||||
t.equal(graph.getLinkCount(), 1, 'two nodes are there');
|
||||
|
||||
t.equal(graph.getNodesCount(), 2, 'two nodes are there');
|
||||
t.equal(graph.getLinksCount(), 1, 'two nodes are there');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove link removes it', function(t) {
|
||||
t.plan(5);
|
||||
|
||||
var graph = createGraph();
|
||||
var link = graph.addLink(1, 2);
|
||||
|
||||
var linkIsRemoved = graph.removeLink(link);
|
||||
|
||||
t.equal(graph.getNodesCount(), 2, 'remove link should not remove nodes');
|
||||
t.equal(graph.getLinksCount(), 0, 'No Links');
|
||||
t.equal(graph.getLinks(1).size, 0, 'link should be removed from the first node');
|
||||
t.equal(graph.getLinks(2).size, 0, 'link should be removed from the second node');
|
||||
t.ok(linkIsRemoved, 'Link removal is successful');
|
||||
|
||||
graph.forEachLink(function() {
|
||||
test.ok(false, 'No links should be in graph');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can remove link by from/to ids', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var linkIsRemoved = graph.removeLink(1, 2);
|
||||
|
||||
t.equal(graph.getNodesCount(), 2, 'remove link should not remove nodes');
|
||||
t.equal(graph.getLinksCount(), 0, 'No Links');
|
||||
t.equal(graph.getLinks(1).size, 0, 'link should be removed from the first node');
|
||||
t.equal(graph.getLinks(2).size, 0, 'link should be removed from the second node');
|
||||
t.ok(linkIsRemoved, 'Link removal is successful');
|
||||
|
||||
graph.forEachLink(function() {
|
||||
test.ok(false, 'No links should be in graph');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove link returns false if no link removed', function (t) {
|
||||
var graph = createGraph();
|
||||
|
||||
graph.addLink(1, 2);
|
||||
var result = graph.removeLink('blah');
|
||||
t.notOk(result, 'Link is not removed');
|
||||
|
||||
var alsoNo = graph.removeLink();
|
||||
t.notOk(alsoNo, 'No link - no removal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove isolated node fires changed event', function(t) {
|
||||
t.plan(4);
|
||||
var graph = createGraph();
|
||||
graph.addNode(1);
|
||||
|
||||
graph.on('changed', function(changes) {
|
||||
t.ok(changes && changes.length === 1, "One change should be recorded: node removed");
|
||||
t.equal(changes[0].node.id, 1, "Wrong node Id");
|
||||
t.equal(changes[0].changeType, 'remove', "'remove' change type expected.");
|
||||
});
|
||||
|
||||
var result = graph.removeNode(1);
|
||||
t.ok(result, 'node is removed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove link fires changed event', function(t) {
|
||||
t.plan(3);
|
||||
var graph = createGraph();
|
||||
var link = graph.addLink(1, 2);
|
||||
|
||||
graph.on('changed', function(changes) {
|
||||
t.ok(changes && changes.length === 1, "One change should be recorded: link removed");
|
||||
t.equal(changes[0].link, link, "Wrong link removed");
|
||||
t.equal(changes[0].changeType, 'remove', "'remove' change type expected.");
|
||||
});
|
||||
|
||||
graph.removeLink(link);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove linked node fires changed event', function(t) {
|
||||
t.plan(5);
|
||||
var graph = createGraph(),
|
||||
link = graph.addLink(1, 2),
|
||||
nodeIdToRemove = 1;
|
||||
|
||||
graph.on('changed', function(changes) {
|
||||
t.ok(changes && changes.length === 2, "Two changes should be recorded: link and node removed");
|
||||
t.equal(changes[0].link, link, "Wrong link removed");
|
||||
t.equal(changes[0].changeType, 'remove', "'remove' change type expected.");
|
||||
t.equal(changes[1].node.id, nodeIdToRemove, "Wrong node removed");
|
||||
t.equal(changes[1].changeType, 'remove', "'remove' change type expected.");
|
||||
});
|
||||
|
||||
graph.removeNode(nodeIdToRemove);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove node with many links removes them all', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(1, 3);
|
||||
|
||||
graph.removeNode(1);
|
||||
|
||||
t.equal(graph.getNodesCount(), 2, 'remove link should remove one node only');
|
||||
t.equal(graph.getLinks(1), null, 'link should be removed from the first node');
|
||||
t.equal(graph.getLinks(2).size, 0, 'link should be removed from the second node');
|
||||
t.equal(graph.getLinks(3).size, 0, 'link should be removed from the third node');
|
||||
graph.forEachLink(function() {
|
||||
test.ok(false, 'No links should be in graph');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('remove node returns false when no node removed', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addNode('hello');
|
||||
var result = graph.removeNode('blah');
|
||||
t.notOk(result, 'No "blah" node');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('clearGraph clears graph', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addNode('hello');
|
||||
graph.addLink(1, 2);
|
||||
graph.clear();
|
||||
|
||||
t.equal(graph.getNodesCount(), 0, 'No nodes');
|
||||
t.equal(graph.getLinksCount(), 0, 'No links');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('beginUpdate holds events', function(t) {
|
||||
var graph = createGraph();
|
||||
var changedCount = 0;
|
||||
graph.on('changed', function () {
|
||||
changedCount += 1;
|
||||
});
|
||||
graph.beginUpdate();
|
||||
graph.addNode(1);
|
||||
t.equal(changedCount, 0, 'Begin update freezes updates until `endUpdate()`');
|
||||
graph.endUpdate();
|
||||
t.equal(changedCount, 1, 'event is fired only after endUpdate()');
|
||||
t.end();
|
||||
});
|
||||
25
VISUALIZACION/node_modules/ngraph.graph/test/findConnectedComponents.js
generated
vendored
Executable file
25
VISUALIZACION/node_modules/ngraph.graph/test/findConnectedComponents.js
generated
vendored
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
var test = require('tap').test;
|
||||
var findConnectedComponents = require('../examples/findConnectedComponents');
|
||||
var createGraph = require('..');
|
||||
|
||||
test('can find connected components', function(t) {
|
||||
// our graph has three components
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(2, 3);
|
||||
|
||||
graph.addLink(5, 6);
|
||||
graph.addNode(8);
|
||||
// let's add loop:
|
||||
graph.addLink(9, 9);
|
||||
|
||||
// lets verify it:
|
||||
var components = findConnectedComponents(graph);
|
||||
t.equal(components.length, 4, 'all components found');
|
||||
t.same(components[0], [1, 2, 3], 'first component found');
|
||||
t.same(components[1], [5, 6], 'second component found');
|
||||
t.same(components[2], [8], 'third component found');
|
||||
t.same(components[3], [9], 'fourth component found');
|
||||
|
||||
t.end();
|
||||
});
|
||||
158
VISUALIZACION/node_modules/ngraph.graph/test/iteration.js
generated
vendored
Executable file
158
VISUALIZACION/node_modules/ngraph.graph/test/iteration.js
generated
vendored
Executable file
|
|
@ -0,0 +1,158 @@
|
|||
var test = require('tap').test,
|
||||
createGraph = require('..');
|
||||
|
||||
test('forEachLinkedNode respects orientation', function(t) {
|
||||
t.plan(3);
|
||||
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(2, 3);
|
||||
var oriented = true;
|
||||
graph.forEachLinkedNode(2, function(node, link) {
|
||||
t.ok(link.toId === 3, 'Only 3 is connected to node 2, when traversal is oriented');
|
||||
}, oriented);
|
||||
|
||||
graph.forEachLinkedNode(2, function(node, link) {
|
||||
t.ok(link.toId === 3 || link.toId === 2, 'both incoming and outgoing links are visited');
|
||||
}, !oriented);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLinkedNode handles self-loops', function(t) {
|
||||
t.plan(1);
|
||||
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 1);
|
||||
// we should visit exactly one time
|
||||
graph.forEachLinkedNode(1, function(node, link) {
|
||||
t.ok(link.fromId === 1 && link.toId === 1, 'Link 1 is visited once');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLinkedNode will not crash on invalid node id', function(t) {
|
||||
t.plan(0);
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.forEachLinkedNode(3, function() {
|
||||
t.notOk(true, 'This code will never be executed');
|
||||
});
|
||||
});
|
||||
|
||||
test('forEachLinkedNode can quit fast for oriented graphs', function(t) {
|
||||
var graph = createGraph();
|
||||
var oriented = true;
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(1, 3);
|
||||
|
||||
var visited = 0;
|
||||
graph.forEachLinkedNode(1, function() {
|
||||
t.ok(true, 'Visited first link');
|
||||
visited += 1;
|
||||
return true; // We want to stop right now!
|
||||
}, oriented);
|
||||
t.equal(visited, 1, 'One link is visited');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLinkedNode can quit fast for non-oriented graphs', function(t) {
|
||||
var graph = createGraph();
|
||||
var oriented = false;
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(1, 3);
|
||||
|
||||
var visited = 0;
|
||||
graph.forEachLinkedNode(1, function() {
|
||||
t.ok(true, 'Visited first link');
|
||||
visited += 1;
|
||||
return true; // We want to stop right now!
|
||||
}, oriented);
|
||||
|
||||
t.equal(visited, 1, 'One link is visited');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLinkedNode returns quitFast flag', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(1, 3);
|
||||
|
||||
var fastQuit = graph.forEachLinkedNode(1, function() {
|
||||
return true; // Stop right now.
|
||||
});
|
||||
|
||||
t.ok(fastQuit, 'Fast quit triggered when callback opted out');
|
||||
|
||||
var notSoFast = graph.forEachLinkedNode(1, function() { });
|
||||
t.notOk(notSoFast, 'Fast quit is not triggered when all elements visited');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLink visits each link', function(t) {
|
||||
t.plan(1);
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.forEachLink(function(link) {
|
||||
t.ok(link.fromId === 1 && link.toId === 2, 'Link is here');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLink will not crash on empty callback', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.forEachLink(); // didn't pass callback, no worries.
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachNode will stop when requested', function(t) {
|
||||
t.plan(1);
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.forEachNode(function(node) {
|
||||
t.equal(node.id, 1, 'We visit only one node');
|
||||
return true; // we want to stop now!
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachNode returns fastQuit', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
var fastQuit = graph.forEachNode(function(node) {
|
||||
t.equal(node.id, 1, 'We visit only one node');
|
||||
return true; // we want to stop now!
|
||||
}); // no callback? No worries
|
||||
|
||||
t.ok(fastQuit, 'fastQuit is set when callback opted out');
|
||||
|
||||
var notSoFast = graph.forEachNode(function() { });
|
||||
t.notOk(notSoFast, 'fastQuit is not set when all nodes visited');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachNode throws when callback is not a function', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
t.throws(function() {
|
||||
graph.forEachNode('not a function');
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('forEachLink stops when requested', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
graph.addLink(2, 3);
|
||||
|
||||
var visitCount = 0;
|
||||
graph.forEachLink(function() {
|
||||
visitCount += 1;
|
||||
return true;
|
||||
});
|
||||
t.equal(visitCount, 1, 'only one link visited');
|
||||
t.end();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue