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.forcelayout/.eslintignore
generated
vendored
Executable file
2
VISUALIZACION/node_modules/ngraph.forcelayout/.eslintignore
generated
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
dist
|
||||
demo/dist
|
||||
18
VISUALIZACION/node_modules/ngraph.forcelayout/.eslintrc.json
generated
vendored
Executable file
18
VISUALIZACION/node_modules/ngraph.forcelayout/.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.forcelayout/.github/workflows/tests.yaml
generated
vendored
Executable file
26
VISUALIZACION/node_modules/ngraph.forcelayout/.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
|
||||
28
VISUALIZACION/node_modules/ngraph.forcelayout/Changelog.md
generated
vendored
Executable file
28
VISUALIZACION/node_modules/ngraph.forcelayout/Changelog.md
generated
vendored
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
# v3.0
|
||||
|
||||
The following physics settings are renamed:
|
||||
|
||||
* `springCoeff -> springCoefficient`
|
||||
* `dragCoeff -> dragCoefficient`
|
||||
|
||||
A new interactive demo is added to the library: http://anvaka.github.io/ngraph.forcelayout/.
|
||||
|
||||
Also the library is now available for consumption via CDN.
|
||||
|
||||
# v2.0
|
||||
|
||||
Major rework on how library treats dimensions of space. Previous versions of the library
|
||||
required concrete implementation for the given space (e.g. [3d](https://github.com/anvaka/ngraph.forcelayout3d), [N-d](https://github.com/anvaka/ngraph.forcelayout.nd)).
|
||||
|
||||
With version 2.0, `ngraph.forcealyout` generates code on the fly to support layout in the
|
||||
given dimension. This comes at no extra performance cost to the consumer.
|
||||
|
||||
Second big change, is that custom forces can now be added to the library via `simulator.addForce()`
|
||||
`simulator.removeForce()` api.
|
||||
|
||||
With this change, the old `physicsSimulator` factory methods became obsolete and were removed
|
||||
(like `settings.createQuadTree`, `settings,createBounds`, [etc.](https://github.com/anvaka/ngraph.forcelayout/blob/d2eea4a5dd6913fb0002787d91d211916b56ba01/lib/physicsSimulator.js#L50-L55) )
|
||||
|
||||
# 0.xx - V1.0
|
||||
|
||||
This was original implementation of the ngraph.forcelayout.
|
||||
27
VISUALIZACION/node_modules/ngraph.forcelayout/LICENSE
generated
vendored
Executable file
27
VISUALIZACION/node_modules/ngraph.forcelayout/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.
|
||||
240
VISUALIZACION/node_modules/ngraph.forcelayout/README.md
generated
vendored
Executable file
240
VISUALIZACION/node_modules/ngraph.forcelayout/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,240 @@
|
|||
# ngraph.forcelayout
|
||||
|
||||
[](https://github.com/anvaka/ngraph.forcelayout/actions/workflows/tests.yaml)
|
||||
|
||||
This is a [force directed](http://en.wikipedia.org/wiki/Force-directed_graph_drawing) graph layout algorithm,
|
||||
that works in any dimension (2D, 3D, and above).
|
||||
|
||||
The library uses quad tree to speed up computation of long-distance forces.
|
||||
|
||||
This repository is part of [ngraph family](https://github.com/anvaka/ngraph), and operates on
|
||||
[`ngraph.graph`](https://github.com/anvaka/ngraph.graph) data structure.
|
||||
|
||||
# API
|
||||
|
||||
All force directed algorithms are iterative. We need to perform multiple iterations of an algorithm,
|
||||
before graph starts looking good:
|
||||
|
||||
``` js
|
||||
// graph is an instance of `ngraph.graph` object.
|
||||
var createLayout = require('ngraph.forcelayout');
|
||||
var layout = createLayout(graph);
|
||||
for (var i = 0; i < ITERATIONS_COUNT; ++i) {
|
||||
layout.step();
|
||||
}
|
||||
|
||||
// now we can ask layout where each node/link is best positioned:
|
||||
graph.forEachNode(function(node) {
|
||||
console.log(layout.getNodePosition(node.id));
|
||||
// Node position is pair of x,y coordinates:
|
||||
// {x: ... , y: ... }
|
||||
});
|
||||
|
||||
graph.forEachLink(function(link) {
|
||||
console.log(layout.getLinkPosition(link.id));
|
||||
// link position is a pair of two positions:
|
||||
// {
|
||||
// from: {x: ..., y: ...},
|
||||
// to: {x: ..., y: ...}
|
||||
// }
|
||||
});
|
||||
```
|
||||
|
||||
If you'd like to perform graph layout in space with more than two dimensions, just add one
|
||||
argument to this line:
|
||||
|
||||
``` js
|
||||
let layout = createLayout(graph, {dimensions: 3}); // 3D layout
|
||||
let nodePosition = layout.getNodePosition(nodeId); // has {x, y, z} attributes
|
||||
```
|
||||
|
||||
Even higher dimensions are not a problem for this library:
|
||||
|
||||
``` js
|
||||
let layout = createLayout(graph, {dimensions: 6}); // 6D layout
|
||||
// Every layout with more than 3 dimensions, say N, gets additional attributes:
|
||||
// c4, c5, ... cN
|
||||
let nodePosition = layout.getNodePosition(nodeId); // has {x, y, z, c4, c5, c6}
|
||||
```
|
||||
|
||||
Note: Higher dimensionality comes at exponential cost of memory for every added
|
||||
dimension. See a performance section below for more details.
|
||||
|
||||
## Node position and object reuse
|
||||
|
||||
Recently immutability became a ruling principle of javascript world. This library
|
||||
doesn't follow the rules, and results of `getNodePosition()`/`getLinkPosition()` will be
|
||||
always the same for the same node. This is true:
|
||||
|
||||
``` js
|
||||
layout.getNodePosition(1) === layout.getNodePosition(1);
|
||||
```
|
||||
|
||||
Reason for this is performance. If you are interested in storing positions
|
||||
somewhere else, you can do it and they still will be updated after each force
|
||||
directed layout iteration.
|
||||
|
||||
## "Pin" node and initial position
|
||||
|
||||
Sometimes it's desirable to tell layout algorithm not to move certain nodes.
|
||||
This can be done with `pinNode()` method:
|
||||
|
||||
``` js
|
||||
var nodeToPin = graph.getNode(nodeId);
|
||||
layout.pinNode(nodeToPin, true); // now layout will not move this node
|
||||
```
|
||||
|
||||
If you want to check whether node is pinned or not you can use `isNodePinned()`
|
||||
method. Here is an example how to toggle node pinning, without knowing it's
|
||||
original state:
|
||||
|
||||
``` js
|
||||
var node = graph.getNode(nodeId);
|
||||
layout.pinNode(node, !layout.isNodePinned(node)); // toggle it
|
||||
```
|
||||
|
||||
What if you still want to move your node according to some external factor (e.g.
|
||||
you have initial positions, or user drags pinned node)? To do this, call
|
||||
`setNodePosition()` method:
|
||||
|
||||
``` js
|
||||
layout.setNodePosition(nodeId, x, y);
|
||||
```
|
||||
|
||||
## Monitoring changes
|
||||
|
||||
Like many other algorithms in `ngraph` family, force layout monitors graph changes
|
||||
via [graph events](https://github.com/anvaka/ngraph.graph#listening-to-events).
|
||||
It keeps layout up to date whenever graph changes:
|
||||
|
||||
``` js
|
||||
var graph = require('ngraph.graph')(); // empty graph
|
||||
var layout = require('ngraph.layout')(graph); // layout of empty graph
|
||||
|
||||
graph.addLink(1, 2); // create node 1 and 2, and make link between them
|
||||
layout.getNodePosition(1); // returns position.
|
||||
```
|
||||
|
||||
If you want to stop monitoring graph events, call `dispose()` method:
|
||||
|
||||
``` js
|
||||
layout.dispose();
|
||||
```
|
||||
|
||||
## Physics Simulator
|
||||
|
||||
Simulator calculates forces acting on each body and then deduces their position via Newton's law.
|
||||
There are three major forces in the system:
|
||||
|
||||
1. Spring force keeps connected nodes together via [Hooke's law](http://en.wikipedia.org/wiki/Hooke's_law)
|
||||
2. Each body repels each other via [Coulomb's law](http://en.wikipedia.org/wiki/Coulomb's_law)
|
||||
3. The drag force slows the entire simulation down, helping with convergence.
|
||||
|
||||
Body forces are calculated in `n*lg(n)` time with help of Barnes-Hut algorithm implemented with quadtree.
|
||||
|
||||
``` js
|
||||
// Configure
|
||||
var physicsSettings = {
|
||||
timeStep: 0.5,
|
||||
dimensions: 2,
|
||||
gravity: -12,
|
||||
theta: 0.8,
|
||||
springLength: 10,
|
||||
springCoefficient: 0.8,
|
||||
dragCoefficient: 0.9,
|
||||
};
|
||||
|
||||
// pass it as second argument to layout:
|
||||
var layout = require('ngraph.forcelayout')(graph, physicsSettings);
|
||||
```
|
||||
|
||||
You can get current physics simulator from layout by checking `layout.simulator`
|
||||
property. This is a read only property.
|
||||
|
||||
## Space occupied by graph
|
||||
|
||||
Finally, it's often desirable to know how much space does our graph occupy. To
|
||||
quickly get bounding box use `getGraphRect()` method:
|
||||
|
||||
``` js
|
||||
var rect = layout.getGraphRect();
|
||||
// rect.min_x, rect.min_y - left top coordinates of the bounding box
|
||||
// rect.max_x, rect.max_y - right bottom coordinates of the bounding box
|
||||
```
|
||||
|
||||
## Manipulating bodies
|
||||
|
||||
This is advanced technique to get to internal state of the simulator. If you need
|
||||
to get a node position use regular `layout.getNodePosition(nodeId)` described
|
||||
above.
|
||||
|
||||
In some cases you really need to manipulate physic attributes on a body level.
|
||||
To get to a single body by node id:
|
||||
|
||||
``` js
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
// Get body that represents node 1:
|
||||
var body = layout.getBody(1);
|
||||
assert(
|
||||
typeof body.pos.x === 'number' &&
|
||||
typeof body.pos.y === 'number', 'Body has position');
|
||||
assert(body.mass, 'Body has mass');
|
||||
```
|
||||
|
||||
To iterate over all bodies at once:
|
||||
|
||||
``` js
|
||||
layout.forEachBody(function(body, nodeId) {
|
||||
assert(
|
||||
typeof body.pos.x === 'number' &&
|
||||
typeof body.pos.y === 'number', 'Body has position');
|
||||
assert(graph.getNode(nodeId), 'NodeId is coming from the graph');
|
||||
});
|
||||
```
|
||||
|
||||
# Section about performance
|
||||
|
||||
This library is focused on performance of physical simulation. We use quad tree data structure
|
||||
in 2D space to approximate long distance forces, and reduce amount of required computations.
|
||||
|
||||
When layout is performed in higher dimensions we use analogues tree data structure. By design
|
||||
such tree requires to store `2^dimensions_count` child nodes on each node. In practice, performing
|
||||
layout in 6 dimensional space on a graph with a few thousand nodes yields decent performance
|
||||
on modern mac book (graph can be both rendered and layed out at 60FPS rate).
|
||||
|
||||
Additionally, the vector algebra is optimized by a ad-hoc code generation. Essentially this means
|
||||
that upon first load of the library, we check the dimension of the space where you want to perform
|
||||
layout, and generate all required data structure to run fast in this space.
|
||||
|
||||
The code generation happens only once when dimension is requested. Any subsequent layouts in the same
|
||||
space would reuse generated codes. It is pretty fast and cool.
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```
|
||||
npm install ngraph.forcelayout
|
||||
```
|
||||
|
||||
Or download from CDN:
|
||||
|
||||
``` html
|
||||
<script src='https://unpkg.com/ngraph.forcelayout@3.0.0/dist/ngraph.forcelayout.min.js'></script>
|
||||
```
|
||||
|
||||
If you download from CDN the library will be available under `ngraphCreateLayout` global name.
|
||||
|
||||
# license
|
||||
|
||||
MIT
|
||||
|
||||
# Feedback?
|
||||
|
||||
I'd totally love it! Please email me, open issue here, [tweet](https://twitter.com/anvaka) to me,
|
||||
or join discussion [on gitter](https://gitter.im/anvaka/VivaGraphJS).
|
||||
|
||||
If you love this library, please consider sponsoring it at https://github.com/sponsors/anvaka or at
|
||||
https://www.patreon.com/anvaka
|
||||
2
VISUALIZACION/node_modules/ngraph.forcelayout/demo/.browserslistrc
generated
vendored
Executable file
2
VISUALIZACION/node_modules/ngraph.forcelayout/demo/.browserslistrc
generated
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
> 1%
|
||||
last 2 versions
|
||||
18
VISUALIZACION/node_modules/ngraph.forcelayout/demo/.eslintrc.js
generated
vendored
Executable file
18
VISUALIZACION/node_modules/ngraph.forcelayout/demo/.eslintrc.js
generated
vendored
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
'extends': [
|
||||
'plugin:vue/essential',
|
||||
'eslint:recommended'
|
||||
],
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
'no-unused-vars': 'off'
|
||||
},
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
}
|
||||
}
|
||||
33
VISUALIZACION/node_modules/ngraph.forcelayout/demo/README.md
generated
vendored
Executable file
33
VISUALIZACION/node_modules/ngraph.forcelayout/demo/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
# ngraph.forcelayout demo
|
||||
|
||||
This folder contains a demo of the `ngraph.forcelayout` package.
|
||||
|
||||
If you drop any `.dot` file into the browser window the demo will attempt to visualize it.
|
||||
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
|
||||
```
|
||||
npm start
|
||||
```
|
||||
|
||||
This should render a simple graph and you can do some basic layout. You can drop `.dot` files into it
|
||||
to load new graphs.
|
||||
|
||||
### Compiles and minifies for production
|
||||
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
## What's inside?
|
||||
|
||||
* [ngraph.graph](https://github.com/anvaka/ngraph.graph) as a graph data structure
|
||||
* [ngraph.forcelayout](https://github.com/anvaka/ngraph.forcelayout) for the basic graph layout
|
||||
* [w-gl](https://github.com/anvaka/w-gl) - super duper obscure (and fast) WebGL renderer.
|
||||
* vue.js powered UI and dev tools.
|
||||
|
||||
## Thanks!
|
||||
|
||||
* Stay tuned for updates: https://twitter.com/anvaka
|
||||
* If you like my work and would like to support it - https://www.patreon.com/anvaka
|
||||
5
VISUALIZACION/node_modules/ngraph.forcelayout/demo/babel.config.js
generated
vendored
Executable file
5
VISUALIZACION/node_modules/ngraph.forcelayout/demo/babel.config.js
generated
vendored
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
10
VISUALIZACION/node_modules/ngraph.forcelayout/demo/deploy.sh
generated
vendored
Executable file
10
VISUALIZACION/node_modules/ngraph.forcelayout/demo/deploy.sh
generated
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
rm -rf ./dist
|
||||
npm run build
|
||||
cd ./dist
|
||||
git init
|
||||
git add .
|
||||
git commit -m 'push to gh-pages'
|
||||
## Change the line below to deploy to your gh-pages
|
||||
git push --force git@github.com:anvaka/ngraph.forcelayout.git master:gh-pages
|
||||
cd ../
|
||||
27599
VISUALIZACION/node_modules/ngraph.forcelayout/demo/package-lock.json
generated
vendored
Executable file
27599
VISUALIZACION/node_modules/ngraph.forcelayout/demo/package-lock.json
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
37
VISUALIZACION/node_modules/ngraph.forcelayout/demo/package.json
generated
vendored
Executable file
37
VISUALIZACION/node_modules/ngraph.forcelayout/demo/package.json
generated
vendored
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "graph-layout-demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"start": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"d3-color": "^2.0.0",
|
||||
"miserables": "^2.0.0",
|
||||
"ngraph.events": "^1.0.0",
|
||||
"ngraph.forcelayout": "^3.2.0",
|
||||
"ngraph.fromdot": "^6.0.0",
|
||||
"ngraph.fromjson": "^3.0.0",
|
||||
"ngraph.generators": "^20.0.0",
|
||||
"ngraph.graph": "^20.0.0",
|
||||
"ngraph.hde": "^1.0.1",
|
||||
"query-state": "^4.3.0",
|
||||
"vue": "^2.6.12",
|
||||
"w-gl": "^0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.5.4",
|
||||
"@vue/cli-plugin-eslint": "^4.5.4",
|
||||
"@vue/cli-service": "^4.5.4",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
}
|
||||
}
|
||||
50
VISUALIZACION/node_modules/ngraph.forcelayout/demo/public/index.html
generated
vendored
Executable file
50
VISUALIZACION/node_modules/ngraph.forcelayout/demo/public/index.html
generated
vendored
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title>ngraph.forcelayout demo</title>
|
||||
<!-- <script src="ngraph.forcelayout2d.js"></script> -->
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #EEE;
|
||||
margin: 0;
|
||||
background: rgb(12, 41, 82);
|
||||
overflow: hidden;
|
||||
}
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but puller doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<canvas id='cnv'></canvas>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', 'UA-47259320-1', 'anvaka.github.io');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
225
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/App.vue
generated
vendored
Executable file
225
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/App.vue
generated
vendored
Executable file
|
|
@ -0,0 +1,225 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<h2><a href='https://github.com/anvaka/ngraph.forcelayout'>ngraph.forcelayout</a> demo
|
||||
<small class='toggle-settings'><a href='#' @click.prevent='settingsOpen = !settingsOpen'>{{settingsOpen ? 'hide settings' : 'show settings'}}</a></small>
|
||||
</h2>
|
||||
<div class='content' v-if='settingsOpen'>
|
||||
<div class='row'>
|
||||
<div class='label'>Graph </div>
|
||||
<select v-model='selectedGraph' :disable='loading' class='value'>
|
||||
<option v-for="graph in graphs" :key='graph' :value='graph'>{{graph}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<input-value label='Time step' v-model='layoutSettings.timeStep'>
|
||||
This is integration time step value. The higher it is, the faster nodes will move, but setting it too high
|
||||
can result in lots of jitter and instability.
|
||||
</input-value>
|
||||
<input-value label='Gravity' v-model='layoutSettings.gravity'>
|
||||
This coefficient defines how strongly each node repels each other.
|
||||
</input-value>
|
||||
<input-value label='Ideal spring length' v-model='layoutSettings.springLength'>
|
||||
What is the ideal length of each spring?
|
||||
</input-value>
|
||||
<input-value label='Spring coefficient' v-model='layoutSettings.springCoefficient'>
|
||||
Higher values makes the spring force stronger, pushing edges closer to the ideal spring length.
|
||||
</input-value>
|
||||
<input-value label='Drag coefficient' v-model='layoutSettings.dragCoefficient'>
|
||||
This coefficient introduces "resistance" from environment. When it is close to 0 the forces
|
||||
will have a lot of freedom, nothing will be stopping them, and that can result in a very
|
||||
unstable simulation.
|
||||
</input-value>
|
||||
<input-value label='Theta' v-model='layoutSettings.theta'>
|
||||
This coefficient influences when we apply long distance forces approximation. When this value is
|
||||
close to 0, the simulation compares forces between every single node (giving O(n^2), slow performance).
|
||||
Recommended value is 0.8.
|
||||
</input-value>
|
||||
|
||||
<input-value label='Dimensions' v-model='layoutSettings.dimensions' step=1>
|
||||
Defines number of dimensions of the space where layout is performed. For visualization purpose
|
||||
2 or 3 dimensions are normally enough. Note: Memory consumptions grows exponentially with number
|
||||
of dimensions.
|
||||
</input-value>
|
||||
|
||||
<input-flag label='Follow bounding box' v-model='fixedViewBox' step=1>
|
||||
Setting this to true will disable pan/zoom but will always keep the graph visible. This is not
|
||||
part of the layout algorithm. Just a view setting of the renderer.
|
||||
</input-flag>
|
||||
<div v-if='loading'>Loading graph...</div>
|
||||
</div>
|
||||
<div v-if='!loading' class='layout-box'>
|
||||
<a href="#" @click.prevent='toggleLayoutRun' class='btn'>{{isRunning ? 'Stop layout' : 'Start layout'}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import createGraphScene from './lib/createGraphScene';
|
||||
import getAvailableGraphs from './lib/getAvailableGraphs';
|
||||
import loadGraph from './lib/loadGraph';
|
||||
import bus from './lib/bus';
|
||||
import queryState from 'query-state';
|
||||
import InputValue from './components/InputValue';
|
||||
import InputFlag from './components/InputFlag';
|
||||
|
||||
let appState = queryState({
|
||||
graph: 'Miserables',
|
||||
timeStep: 0.5,
|
||||
springLength: 10,
|
||||
springCoefficient: 0.8,
|
||||
dragCoefficient: 0.9,
|
||||
dimensions: 2,
|
||||
theta: 0.8,
|
||||
gravity: -12,
|
||||
}, { useSearch: true });
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
components: {
|
||||
InputValue,
|
||||
InputFlag
|
||||
},
|
||||
methods: {
|
||||
toggleLayoutRun() {
|
||||
this.isRunning = !this.isRunning;
|
||||
this.scene.runLayout(this.isRunning);
|
||||
},
|
||||
|
||||
loadNewGraph(newGraph) {
|
||||
this.loading = true;
|
||||
this.stats = null;
|
||||
this.isRunning = false;
|
||||
|
||||
loadGraph(newGraph).then(newGraph => {
|
||||
bus.fire('load-graph', newGraph, this.selectedLayout);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
onGraphLoaded() {
|
||||
this.isRunning = false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
layoutSettings: {
|
||||
deep: true,
|
||||
handler(newValue) {
|
||||
this.scene.updateLayoutSettings(newValue);
|
||||
appState.set(newValue);
|
||||
}
|
||||
},
|
||||
fixedViewBox(newValue) {
|
||||
this.scene.setFixedViewBox(newValue);
|
||||
},
|
||||
selectedGraph(newGraph) {
|
||||
appState.set('graph', newGraph);
|
||||
this.loadNewGraph(newGraph);
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let graphs = getAvailableGraphs();
|
||||
return {
|
||||
isRunning: false,
|
||||
fixedViewBox: false,
|
||||
selectedGraph: appState.get('graph'),
|
||||
settingsOpen: window.innerWidth > 500,
|
||||
loading: false,
|
||||
layoutSettings: {
|
||||
timeStep: appState.get('timeStep'),
|
||||
springLength: appState.get('springLength'),
|
||||
springCoefficient: appState.get('springCoefficient'),
|
||||
dragCoefficient: appState.get('dragCoefficient'),
|
||||
dimensions: appState.get('dimensions'),
|
||||
theta: appState.get('theta'),
|
||||
gravity: appState.get('gravity'),
|
||||
},
|
||||
graphs
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const canvas = document.getElementById('cnv');
|
||||
this.scene = createGraphScene(canvas, {...this.layoutSettings});
|
||||
this.loadNewGraph(this.selectedGraph);
|
||||
bus.on('load-graph', this.onGraphLoaded);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
if (this.scene) {
|
||||
this.scene.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='stylus'>
|
||||
small-screen = 500px;
|
||||
|
||||
#app {
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
background: rgb(12, 41, 82);
|
||||
border: 1px solid white;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.content {
|
||||
padding: 8px;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.row .label {
|
||||
flex: 1;
|
||||
}
|
||||
.row .value {
|
||||
flex: 1;
|
||||
}
|
||||
.row select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a.btn {
|
||||
color: rgb(244, 244, 244);
|
||||
text-decoration: none;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-top: 1px solid;
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 0;
|
||||
}
|
||||
h2 {
|
||||
margin: 8px;
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
a {
|
||||
color: #267fcd;
|
||||
}
|
||||
small a {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 8px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.number {
|
||||
color: yellow;
|
||||
font-size: 18px;
|
||||
}
|
||||
.names {
|
||||
position: fixed;
|
||||
font-size: 24px;
|
||||
top: 18px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
@media (max-width: small-screen) {
|
||||
#app {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/HelpIcon.vue
generated
vendored
Executable file
15
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/HelpIcon.vue
generated
vendored
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<a @click.prevent='show' class='help-icon' href='#' title='Click for more details'>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="9" height="14" viewBox="0 0 9 14" fill='#267fcd' >
|
||||
<path d="M5.5 9.812v1.875q0 0.125-0.094 0.219t-0.219 0.094h-1.875q-0.125 0-0.219-0.094t-0.094-0.219v-1.875q0-0.125 0.094-0.219t0.219-0.094h1.875q0.125 0 0.219 0.094t0.094 0.219zM7.969 5.125q0 0.422-0.121 0.789t-0.273 0.598-0.43 0.465-0.449 0.34-0.477 0.277q-0.32 0.18-0.535 0.508t-0.215 0.523q0 0.133-0.094 0.254t-0.219 0.121h-1.875q-0.117 0-0.199-0.145t-0.082-0.293v-0.352q0-0.648 0.508-1.223t1.117-0.848q0.461-0.211 0.656-0.438t0.195-0.594q0-0.328-0.363-0.578t-0.84-0.25q-0.508 0-0.844 0.227-0.273 0.195-0.836 0.898-0.102 0.125-0.242 0.125-0.094 0-0.195-0.062l-1.281-0.977q-0.102-0.078-0.121-0.195t0.043-0.219q1.25-2.078 3.625-2.078 0.625 0 1.258 0.242t1.141 0.648 0.828 0.996 0.32 1.238z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
show() { this.$emit('show');}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
102
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/InputFlag.vue
generated
vendored
Executable file
102
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/InputFlag.vue
generated
vendored
Executable file
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<div class='block'>
|
||||
<div class='row'>
|
||||
<div class='col'>{{label}}</div>
|
||||
<div class='col'>
|
||||
<input type='checkbox' v-model='inputValue' >
|
||||
</div>
|
||||
<help-icon @show='helpVisible = !helpVisible' :class='{open: helpVisible}'></help-icon>
|
||||
</div>
|
||||
<div class='row help' v-if='helpVisible'>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import HelpIcon from './HelpIcon';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HelpIcon
|
||||
},
|
||||
props: {
|
||||
label: String,
|
||||
value: Boolean,
|
||||
},
|
||||
methods: {
|
||||
selectAll(e) {
|
||||
e.target.select()
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
helpVisible: false,
|
||||
inputValue: this.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
inputValue(newValue) {
|
||||
this.$emit('input', newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
primary-text = white;
|
||||
|
||||
help-background = #004499;
|
||||
|
||||
.block {
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.col {
|
||||
flex: 1;
|
||||
}
|
||||
a.help-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
width: 25px;
|
||||
margin-right: -7px;
|
||||
svg {
|
||||
fill: secondary-text;
|
||||
}
|
||||
&.open {
|
||||
background: help-background;
|
||||
svg {
|
||||
fill: primary-text;
|
||||
}
|
||||
}
|
||||
}
|
||||
.row.help {
|
||||
margin-top: 0;
|
||||
background: help-background;
|
||||
padding: 8px;
|
||||
margin: 0 -7px;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='number'] {
|
||||
background: transparent;
|
||||
color: primary-text;
|
||||
border: 1px solid transparent;
|
||||
padding: 7px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
margin-left: 7px;
|
||||
&:focus {
|
||||
outline-offset: 0;
|
||||
outline: none;
|
||||
border: 1px dashed;
|
||||
background: #13294f;
|
||||
}
|
||||
&:invalid {
|
||||
box-shadow:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
113
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/InputValue.vue
generated
vendored
Executable file
113
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/components/InputValue.vue
generated
vendored
Executable file
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<div class='block'>
|
||||
<div class='row'>
|
||||
<div class='col'>{{label}}</div>
|
||||
<div class='col'>
|
||||
<input type='number'
|
||||
:step='step'
|
||||
v-model='inputValue'
|
||||
@focus="selectAll"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="off"
|
||||
spellcheck="false">
|
||||
</div>
|
||||
<help-icon @show='helpVisible = !helpVisible' :class='{open: helpVisible}'></help-icon>
|
||||
</div>
|
||||
<div class='row help' v-if='helpVisible'>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import HelpIcon from './HelpIcon';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HelpIcon
|
||||
},
|
||||
props: {
|
||||
label: String,
|
||||
value: Number,
|
||||
step: {
|
||||
default: '0.1',
|
||||
type: String
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
selectAll(e) {
|
||||
e.target.select()
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
helpVisible: false,
|
||||
inputValue: this.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
inputValue(newValue) {
|
||||
this.$emit('input', parseFloat(newValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus">
|
||||
primary-text = white;
|
||||
|
||||
help-background = #004499;
|
||||
|
||||
.block {
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 1px;
|
||||
}
|
||||
.col {
|
||||
flex: 1;
|
||||
}
|
||||
a.help-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
width: 25px;
|
||||
margin-right: -7px;
|
||||
svg {
|
||||
fill: secondary-text;
|
||||
}
|
||||
&.open {
|
||||
background: help-background;
|
||||
svg {
|
||||
fill: primary-text;
|
||||
}
|
||||
}
|
||||
}
|
||||
.row.help {
|
||||
margin-top: 0;
|
||||
background: help-background;
|
||||
padding: 8px;
|
||||
margin: 0 -7px;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='number'] {
|
||||
background: transparent;
|
||||
color: primary-text;
|
||||
border: 1px solid transparent;
|
||||
padding: 7px;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
margin-left: 7px;
|
||||
&:focus {
|
||||
outline-offset: 0;
|
||||
outline: none;
|
||||
border: 1px dashed;
|
||||
background: #13294f;
|
||||
}
|
||||
&:invalid {
|
||||
box-shadow:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
98
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/LineCollection.js
generated
vendored
Executable file
98
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/LineCollection.js
generated
vendored
Executable file
|
|
@ -0,0 +1,98 @@
|
|||
import {GLCollection, defineProgram, InstancedAttribute, ColorAttribute} from 'w-gl';
|
||||
|
||||
export default class LineCollection extends GLCollection {
|
||||
constructor(gl, options = {}) {
|
||||
let program = defineProgram({
|
||||
gl,
|
||||
vertex: `
|
||||
uniform mat4 modelViewProjection;
|
||||
uniform float width;
|
||||
uniform vec2 resolution;
|
||||
|
||||
attribute vec4 color;
|
||||
attribute vec3 from, to;
|
||||
attribute vec2 point;
|
||||
|
||||
varying vec4 vColor;
|
||||
varying vec2 vPoint;
|
||||
|
||||
void main() {
|
||||
vec4 clip0 = modelViewProjection * vec4(from, 1.0);
|
||||
vec4 clip1 = modelViewProjection * vec4(to, 1.0);
|
||||
|
||||
vec2 screen0 = resolution * (0.5 * clip0.xy/clip0.w + 0.5);
|
||||
vec2 screen1 = resolution * (0.5 * clip1.xy/clip1.w + 0.5);
|
||||
|
||||
vec2 xBasis = normalize(screen1 - screen0);
|
||||
vec2 yBasis = vec2(-xBasis.y, xBasis.x);
|
||||
|
||||
// Offset the original points:
|
||||
vec2 pt0 = screen0 + width * point.x * yBasis;
|
||||
vec2 pt1 = screen1 + width * point.x * yBasis;
|
||||
|
||||
vec2 pt = mix(pt0, pt1, point.y);
|
||||
vec4 clip = mix(clip0, clip1, point.y);
|
||||
|
||||
gl_Position = vec4(clip.w * (2.0 * pt/resolution - 1.0), clip.z, clip.w);
|
||||
vColor = color.abgr; // mix(.abgr, aToColor.abgr, aPosition.y);
|
||||
}`,
|
||||
|
||||
fragment: `
|
||||
precision highp float;
|
||||
varying vec4 vColor;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vColor;
|
||||
}`,
|
||||
attributes: {
|
||||
color: new ColorAttribute()
|
||||
},
|
||||
instanced: {
|
||||
point: new InstancedAttribute([
|
||||
-0.5, 0, -0.5, 1, 0.5, 1, // First 2D triangle of the quad
|
||||
-0.5, 0, 0.5, 1, 0.5, 0 // Second 2D triangle of the quad
|
||||
])
|
||||
}
|
||||
});
|
||||
super(program);
|
||||
this.width = options.width || 2;
|
||||
}
|
||||
|
||||
draw(_, drawContext) {
|
||||
if (!this.uniforms) {
|
||||
this.uniforms = {
|
||||
modelViewProjection: this.modelViewProjection,
|
||||
width: this.width,
|
||||
resolution: [drawContext.width, drawContext.height]
|
||||
}
|
||||
}
|
||||
this.uniforms.resolution[0] = drawContext.width;
|
||||
this.uniforms.resolution[1] = drawContext.height;
|
||||
this.program.draw(this.uniforms);
|
||||
}
|
||||
|
||||
// implement lineRenderTrait to allow SVG export via w-gl
|
||||
forEachLine(cb) {
|
||||
let count = this.program.getCount()
|
||||
for (let i = 0; i < count; ++i) {
|
||||
let vertex = this.program.get(i);
|
||||
let from = { x: vertex.from[0], y: vertex.from[1], z: vertex.from[2], color: vertex.color }
|
||||
let to = { x: vertex.to[0], y: vertex.to[1], z: vertex.to[2], color: vertex.color }
|
||||
cb(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
getLineColor(from) {
|
||||
let count = this.program.getCount()
|
||||
let c = from ?
|
||||
from.color :
|
||||
count > 0 ? this.program.get(0).color : 0xFFFFFFFF;
|
||||
|
||||
return [
|
||||
(c >> 24) & 0xFF / 255,
|
||||
(c >> 16) & 0xFF / 255,
|
||||
(c >> 8) & 0xFF / 255,
|
||||
(c >> 0) & 0xFF / 255,
|
||||
]
|
||||
}
|
||||
}
|
||||
56
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/PointCollection.js
generated
vendored
Executable file
56
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/PointCollection.js
generated
vendored
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
import {GLCollection, defineProgram, ColorAttribute, InstancedAttribute} from 'w-gl';
|
||||
|
||||
export default class PointCollection extends GLCollection {
|
||||
constructor(gl) {
|
||||
let program = defineProgram({
|
||||
gl,
|
||||
vertex: `
|
||||
uniform mat4 modelViewProjection;
|
||||
|
||||
attribute float size;
|
||||
attribute vec3 position;
|
||||
attribute vec4 color;
|
||||
|
||||
attribute vec2 point; // instanced
|
||||
|
||||
varying vec4 vColor;
|
||||
varying vec2 vPoint;
|
||||
void main() {
|
||||
gl_Position = modelViewProjection * vec4(position + vec3(point * size, 0.), 1.0);
|
||||
vColor = color.abgr;
|
||||
vPoint = point;
|
||||
}`,
|
||||
|
||||
fragment: `
|
||||
precision highp float;
|
||||
varying vec4 vColor;
|
||||
varying vec2 vPoint;
|
||||
void main() {
|
||||
float dist = length(vPoint);
|
||||
if (dist >= 0.5) {discard;}
|
||||
gl_FragColor = vColor;
|
||||
}`,
|
||||
// These are just overrides:
|
||||
attributes: {
|
||||
color: new ColorAttribute(),
|
||||
},
|
||||
instanced: {
|
||||
point: new InstancedAttribute([
|
||||
-0.5, -0.5, -0.5, 0.5, 0.5, 0.5,
|
||||
0.5, 0.5, 0.5, -0.5, -0.5, -0.5,
|
||||
])
|
||||
},
|
||||
|
||||
preDrawHook(/* programInfo */) {
|
||||
return `gl.enable(gl.DEPTH_TEST);
|
||||
gl.depthFunc(gl.LEQUAL);`;
|
||||
},
|
||||
postDrawHook() {
|
||||
return 'gl.disable(gl.DEPTH_TEST);';
|
||||
},
|
||||
});
|
||||
|
||||
super(program);
|
||||
}
|
||||
}
|
||||
5
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/bus.js
generated
vendored
Executable file
5
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/bus.js
generated
vendored
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
import eventify from 'ngraph.events';
|
||||
|
||||
const bus = eventify({});
|
||||
|
||||
export default bus;
|
||||
15
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/createForceLayout.js
generated
vendored
Executable file
15
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/createForceLayout.js
generated
vendored
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
import createLayout from '../../../';
|
||||
|
||||
export default function createForceLayout(graph, layoutSettings) {
|
||||
// return window.ngraphCreate2dLayout(graph, Object.assign({
|
||||
return createLayout(graph, Object.assign({
|
||||
dimensions: 2,
|
||||
timeStep: 0.5,
|
||||
springLength: 10,
|
||||
gravity: -12,
|
||||
springCoefficient: 0.8,
|
||||
dragCoefficient: 0.9,
|
||||
// adaptiveTimeStepWeight: 0.1,
|
||||
debug: false,
|
||||
}, layoutSettings));
|
||||
}
|
||||
259
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/createGraphScene.js
generated
vendored
Executable file
259
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/createGraphScene.js
generated
vendored
Executable file
|
|
@ -0,0 +1,259 @@
|
|||
import {createScene, createGuide} from 'w-gl';
|
||||
import LineCollection from './LineCollection';
|
||||
import PointCollection from './PointCollection';
|
||||
import bus from './bus';
|
||||
import createHighLayout from 'ngraph.hde'
|
||||
import createForceLayout from './createForceLayout';
|
||||
import findLargestComponent from './findLargestComponent';
|
||||
import createGraph from 'ngraph.graph';
|
||||
|
||||
export default function createGraphScene(canvas, layoutSettings = {}) {
|
||||
let drawLinks = true;
|
||||
|
||||
// Since graph can be loaded dynamically, we have these uninitialized
|
||||
// and captured into closure. loadGraph will do the initialization
|
||||
let graph, layout;
|
||||
let scene, nodes, lines, guide;
|
||||
|
||||
let fixedViewBox = false;
|
||||
let isRunning = false;
|
||||
let rafHandle;
|
||||
|
||||
bus.on('load-graph', loadGraph);
|
||||
|
||||
return {
|
||||
dispose,
|
||||
runLayout,
|
||||
updateLayoutSettings,
|
||||
setFixedViewBox,
|
||||
};
|
||||
|
||||
function loadGraph(newGraph, desiredLayout) {
|
||||
if (scene) {
|
||||
scene.dispose();
|
||||
layout.dispose();
|
||||
scene = null
|
||||
isRunning = false;
|
||||
cancelAnimationFrame(rafHandle);
|
||||
}
|
||||
// newGraph = createGraph(); newGraph.addLink(1, 2)
|
||||
scene = initScene();
|
||||
|
||||
graph = newGraph; //findLargestComponent(newGraph, 1)[0];
|
||||
|
||||
// Let them play on console with it!
|
||||
window.graph = graph;
|
||||
|
||||
guide = createGuide(scene, {showGrid: true, lineColor: 0xffffff10, maxAlpha: 0x10, showCursor: false});
|
||||
// this is a standard force layout
|
||||
layout = createForceLayout(graph, layoutSettings);
|
||||
|
||||
//standardizePositions(layout)
|
||||
let minX = -42, minY = -42;
|
||||
let maxX = 42, maxY =42
|
||||
|
||||
setSceneSize(Math.max(maxX - minX, maxY - minY) * 1.2);
|
||||
initUIElements();
|
||||
|
||||
rafHandle = requestAnimationFrame(frame);
|
||||
}
|
||||
|
||||
function setSceneSize(sceneSize) {
|
||||
scene.setViewBox({
|
||||
left: -sceneSize,
|
||||
top: -sceneSize,
|
||||
right: sceneSize,
|
||||
bottom: sceneSize,
|
||||
});
|
||||
}
|
||||
|
||||
function runLayout(newIsRunning) {
|
||||
isRunning = newIsRunning;
|
||||
}
|
||||
|
||||
function updateLayoutSettings(newLayoutSettings) {
|
||||
let props = ['timeStep', 'springLength', 'springCoefficient', 'dimensions', 'dragCoefficient', 'gravity', 'theta']
|
||||
let previousDimensions = (layoutSettings && layoutSettings.dimensions) || 2;
|
||||
layoutSettings = props.reduce((settings, name) => (settings[name] = newLayoutSettings[name], settings), {});
|
||||
if (!layout) return;
|
||||
|
||||
if (layoutSettings.dimensions !== previousDimensions) {
|
||||
let prevLayout = layout;
|
||||
layout = createForceLayout(graph, layoutSettings)
|
||||
graph.forEachNode(node => {
|
||||
let prevPos = prevLayout.getNodePosition(node.id);
|
||||
let positions = Object.keys(prevPos).map(name => prevPos[name]);
|
||||
for (let i = previousDimensions; i < layoutSettings.dimensions; ++i) {
|
||||
// If new layout has more dimensions than the previous layout, fill those with random values:
|
||||
positions.push(Math.random());
|
||||
}
|
||||
positions.unshift(node.id);
|
||||
layout.setNodePosition.apply(layout, positions);
|
||||
});
|
||||
|
||||
prevLayout.dispose();
|
||||
} else {
|
||||
props.forEach(name => {
|
||||
layout.simulator[name](layoutSettings[name]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setFixedViewBox(isFixed) {
|
||||
fixedViewBox = isFixed;
|
||||
}
|
||||
|
||||
function initScene() {
|
||||
let scene = createScene(canvas);
|
||||
scene.setClearColor(12/255, 41/255, 82/255, 1)
|
||||
return scene;
|
||||
}
|
||||
|
||||
function initUIElements() {
|
||||
nodes = new PointCollection(scene.getGL(), {
|
||||
capacity: graph.getNodesCount()
|
||||
});
|
||||
|
||||
graph.forEachNode(node => {
|
||||
var point = layout.getNodePosition(node.id);
|
||||
let size = 1;
|
||||
if (node.data && node.data.size) {
|
||||
size = node.data.size;
|
||||
} else {
|
||||
if (!node.data) node.data = {};
|
||||
node.data.size = size;
|
||||
}
|
||||
node.ui = {size, position: [point.x, point.y, point.z || 0], color: 0x90f8fcff};
|
||||
node.uiId = nodes.add(node.ui);
|
||||
});
|
||||
|
||||
lines = new LineCollection(scene.getGL(), { capacity: graph.getLinksCount() });
|
||||
|
||||
graph.forEachLink(link => {
|
||||
var from = layout.getNodePosition(link.fromId);
|
||||
var to = layout.getNodePosition(link.toId);
|
||||
var line = { from: [from.x, from.y, from.z || 0], to: [to.x, to.y, to.z || 0], color: 0xFFFFFF10 };
|
||||
link.ui = line;
|
||||
link.uiId = lines.add(link.ui);
|
||||
});
|
||||
// lines.add({from: [0, 0, 0], to: [0, 10, 0], color: 0xFF0000FF})
|
||||
|
||||
scene.appendChild(lines);
|
||||
scene.appendChild(nodes);
|
||||
}
|
||||
|
||||
function frame() {
|
||||
rafHandle = requestAnimationFrame(frame);
|
||||
|
||||
if (isRunning) {
|
||||
layout.step();
|
||||
if (fixedViewBox) {
|
||||
let rect = layout.getGraphRect();
|
||||
scene.setViewBox({
|
||||
left: rect.min_x,
|
||||
top: rect.min_y,
|
||||
right: rect.max_x,
|
||||
bottom: rect.max_y,
|
||||
});
|
||||
}
|
||||
}
|
||||
drawGraph();
|
||||
scene.renderFrame();
|
||||
}
|
||||
|
||||
function drawGraph() {
|
||||
let names = ['x', 'y', 'z']
|
||||
// let minR = Infinity; let maxR = -minR;
|
||||
// let minG = Infinity; let maxG = -minG;
|
||||
// let minB = Infinity; let maxB = -minB;
|
||||
// graph.forEachNode(node => {
|
||||
// let pos = layout.getNodePosition(node.id);
|
||||
// if (pos.c4 < minR) minR = pos.c4;
|
||||
// if (pos.c4 > maxR) maxR = pos.c4;
|
||||
|
||||
// if (pos.c5 < minG) minG = pos.c5;
|
||||
// if (pos.c5 > maxG) maxG = pos.c5;
|
||||
|
||||
// if (pos.c6 < minB) minB = pos.c6;
|
||||
// if (pos.c6 > maxB) maxB = pos.c6;
|
||||
// });
|
||||
|
||||
graph.forEachNode(node => {
|
||||
let pos = layout.getNodePosition(node.id);
|
||||
let uiPosition = node.ui.position;
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
uiPosition[i] = pos[names[i]] || 0;
|
||||
}
|
||||
// let r = Math.floor(255 * (pos.c4 - minR) / (maxR - minR)) << 24;
|
||||
// let g = Math.floor(255 * (pos.c5 - minG) / (maxG - minG)) << 16;
|
||||
// let b = Math.floor(255 * (pos.c6 - minB) / (maxB - minB)) << 8;
|
||||
// [r, g, b] = lab2rgb(
|
||||
// (pos.c4 - minR) / (maxR - minR),
|
||||
// (pos.c5 - minG) / (maxG - minG),
|
||||
// (pos.c6 - minB) / (maxB - minB)
|
||||
// );
|
||||
// node.ui.color = (0x000000FF | r | g | b);
|
||||
nodes.update(node.uiId, node.ui)
|
||||
});
|
||||
|
||||
if (drawLinks) {
|
||||
graph.forEachLink(link => {
|
||||
var fromPos = layout.getNodePosition(link.fromId);
|
||||
var toPos = layout.getNodePosition(link.toId);
|
||||
let {from, to} = link.ui;
|
||||
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
from[i] = fromPos[names[i]] || 0;
|
||||
to[i] = toPos[names[i]] || 0;
|
||||
}
|
||||
// from[0] = fromPos.x || 0; from[1] = fromPos.y || 0; from[2] = fromPos.z || 0;
|
||||
// to[0] = toPos.x || 0; to[1] = toPos.y || 0; to[2] = toPos.z || 0;
|
||||
// link.ui.color = lerp(graph.getNode(link.fromId).ui.color, graph.getNode(link.toId).ui.color);
|
||||
lines.update(link.uiId, link.ui);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function lerp(aColor, bColor) {
|
||||
let ar = (aColor >> 24) & 0xFF;
|
||||
let ag = (aColor >> 16) & 0xFF;
|
||||
let ab = (aColor >> 8) & 0xFF;
|
||||
let br = (bColor >> 24) & 0xFF;
|
||||
let bg = (bColor >> 16) & 0xFF;
|
||||
let bb = (bColor >> 8) & 0xFF;
|
||||
let r = Math.floor((ar + br) / 2);
|
||||
let g = Math.floor((ag + bg) / 2);
|
||||
let b = Math.floor((ab + bb) / 2);
|
||||
return (r << 24) | (g << 16) | (b << 8) | 0xF0;
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
cancelAnimationFrame(rafHandle);
|
||||
|
||||
scene.dispose();
|
||||
bus.off('load-graph', loadGraph);
|
||||
}
|
||||
}
|
||||
|
||||
function standardizePositions(layout) {
|
||||
let arr = [];
|
||||
let avgX = 0, avgY = 0;
|
||||
layout.forEachBody(body => {
|
||||
arr.push(body.pos);
|
||||
avgX += body.pos.x;
|
||||
avgY += body.pos.y;
|
||||
});
|
||||
let meanX = avgX / arr.length;
|
||||
let meanY = avgY / arr.length;
|
||||
let varX = 0, varY = 0;
|
||||
arr.forEach(pos => {
|
||||
varX += Math.pow(pos.x - meanX, 2);
|
||||
varY += Math.pow(pos.y - meanY, 2);
|
||||
});
|
||||
varX = Math.sqrt(varX / arr.length);
|
||||
varY = Math.sqrt(varY / arr.length);
|
||||
arr.forEach(pos => {
|
||||
pos.x = 10 * (pos.x - meanX) / varX;
|
||||
pos.y = 10 * (pos.y - meanY) / varY;
|
||||
});
|
||||
}
|
||||
78
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/fileDrop.js
generated
vendored
Executable file
78
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/fileDrop.js
generated
vendored
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Handles dropped files into the browser.
|
||||
*/
|
||||
export default function fileDrop(dropHandler, onDropped) {
|
||||
dropHandler.addEventListener('drop', handleDrop, true);
|
||||
dropHandler.addEventListener('dragover', handleDragOver);
|
||||
dropHandler.addEventListener('dragenter', prevent);
|
||||
dropHandler.addEventListener('dragleave', handleDragEnd)
|
||||
dropHandler.addEventListener('dragend', handleDragEnd);
|
||||
|
||||
return {
|
||||
dispose
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
dropHandler.removeEventListener('drop', handleDrop);
|
||||
dropHandler.removeEventListener('dragover', handleDragOver);
|
||||
dropHandler.removeEventListener('dragenter', prevent);
|
||||
dropHandler.removeEventListener('dragleave', handleDragEnd)
|
||||
dropHandler.removeEventListener('dragend', handleDragEnd);
|
||||
}
|
||||
|
||||
function prevent(e) {
|
||||
if (!hasFiles(e)) return;
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function handleDrop(ev) {
|
||||
handleDragEnd();
|
||||
ev.preventDefault();
|
||||
// If dropped items aren't files, reject them
|
||||
var dt = ev.dataTransfer;
|
||||
var files = []
|
||||
var i, file;
|
||||
if (dt.items) {
|
||||
// Use DataTransferItemList interface to access the file(s)
|
||||
for (i = 0; i < dt.items.length; i++) {
|
||||
if (dt.items[i].kind == "file") {
|
||||
file = dt.items[i].getAsFile();
|
||||
files.push(file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Use DataTransfer interface to access the file(s)
|
||||
for (i = 0; i < dt.files.length; i++) {
|
||||
file = dt.files[i];
|
||||
files.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
onDropped(files);
|
||||
}
|
||||
|
||||
|
||||
function handleDragOver(e) {
|
||||
if (!hasFiles(e)) return;
|
||||
|
||||
e.preventDefault();
|
||||
dropHandler.classList.add('drag-over');
|
||||
}
|
||||
|
||||
function hasFiles(e) {
|
||||
if (!e.dataTransfer) return false;
|
||||
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) return true;
|
||||
var items = e.dataTransfer.items;
|
||||
if (!items) return false;
|
||||
for (var i = 0; i < items.length; ++i) {
|
||||
if (items[i].kind === 'file') return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleDragEnd() {
|
||||
dropHandler.classList.remove('drag-over');
|
||||
}
|
||||
}
|
||||
64
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/findLargestComponent.js
generated
vendored
Executable file
64
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/findLargestComponent.js
generated
vendored
Executable file
|
|
@ -0,0 +1,64 @@
|
|||
import createGraph from 'ngraph.graph';
|
||||
|
||||
/**
|
||||
* Returns array of first `count` largest connected components
|
||||
* of the `graph`
|
||||
*/
|
||||
export default function findLargestComponent(graph, count) {
|
||||
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 = new Set();
|
||||
connectedComponents.push(currentComponent);
|
||||
|
||||
// Let's find what other nodes belong to this component
|
||||
bfs(graph, node.id, otherNode => {
|
||||
currentComponent.add(otherNode);
|
||||
nodeIdToComponentId.set(otherNode, lastComponentId);
|
||||
});
|
||||
|
||||
lastComponentId += 1;
|
||||
});
|
||||
|
||||
return connectedComponents.sort((a, b) => b.size - a.size)
|
||||
.slice(0, count)
|
||||
.map(largestComponent => {
|
||||
let subGraph = createGraph();
|
||||
// not the most efficient way, as we iterate over every single link.
|
||||
// This could be improved, for example by performing bfs from the component
|
||||
graph.forEachLink(link => {
|
||||
if (largestComponent.has(link.fromId)) {
|
||||
subGraph.addLink(link.fromId, link.toId);
|
||||
}
|
||||
})
|
||||
|
||||
return subGraph;
|
||||
});
|
||||
}
|
||||
|
||||
function bfs(graph, startFromNodeId, visitor) {
|
||||
let queue = [startFromNodeId];
|
||||
let visited = new Set(queue);
|
||||
|
||||
while (queue.length) {
|
||||
let nodeId = queue.shift();
|
||||
visitor(nodeId);
|
||||
|
||||
graph.forEachLinkedNode(nodeId, function(otherNode) {
|
||||
if (visited.has(otherNode.id)) return;
|
||||
|
||||
queue.push(otherNode.id);
|
||||
visited.add(otherNode.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
731
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/getAvailableGraphs.js
generated
vendored
Executable file
731
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/getAvailableGraphs.js
generated
vendored
Executable file
|
|
@ -0,0 +1,731 @@
|
|||
export default function getAvailableGraphs() {
|
||||
return [
|
||||
'Miserables',
|
||||
'Binary',
|
||||
'HB/blckhole',
|
||||
'Bai/rw5151',
|
||||
'HB/bcsstm13',
|
||||
'HB/lshp1882',
|
||||
'HB/plat1919',
|
||||
'HB/bcsstk26',
|
||||
'Bai/dw256A',
|
||||
'Bai/tols2000',
|
||||
'Bai/dw1024',
|
||||
'Bai/rdb2048',
|
||||
'Pajek/CSphd',
|
||||
'GHS_indef/laser',
|
||||
"Bai/bfwa398",
|
||||
"Bai/bfwa62",
|
||||
"Bai/bfwb398",
|
||||
"Bai/bfwb62",
|
||||
"Bai/bfwb782",
|
||||
"Bai/bwm200",
|
||||
"Bai/cdde1",
|
||||
"Bai/cdde2",
|
||||
"Bai/cdde3",
|
||||
"Bai/cdde4",
|
||||
"Bai/cdde5",
|
||||
"Bai/cdde6",
|
||||
"Bai/ck104",
|
||||
"Bai/ck400",
|
||||
"Bai/ck656",
|
||||
"Bai/dw256B",
|
||||
"Bai/dwa512",
|
||||
"Bai/dwb512",
|
||||
"Bai/dwg961a",
|
||||
"Bai/lop163",
|
||||
"Bai/mhdb416",
|
||||
"Bai/odepa400",
|
||||
"Bai/olm100",
|
||||
"Bai/olm1000",
|
||||
"Bai/olm500",
|
||||
"Bai/pde225",
|
||||
"Bai/pde900",
|
||||
"Bai/qh1484",
|
||||
"Bai/qh768",
|
||||
"Bai/qh882",
|
||||
"Bai/rdb1250",
|
||||
"Bai/rdb1250l",
|
||||
"Bai/rdb200",
|
||||
"Bai/rdb200l",
|
||||
"Bai/rdb450",
|
||||
"Bai/rdb450l",
|
||||
"Bai/rdb800l",
|
||||
"Bai/rdb968",
|
||||
"Bai/rw136",
|
||||
"Bai/rw496",
|
||||
"Bai/tols1090",
|
||||
"Bai/tols340",
|
||||
"Bai/tols90",
|
||||
"Bai/tub100",
|
||||
"Bai/tub1000",
|
||||
"Barabasi/NotreDame_yeast",
|
||||
"Bates/Chem97ZtZ",
|
||||
"FEMLAB/poisson2D",
|
||||
"FEMLAB/problem1",
|
||||
"FIDAP/ex1",
|
||||
"FIDAP/ex5",
|
||||
"Grund/b1_ss",
|
||||
"Grund/d_ss",
|
||||
"Grund/poli",
|
||||
"Gset/G11",
|
||||
"Gset/G12",
|
||||
"Gset/G13",
|
||||
"Gset/G14",
|
||||
"Gset/G15",
|
||||
"Gset/G16",
|
||||
"Gset/G17",
|
||||
"Gset/G18",
|
||||
"Gset/G19",
|
||||
"Gset/G20",
|
||||
"Gset/G21",
|
||||
"Gset/G32",
|
||||
"Gset/G33",
|
||||
"Gset/G34",
|
||||
"Gset/G35",
|
||||
"Gset/G36",
|
||||
"Gset/G37",
|
||||
"Gset/G38",
|
||||
"Gset/G39",
|
||||
"Gset/G40",
|
||||
"Gset/G41",
|
||||
"Gset/G42",
|
||||
"Gset/G43",
|
||||
"Gset/G44",
|
||||
"Gset/G45",
|
||||
"Gset/G46",
|
||||
"Gset/G47",
|
||||
"Gset/G48",
|
||||
"Gset/G49",
|
||||
"Gset/G50",
|
||||
"Gset/G51",
|
||||
"Gset/G52",
|
||||
"Gset/G53",
|
||||
"Gset/G54",
|
||||
"Gset/G55",
|
||||
"Gset/G57",
|
||||
"Hamrle/Hamrle1",
|
||||
"HB/1138_bus",
|
||||
"HB/494_bus",
|
||||
"HB/662_bus",
|
||||
"HB/685_bus",
|
||||
"HB/abb313",
|
||||
"HB/arc130",
|
||||
"HB/ash219",
|
||||
"HB/ash292",
|
||||
"HB/ash331",
|
||||
"HB/ash608",
|
||||
"HB/ash85",
|
||||
"HB/ash958",
|
||||
"HB/bcspwr01",
|
||||
"HB/bcspwr02",
|
||||
"HB/bcspwr03",
|
||||
"HB/bcspwr04",
|
||||
"HB/bcspwr05",
|
||||
"HB/bcspwr06",
|
||||
"HB/bcspwr07",
|
||||
"HB/bcspwr08",
|
||||
"HB/bcspwr09",
|
||||
"HB/bcsstk01",
|
||||
"HB/bcsstk02",
|
||||
"HB/bcsstk03",
|
||||
"HB/bcsstk04",
|
||||
"HB/bcsstk05",
|
||||
"HB/bcsstk06",
|
||||
"HB/bcsstk07",
|
||||
"HB/bcsstk19",
|
||||
"HB/bcsstk20",
|
||||
"HB/bcsstk22",
|
||||
"HB/bcsstm01",
|
||||
"HB/bcsstm02",
|
||||
"HB/bcsstm03",
|
||||
"HB/bcsstm04",
|
||||
"HB/bcsstm05",
|
||||
"HB/bcsstm06",
|
||||
"HB/bcsstm07",
|
||||
"HB/bcsstm08",
|
||||
"HB/bcsstm09",
|
||||
"HB/bcsstm11",
|
||||
"HB/bcsstm19",
|
||||
"HB/bcsstm20",
|
||||
"HB/bcsstm21",
|
||||
"HB/bcsstm22",
|
||||
"HB/bcsstm23",
|
||||
"HB/bcsstm24",
|
||||
"HB/bcsstm26",
|
||||
"HB/bp_0",
|
||||
"HB/bp_1000",
|
||||
"HB/bp_1200",
|
||||
"HB/bp_1400",
|
||||
"HB/bp_1600",
|
||||
"HB/bp_200",
|
||||
"HB/bp_400",
|
||||
"HB/bp_600",
|
||||
"HB/bp_800",
|
||||
"HB/can_1054",
|
||||
"HB/can_1072",
|
||||
"HB/can_144",
|
||||
"HB/can_161",
|
||||
"HB/can_187",
|
||||
"HB/can_229",
|
||||
"HB/can_24",
|
||||
"HB/can_256",
|
||||
"HB/can_268",
|
||||
"HB/can_292",
|
||||
"HB/can_445",
|
||||
"HB/can_61",
|
||||
"HB/can_62",
|
||||
"HB/can_634",
|
||||
"HB/can_715",
|
||||
"HB/can_73",
|
||||
"HB/can_838",
|
||||
"HB/can_96",
|
||||
"HB/curtis54",
|
||||
"HB/dwt_1005",
|
||||
"HB/dwt_1007",
|
||||
"HB/dwt_1242",
|
||||
"HB/dwt_162",
|
||||
"HB/dwt_193",
|
||||
"HB/dwt_198",
|
||||
"HB/dwt_209",
|
||||
"HB/dwt_221",
|
||||
"HB/dwt_234",
|
||||
"HB/dwt_245",
|
||||
"HB/dwt_2680",
|
||||
"HB/dwt_307",
|
||||
"HB/dwt_310",
|
||||
"HB/dwt_346",
|
||||
"HB/dwt_361",
|
||||
"HB/dwt_419",
|
||||
"HB/dwt_492",
|
||||
"HB/dwt_503",
|
||||
"HB/dwt_512",
|
||||
"HB/dwt_59",
|
||||
"HB/dwt_592",
|
||||
"HB/dwt_607",
|
||||
"HB/dwt_66",
|
||||
"HB/dwt_72",
|
||||
"HB/dwt_758",
|
||||
"HB/dwt_869",
|
||||
"HB/dwt_87",
|
||||
"HB/dwt_878",
|
||||
"HB/dwt_918",
|
||||
"HB/dwt_992",
|
||||
"HB/eris1176",
|
||||
"HB/fs_183_1",
|
||||
"HB/fs_183_3",
|
||||
"HB/fs_183_4",
|
||||
"HB/fs_183_6",
|
||||
"HB/fs_541_1",
|
||||
"HB/fs_541_2",
|
||||
"HB/fs_541_3",
|
||||
"HB/fs_541_4",
|
||||
"HB/fs_680_1",
|
||||
"HB/fs_680_2",
|
||||
"HB/fs_680_3",
|
||||
"HB/gent113",
|
||||
"HB/gr_30_30",
|
||||
"HB/gre_1107",
|
||||
"HB/gre_115",
|
||||
"HB/gre_185",
|
||||
"HB/gre_216a",
|
||||
"HB/gre_216b",
|
||||
"HB/gre_343",
|
||||
"HB/gre_512",
|
||||
"HB/hor_131",
|
||||
"HB/ibm32",
|
||||
"HB/illc1033",
|
||||
"HB/impcol_a",
|
||||
"HB/impcol_b",
|
||||
"HB/impcol_c",
|
||||
"HB/impcol_d",
|
||||
"HB/impcol_e",
|
||||
"HB/jagmesh1",
|
||||
"HB/jagmesh2",
|
||||
"HB/jagmesh3",
|
||||
"HB/jagmesh4",
|
||||
"HB/jagmesh5",
|
||||
"HB/jagmesh7",
|
||||
"HB/jagmesh8",
|
||||
"HB/jagmesh9",
|
||||
"HB/jgl009",
|
||||
"HB/jgl011",
|
||||
"HB/jpwh_991",
|
||||
"HB/lap_25",
|
||||
"HB/lns_131",
|
||||
"HB/lns_511",
|
||||
"HB/lnsp_131",
|
||||
"HB/lnsp_511",
|
||||
"HB/lock_700",
|
||||
"HB/lshp1009",
|
||||
"HB/lshp1270",
|
||||
"HB/lshp1561",
|
||||
"HB/lshp2233",
|
||||
"HB/lshp2614",
|
||||
"HB/lshp3025",
|
||||
"HB/lshp3466",
|
||||
"HB/lshp_265",
|
||||
"HB/lshp_406",
|
||||
"HB/lshp_577",
|
||||
"HB/lshp_778",
|
||||
"HB/lund_a",
|
||||
"HB/lund_b",
|
||||
"HB/mcca",
|
||||
"HB/nnc261",
|
||||
"HB/nnc666",
|
||||
"HB/nos1",
|
||||
"HB/nos2",
|
||||
"HB/nos4",
|
||||
"HB/nos5",
|
||||
"HB/nos6",
|
||||
"HB/nos7",
|
||||
"HB/orsirr_1",
|
||||
"HB/orsirr_2",
|
||||
"HB/plat362",
|
||||
"HB/plskz362",
|
||||
"HB/pores_1",
|
||||
"HB/pores_3",
|
||||
"HB/rgg010",
|
||||
"HB/saylr1",
|
||||
"HB/saylr3",
|
||||
"HB/sherman1",
|
||||
"HB/sherman4",
|
||||
"HB/shl_0",
|
||||
"HB/shl_200",
|
||||
"HB/shl_400",
|
||||
"HB/sstmodel",
|
||||
"HB/steam1",
|
||||
"HB/steam3",
|
||||
"HB/str_0",
|
||||
"HB/str_200",
|
||||
"HB/str_400",
|
||||
"HB/str_600",
|
||||
"HB/well1033",
|
||||
"HB/west0067",
|
||||
"HB/west0132",
|
||||
"HB/west0156",
|
||||
"HB/west0167",
|
||||
"HB/west0381",
|
||||
"HB/west0479",
|
||||
"HB/west0497",
|
||||
"HB/west0655",
|
||||
"HB/west0989",
|
||||
"HB/west1505",
|
||||
"HB/west2021",
|
||||
"HB/will199",
|
||||
"HB/will57",
|
||||
"HB/wm1",
|
||||
"HB/wm2",
|
||||
"HB/wm3",
|
||||
"HB/young1c",
|
||||
"HB/young2c",
|
||||
"HB/young3c",
|
||||
"HB/young4c",
|
||||
"JGD_BIBD/bibd_11_5",
|
||||
"JGD_BIBD/bibd_12_4",
|
||||
"JGD_BIBD/bibd_12_5",
|
||||
"JGD_BIBD/bibd_15_3",
|
||||
"JGD_BIBD/bibd_17_3",
|
||||
"JGD_BIBD/bibd_17_4",
|
||||
"JGD_BIBD/bibd_17_4b",
|
||||
"JGD_BIBD/bibd_81_2",
|
||||
"JGD_BIBD/bibd_9_3",
|
||||
"JGD_BIBD/bibd_9_5",
|
||||
"JGD_CAG/CAG_mat364",
|
||||
"JGD_CAG/CAG_mat72",
|
||||
"JGD_Forest/TF10",
|
||||
"JGD_Forest/TF11",
|
||||
"JGD_Forest/TF12",
|
||||
"JGD_Forest/TF13",
|
||||
"JGD_Franz/Franz1",
|
||||
"JGD_Franz/Franz3",
|
||||
"JGD_G5/IG5-10",
|
||||
"JGD_G5/IG5-6",
|
||||
"JGD_G5/IG5-7",
|
||||
"JGD_G5/IG5-8",
|
||||
"JGD_G5/IG5-9",
|
||||
"JGD_GL6/GL6_D_10",
|
||||
"JGD_GL6/GL6_D_6",
|
||||
"JGD_GL6/GL6_D_7",
|
||||
"JGD_GL6/GL6_D_8",
|
||||
"JGD_GL6/GL6_D_9",
|
||||
"JGD_GL7d/GL7d10",
|
||||
"JGD_GL7d/GL7d11",
|
||||
"JGD_GL7d/GL7d26",
|
||||
"JGD_Homology/ch3-3-b1",
|
||||
"JGD_Homology/ch3-3-b2",
|
||||
"JGD_Homology/ch4-4-b1",
|
||||
"JGD_Homology/ch4-4-b2",
|
||||
"JGD_Homology/ch4-4-b3",
|
||||
"JGD_Homology/ch5-5-b1",
|
||||
"JGD_Homology/ch5-5-b2",
|
||||
"JGD_Homology/ch5-5-b3",
|
||||
"JGD_Homology/ch5-5-b4",
|
||||
"JGD_Homology/ch6-6-b1",
|
||||
"JGD_Homology/ch6-6-b2",
|
||||
"JGD_Homology/ch6-6-b5",
|
||||
"JGD_Homology/ch7-6-b1",
|
||||
"JGD_Homology/ch7-7-b1",
|
||||
"JGD_Homology/ch7-8-b1",
|
||||
"JGD_Homology/ch7-9-b1",
|
||||
"JGD_Homology/ch8-8-b1",
|
||||
"JGD_Homology/cis-n4c6-b1",
|
||||
"JGD_Homology/cis-n4c6-b15",
|
||||
"JGD_Homology/cis-n4c6-b2",
|
||||
"JGD_Homology/klein-b1",
|
||||
"JGD_Homology/klein-b2",
|
||||
"JGD_Homology/mk10-b1",
|
||||
"JGD_Homology/mk10-b2",
|
||||
"JGD_Homology/mk10-b4",
|
||||
"JGD_Homology/mk11-b1",
|
||||
"JGD_Homology/mk12-b1",
|
||||
"JGD_Homology/mk9-b1",
|
||||
"JGD_Homology/mk9-b2",
|
||||
"JGD_Homology/mk9-b3",
|
||||
"JGD_Homology/n2c6-b1",
|
||||
"JGD_Homology/n2c6-b10",
|
||||
"JGD_Homology/n2c6-b2",
|
||||
"JGD_Homology/n2c6-b3",
|
||||
"JGD_Homology/n2c6-b9",
|
||||
"JGD_Homology/n3c4-b1",
|
||||
"JGD_Homology/n3c4-b2",
|
||||
"JGD_Homology/n3c4-b3",
|
||||
"JGD_Homology/n3c4-b4",
|
||||
"JGD_Homology/n3c5-b1",
|
||||
"JGD_Homology/n3c5-b2",
|
||||
"JGD_Homology/n3c5-b3",
|
||||
"JGD_Homology/n3c5-b4",
|
||||
"JGD_Homology/n3c5-b5",
|
||||
"JGD_Homology/n3c5-b6",
|
||||
"JGD_Homology/n3c5-b7",
|
||||
"JGD_Homology/n3c6-b1",
|
||||
"JGD_Homology/n3c6-b10",
|
||||
"JGD_Homology/n3c6-b11",
|
||||
"JGD_Homology/n3c6-b2",
|
||||
"JGD_Homology/n3c6-b3",
|
||||
"JGD_Homology/n4c5-b1",
|
||||
"JGD_Homology/n4c5-b10",
|
||||
"JGD_Homology/n4c5-b11",
|
||||
"JGD_Homology/n4c5-b2",
|
||||
"JGD_Homology/n4c5-b3",
|
||||
"JGD_Homology/n4c5-b9",
|
||||
"JGD_Homology/n4c6-b1",
|
||||
"JGD_Homology/n4c6-b15",
|
||||
"JGD_Homology/n4c6-b2",
|
||||
"JGD_Kocay/Trec10",
|
||||
"JGD_Kocay/Trec3",
|
||||
"JGD_Kocay/Trec4",
|
||||
"JGD_Kocay/Trec5",
|
||||
"JGD_Kocay/Trec6",
|
||||
"JGD_Kocay/Trec7",
|
||||
"JGD_Kocay/Trec8",
|
||||
"JGD_Kocay/Trec9",
|
||||
"JGD_Margulies/cat_ears_2_1",
|
||||
"JGD_Margulies/cat_ears_2_4",
|
||||
"JGD_Margulies/cat_ears_3_1",
|
||||
"JGD_Margulies/cat_ears_4_1",
|
||||
"JGD_Margulies/flower_4_1",
|
||||
"JGD_Margulies/flower_5_1",
|
||||
"JGD_Margulies/flower_7_1",
|
||||
"JGD_Margulies/flower_8_1",
|
||||
"JGD_Margulies/kneser_6_2_1",
|
||||
"JGD_Margulies/wheel_3_1",
|
||||
"JGD_Margulies/wheel_4_1",
|
||||
"JGD_Margulies/wheel_5_1",
|
||||
"JGD_Margulies/wheel_6_1",
|
||||
"JGD_Margulies/wheel_7_1",
|
||||
"JGD_Relat/rel3",
|
||||
"JGD_Relat/rel4",
|
||||
"JGD_Relat/rel5",
|
||||
"JGD_Relat/rel6",
|
||||
"JGD_Relat/relat3",
|
||||
"JGD_Relat/relat4",
|
||||
"JGD_Relat/relat5",
|
||||
"JGD_Relat/relat6",
|
||||
"JGD_SL6/D_10",
|
||||
"JGD_SL6/D_11",
|
||||
"JGD_SL6/D_5",
|
||||
"JGD_SL6/D_6",
|
||||
"JGD_SPG/08blocks",
|
||||
"JGD_SPG/EX1",
|
||||
"JGD_SPG/EX2",
|
||||
"JGD_Trefethen/Trefethen_150",
|
||||
"JGD_Trefethen/Trefethen_20",
|
||||
"JGD_Trefethen/Trefethen_200",
|
||||
"JGD_Trefethen/Trefethen_200b",
|
||||
"JGD_Trefethen/Trefethen_20b",
|
||||
"JGD_Trefethen/Trefethen_300",
|
||||
"JGD_Trefethen/Trefethen_500",
|
||||
"JGD_Trefethen/Trefethen_700",
|
||||
"LPnetlib/lp_adlittle",
|
||||
"LPnetlib/lp_afiro",
|
||||
"LPnetlib/lp_agg",
|
||||
"LPnetlib/lp_agg2",
|
||||
"LPnetlib/lp_agg3",
|
||||
"LPnetlib/lp_bandm",
|
||||
"LPnetlib/lp_beaconfd",
|
||||
"LPnetlib/lp_blend",
|
||||
"LPnetlib/lp_bnl1",
|
||||
"LPnetlib/lp_bore3d",
|
||||
"LPnetlib/lp_brandy",
|
||||
"LPnetlib/lp_capri",
|
||||
"LPnetlib/lp_czprob",
|
||||
"LPnetlib/lp_degen2",
|
||||
"LPnetlib/lp_e226",
|
||||
"LPnetlib/lp_etamacro",
|
||||
"LPnetlib/lp_fffff800",
|
||||
"LPnetlib/lp_finnis",
|
||||
"LPnetlib/lp_fit1p",
|
||||
"LPnetlib/lp_ganges",
|
||||
"LPnetlib/lp_gfrd_pnc",
|
||||
"LPnetlib/lp_grow15",
|
||||
"LPnetlib/lp_grow7",
|
||||
"LPnetlib/lp_israel",
|
||||
"LPnetlib/lp_kb2",
|
||||
"LPnetlib/lp_ken_07",
|
||||
"LPnetlib/lp_lotfi",
|
||||
"LPnetlib/lp_modszk1",
|
||||
"LPnetlib/lp_perold",
|
||||
"LPnetlib/lp_pilot4",
|
||||
"LPnetlib/lp_qap8",
|
||||
"LPnetlib/lp_recipe",
|
||||
"LPnetlib/lp_sc105",
|
||||
"LPnetlib/lp_sc205",
|
||||
"LPnetlib/lp_sc50a",
|
||||
"LPnetlib/lp_sc50b",
|
||||
"LPnetlib/lp_scagr25",
|
||||
"LPnetlib/lp_scagr7",
|
||||
"LPnetlib/lp_scfxm1",
|
||||
"LPnetlib/lp_scfxm2",
|
||||
"LPnetlib/lp_scfxm3",
|
||||
"LPnetlib/lp_scorpion",
|
||||
"LPnetlib/lp_scrs8",
|
||||
"LPnetlib/lp_scsd1",
|
||||
"LPnetlib/lp_scsd6",
|
||||
"LPnetlib/lp_sctap1",
|
||||
"LPnetlib/lp_sctap2",
|
||||
"LPnetlib/lp_sctap3",
|
||||
"LPnetlib/lp_share1b",
|
||||
"LPnetlib/lp_share2b",
|
||||
"LPnetlib/lp_shell",
|
||||
"LPnetlib/lp_ship04l",
|
||||
"LPnetlib/lp_ship04s",
|
||||
"LPnetlib/lp_ship08s",
|
||||
"LPnetlib/lp_ship12s",
|
||||
"LPnetlib/lp_sierra",
|
||||
"LPnetlib/lp_stair",
|
||||
"LPnetlib/lp_standata",
|
||||
"LPnetlib/lp_standgub",
|
||||
"LPnetlib/lp_standmps",
|
||||
"LPnetlib/lp_stocfor1",
|
||||
"LPnetlib/lp_tuff",
|
||||
"LPnetlib/lp_vtp_base",
|
||||
"LPnetlib/lpi_bgdbg1",
|
||||
"LPnetlib/lpi_bgetam",
|
||||
"LPnetlib/lpi_bgprtr",
|
||||
"LPnetlib/lpi_box1",
|
||||
"LPnetlib/lpi_chemcom",
|
||||
"LPnetlib/lpi_cplex2",
|
||||
"LPnetlib/lpi_ex72a",
|
||||
"LPnetlib/lpi_ex73a",
|
||||
"LPnetlib/lpi_forest6",
|
||||
"LPnetlib/lpi_galenet",
|
||||
"LPnetlib/lpi_itest2",
|
||||
"LPnetlib/lpi_itest6",
|
||||
"LPnetlib/lpi_klein1",
|
||||
"LPnetlib/lpi_klein2",
|
||||
"LPnetlib/lpi_mondou2",
|
||||
"LPnetlib/lpi_pang",
|
||||
"LPnetlib/lpi_pilot4i",
|
||||
"LPnetlib/lpi_qual",
|
||||
"LPnetlib/lpi_reactor",
|
||||
"LPnetlib/lpi_refinery",
|
||||
"LPnetlib/lpi_vol1",
|
||||
"LPnetlib/lpi_woodinfe",
|
||||
"MathWorks/Harvard500",
|
||||
"MathWorks/Pd_rhs",
|
||||
"MathWorks/pivtol",
|
||||
"MathWorks/QRpivot",
|
||||
"Meszaros/cep1",
|
||||
"Meszaros/cr42",
|
||||
"Meszaros/farm",
|
||||
"Meszaros/gams10a",
|
||||
"Meszaros/gams10am",
|
||||
"Meszaros/gams30a",
|
||||
"Meszaros/gams30am",
|
||||
"Meszaros/gams60am",
|
||||
"Meszaros/gas11",
|
||||
"Meszaros/iiasa",
|
||||
"Meszaros/iprob",
|
||||
"Meszaros/kleemin",
|
||||
"Meszaros/l9",
|
||||
"Meszaros/model1",
|
||||
"Meszaros/model2",
|
||||
"Meszaros/nemsafm",
|
||||
"Meszaros/nemscem",
|
||||
"Meszaros/nsic",
|
||||
"Meszaros/p0033",
|
||||
"Meszaros/p0040",
|
||||
"Meszaros/p0201",
|
||||
"Meszaros/p0282",
|
||||
"Meszaros/p0291",
|
||||
"Meszaros/p0548",
|
||||
"Meszaros/p2756",
|
||||
"Meszaros/problem",
|
||||
"Meszaros/qiulp",
|
||||
"Meszaros/refine",
|
||||
"Meszaros/rosen7",
|
||||
"Meszaros/scagr7-2c",
|
||||
"Meszaros/scrs8-2b",
|
||||
"Meszaros/scrs8-2c",
|
||||
"Meszaros/small",
|
||||
"Meszaros/zed",
|
||||
"Morandini/robot",
|
||||
"Morandini/rotor1",
|
||||
"Muite/Chebyshev1",
|
||||
"NYPA/Maragal_1",
|
||||
"NYPA/Maragal_2",
|
||||
"Oberwolfach/LF10",
|
||||
"Oberwolfach/LFAT5",
|
||||
"Pajek/Cities",
|
||||
"Pajek/divorce",
|
||||
"Pajek/EPA",
|
||||
"Pajek/Erdos02",
|
||||
"Pajek/Erdos971",
|
||||
"Pajek/Erdos972",
|
||||
"Pajek/Erdos981",
|
||||
"Pajek/Erdos982",
|
||||
"Pajek/Erdos991",
|
||||
"Pajek/Erdos992",
|
||||
"Pajek/EVA",
|
||||
"Pajek/football",
|
||||
"Pajek/GD00_a",
|
||||
"Pajek/GD00_c",
|
||||
"Pajek/GD01_a",
|
||||
"Pajek/GD01_A",
|
||||
"Pajek/GD01_b",
|
||||
"Pajek/GD01_c",
|
||||
"Pajek/GD02_a",
|
||||
"Pajek/GD02_b",
|
||||
"Pajek/GD06_Java",
|
||||
"Pajek/GD06_theory",
|
||||
"Pajek/GD95_a",
|
||||
"Pajek/GD95_b",
|
||||
"Pajek/GD95_c",
|
||||
"Pajek/GD96_a",
|
||||
"Pajek/GD96_b",
|
||||
"Pajek/GD96_c",
|
||||
"Pajek/GD96_d",
|
||||
"Pajek/GD97_a",
|
||||
"Pajek/GD97_b",
|
||||
"Pajek/GD97_c",
|
||||
"Pajek/GD98_a",
|
||||
"Pajek/GD98_b",
|
||||
"Pajek/GD98_c",
|
||||
"Pajek/GD99_b",
|
||||
"Pajek/GD99_c",
|
||||
"Pajek/GlossGT",
|
||||
"Pajek/Journals",
|
||||
"Pajek/Kohonen",
|
||||
"Pajek/Ragusa16",
|
||||
"Pajek/Ragusa18",
|
||||
"Pajek/Roget",
|
||||
"Pajek/Sandi_authors",
|
||||
"Pajek/Sandi_sandi",
|
||||
"Pajek/SciMet",
|
||||
"Pajek/SmaGri",
|
||||
"Pajek/SmallW",
|
||||
"Pajek/Stranke94",
|
||||
"Pajek/Tina_AskCal",
|
||||
"Pajek/Tina_AskCog",
|
||||
"Pajek/Tina_DisCal",
|
||||
"Pajek/Tina_DisCog",
|
||||
"Pajek/USAir97",
|
||||
"Pajek/USpowerGrid",
|
||||
"Pajek/WorldCities",
|
||||
"Pajek/yeast",
|
||||
"Pothen/mesh1e1",
|
||||
"Pothen/mesh1em1",
|
||||
"Pothen/mesh1em6",
|
||||
"Pothen/mesh2e1",
|
||||
"Pothen/mesh2em5",
|
||||
"Pothen/mesh3e1",
|
||||
"Pothen/mesh3em5",
|
||||
"Pothen/sphere2",
|
||||
"Pothen/sphere3",
|
||||
"Qaplib/lp_nug05",
|
||||
"Qaplib/lp_nug06",
|
||||
"Qaplib/lp_nug07",
|
||||
"Qaplib/lp_nug08",
|
||||
"Rajat/rajat02",
|
||||
"Rajat/rajat05",
|
||||
"Rajat/rajat11",
|
||||
"Rajat/rajat14",
|
||||
"Rajat/rajat19",
|
||||
"Sandia/oscil_dcop_01",
|
||||
"Sandia/oscil_dcop_02",
|
||||
"Sandia/oscil_dcop_03",
|
||||
"Sandia/oscil_dcop_04",
|
||||
"Sandia/oscil_dcop_05",
|
||||
"Sandia/oscil_dcop_06",
|
||||
"Sandia/oscil_dcop_07",
|
||||
"Sandia/oscil_dcop_08",
|
||||
"Sandia/oscil_dcop_09",
|
||||
"Sandia/oscil_dcop_10",
|
||||
"Sandia/oscil_dcop_11",
|
||||
"Sandia/oscil_dcop_12",
|
||||
"Sandia/oscil_dcop_13",
|
||||
"Sandia/oscil_dcop_14",
|
||||
"Sandia/oscil_dcop_15",
|
||||
"Sandia/oscil_dcop_16",
|
||||
"Sandia/oscil_dcop_17",
|
||||
"Sandia/oscil_dcop_18",
|
||||
"Sandia/oscil_dcop_19",
|
||||
"Sandia/oscil_dcop_20",
|
||||
"Sandia/oscil_dcop_21",
|
||||
"Sandia/oscil_dcop_22",
|
||||
"Sandia/oscil_dcop_23",
|
||||
"Sandia/oscil_dcop_24",
|
||||
"Sandia/oscil_dcop_25",
|
||||
"Sandia/oscil_dcop_26",
|
||||
"Sandia/oscil_dcop_27",
|
||||
"Sandia/oscil_dcop_28",
|
||||
"Sandia/oscil_dcop_29",
|
||||
"Sandia/oscil_dcop_30",
|
||||
"Sandia/oscil_dcop_31",
|
||||
"Sandia/oscil_dcop_32",
|
||||
"Sandia/oscil_dcop_33",
|
||||
"Sandia/oscil_dcop_34",
|
||||
"Sandia/oscil_dcop_35",
|
||||
"Sandia/oscil_dcop_36",
|
||||
"Sandia/oscil_dcop_37",
|
||||
"Sandia/oscil_dcop_38",
|
||||
"Sandia/oscil_dcop_39",
|
||||
"Sandia/oscil_dcop_40",
|
||||
"Sandia/oscil_dcop_41",
|
||||
"Sandia/oscil_dcop_42",
|
||||
"Sandia/oscil_dcop_43",
|
||||
"Sandia/oscil_dcop_44",
|
||||
"Sandia/oscil_dcop_45",
|
||||
"Sandia/oscil_dcop_46",
|
||||
"Sandia/oscil_dcop_47",
|
||||
"Sandia/oscil_dcop_48",
|
||||
"Sandia/oscil_dcop_49",
|
||||
"Sandia/oscil_dcop_50",
|
||||
"Sandia/oscil_dcop_51",
|
||||
"Sandia/oscil_dcop_52",
|
||||
"Sandia/oscil_dcop_53",
|
||||
"Sandia/oscil_dcop_54",
|
||||
"Sandia/oscil_dcop_55",
|
||||
"Sandia/oscil_dcop_56",
|
||||
"Sandia/oscil_dcop_57",
|
||||
"Sandia/oscil_trans_01",
|
||||
"TOKAMAK/utm300",
|
||||
"vanHeukelum/cage3",
|
||||
"vanHeukelum/cage4",
|
||||
"vanHeukelum/cage5",
|
||||
"vanHeukelum/cage6",
|
||||
"vanHeukelum/cage7",
|
||||
"YZhou/circuit204"
|
||||
];
|
||||
}
|
||||
24
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/getGraph.js
generated
vendored
Executable file
24
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/getGraph.js
generated
vendored
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Load your graph here.
|
||||
*/
|
||||
// https://github.com/anvaka/miserables
|
||||
import miserables from 'miserables';
|
||||
|
||||
// Other loaders:
|
||||
// https://github.com/anvaka/ngraph.generators
|
||||
// import generate from 'ngraph.generators';
|
||||
|
||||
// https://github.com/anvaka/ngraph.graph
|
||||
// import createGraph from 'ngraph.graph';
|
||||
|
||||
// https://github.com/anvaka/ngraph.fromjson
|
||||
// import fromjson from 'ngraph.fromjson'
|
||||
|
||||
// https://github.com/anvaka/ngraph.fromdot
|
||||
// import fromdot from 'ngraph.fromdot'
|
||||
|
||||
export default function getGraph() {
|
||||
return miserables.create();
|
||||
// return generate.wattsStrogatz(20, 5, 0.4);
|
||||
}
|
||||
|
||||
39
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/loadDroppedGraph.js
generated
vendored
Executable file
39
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/loadDroppedGraph.js
generated
vendored
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
import fromDot from 'ngraph.fromdot';
|
||||
import fromJson from 'ngraph.fromjson';
|
||||
import bus from './bus.js';
|
||||
|
||||
/**
|
||||
* Loads graph from a dropped file
|
||||
*/
|
||||
export default function loadDroppedGraph(files) {
|
||||
let file = files[0];
|
||||
|
||||
var reader = new FileReader();
|
||||
reader.readAsText(file, "UTF-8");
|
||||
reader.onload = e => {
|
||||
let content = e.target.result;
|
||||
let graph = tryDot(content) || tryJson(content);
|
||||
if (graph) bus.fire('load-graph', graph);
|
||||
}
|
||||
reader.onerror = (e) => {
|
||||
//eslint-disable-next-line
|
||||
console.log('error loading dot file: ', e)
|
||||
};
|
||||
|
||||
function tryDot(fileContent) {
|
||||
try {
|
||||
return fromDot(fileContent);
|
||||
} catch (e) {
|
||||
//eslint-disable-next-line
|
||||
console.log('error loading dot file: ', e)
|
||||
}
|
||||
}
|
||||
function tryJson(fileContent) {
|
||||
try {
|
||||
return fromJson(JSON.parse(fileContent));
|
||||
} catch (e) {
|
||||
//eslint-disable-next-line
|
||||
console.log('error loading JSON: ', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
54
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/loadGraph.js
generated
vendored
Executable file
54
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/loadGraph.js
generated
vendored
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
import createGraph from 'ngraph.graph';
|
||||
import miserables from 'miserables';
|
||||
import generate from 'ngraph.generators';
|
||||
|
||||
let cache = simpleCache();
|
||||
|
||||
export default function loadGraph(name) {
|
||||
if (name === 'Miserables') return Promise.resolve(miserables);
|
||||
if (name === 'Binary') return Promise.resolve(generate.balancedBinTree(10));
|
||||
|
||||
let mtxObject = cache.get(name);
|
||||
if (mtxObject) return Promise.resolve(renderGraph(mtxObject.links, mtxObject.recordsPerEdge));
|
||||
|
||||
return fetch(`https://s3.amazonaws.com/yasiv_uf/out/${name}/index.js`, {
|
||||
mode: 'cors'
|
||||
})
|
||||
.then(x => x.json())
|
||||
.then(mtxObject => {
|
||||
cache.put(name, mtxObject);
|
||||
return renderGraph(mtxObject.links, mtxObject.recordsPerEdge);
|
||||
});
|
||||
}
|
||||
function renderGraph (edges, recordsPerEdge) {
|
||||
let graph = createGraph();
|
||||
for(var i = 0; i < edges.length - 1; i += recordsPerEdge) {
|
||||
graph.addLink(edges[i], edges[i + 1]);
|
||||
}
|
||||
return graph
|
||||
}
|
||||
|
||||
function simpleCache() {
|
||||
var supported = 'localStorage' in window;
|
||||
|
||||
return {
|
||||
get : function(key) {
|
||||
if (!supported) { return null; }
|
||||
var graphData = JSON.parse(window.localStorage.getItem(key));
|
||||
if (!graphData || graphData.recordsPerEdge === undefined) {
|
||||
// this is old cache. Invalidate it
|
||||
return null;
|
||||
}
|
||||
return graphData;
|
||||
},
|
||||
put : function(key, value) {
|
||||
if (!supported) { return false;}
|
||||
try {
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch(err) {
|
||||
// TODO: make something clever than this in case of quata exceeded.
|
||||
window.localStorage.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
54
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/utils.js
generated
vendored
Executable file
54
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/lib/utils.js
generated
vendored
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Set of function that I find useful for explorations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Performs hermit interpolation of `x` between two edges
|
||||
*/
|
||||
export function smoothStep(edge0, edge1, x) {
|
||||
let t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamp `x` to [min, max] range.
|
||||
*/
|
||||
export function clamp(x, min, max) {
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects main statistical properties of a collection
|
||||
*/
|
||||
export function collectStatistics(array) {
|
||||
if (array.length === 0) {
|
||||
return {
|
||||
min: undefined,
|
||||
max: undefined,
|
||||
avg: undefined,
|
||||
sigma: undefined,
|
||||
mod: undefined,
|
||||
count: 0
|
||||
}
|
||||
}
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
let sum = 0;
|
||||
let counts = new Map();
|
||||
array.forEach(x => {
|
||||
if (x < min) min = x;
|
||||
if (x > max) max = x;
|
||||
sum += x;
|
||||
counts.set(x, (counts.get(x) || 0) + 1)
|
||||
});
|
||||
let mod = Array.from(counts).sort((a, b) => b[1] - a[1])[0][0]
|
||||
|
||||
let avg = sum /= array.length;
|
||||
let sigma = 0;
|
||||
array.forEach(x => {
|
||||
sigma += (x - avg) * (x - avg);
|
||||
});
|
||||
sigma = Math.sqrt(sigma / (array.length + 1));
|
||||
let count = array.length;
|
||||
return {min, max, avg, sigma, mod, count};
|
||||
}
|
||||
13
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/main.js
generated
vendored
Executable file
13
VISUALIZACION/node_modules/ngraph.forcelayout/demo/src/main.js
generated
vendored
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import fileDrop from './lib/fileDrop.js';
|
||||
import loadDroppedGraph from './lib/loadDroppedGraph.js';
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
||||
// When they drop a `.dot` file into the browser - let's load it.
|
||||
fileDrop(document.body, loadDroppedGraph);
|
||||
3
VISUALIZACION/node_modules/ngraph.forcelayout/demo/vue.config.js
generated
vendored
Executable file
3
VISUALIZACION/node_modules/ngraph.forcelayout/demo/vue.config.js
generated
vendored
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
publicPath: ''
|
||||
}
|
||||
1832
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout.js
generated
vendored
Executable file
1832
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
1
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout.min.js
generated
vendored
Executable file
1
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout.min.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
1652
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout2d.js
generated
vendored
Executable file
1652
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout2d.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load diff
1
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout2d.min.js
generated
vendored
Executable file
1
VISUALIZACION/node_modules/ngraph.forcelayout/dist/ngraph.forcelayout2d.min.js
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
374
VISUALIZACION/node_modules/ngraph.forcelayout/index.d.ts
generated
vendored
Executable file
374
VISUALIZACION/node_modules/ngraph.forcelayout/index.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,374 @@
|
|||
declare module "ngraph.forcelayout" {
|
||||
import { Graph, NodeId, LinkId, Node, Link } from "ngraph.graph";
|
||||
import { EventedType } from "ngraph.events";
|
||||
|
||||
export type ForceFunction = (iterationNumber: number) => void;
|
||||
|
||||
export interface Vector {
|
||||
x: number;
|
||||
y: number;
|
||||
z?: number;
|
||||
[coord: `c${number}`]: number
|
||||
}
|
||||
|
||||
export interface Body {
|
||||
isPinned: boolean;
|
||||
pos: Vector;
|
||||
force: Vector;
|
||||
velocity: Vector;
|
||||
mass: number;
|
||||
springCount: number;
|
||||
springLength: number;
|
||||
reset(): void;
|
||||
setPosition(x: number, y: number, z?: number, ...c: number[]): void;
|
||||
}
|
||||
|
||||
export interface Spring {
|
||||
from: Body;
|
||||
to: Body;
|
||||
length: number;
|
||||
coefficient: number;
|
||||
}
|
||||
|
||||
export interface QuadNode {
|
||||
body: Body | null;
|
||||
mass: number;
|
||||
mass_x: number;
|
||||
mass_y: number;
|
||||
mass_z?: number;
|
||||
[mass: `mass_c${number}`]: number | null;
|
||||
[mass: `min_c${number}`]: number | null;
|
||||
[mass: `max_c${number}`]: number | null;
|
||||
[quad: `quad${number}`]: number | null;
|
||||
}
|
||||
|
||||
export interface QuadTree {
|
||||
insertBodies(bodies: Body[]): void;
|
||||
getRoot(): QuadNode;
|
||||
updateBodyForce(sourceBody: Body): void;
|
||||
options(newOptions: { gravity: number; theta: number }): { gravity: number; theta: number };
|
||||
}
|
||||
|
||||
export interface BoundingBox {
|
||||
min_x: number;
|
||||
max_x: number;
|
||||
min_y: number;
|
||||
max_y: number;
|
||||
min_z?: number;
|
||||
max_z?: number;
|
||||
[min: `min_c${number}`]: number;
|
||||
[max: `max_c${number}`]: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings for a PhysicsSimulator
|
||||
*/
|
||||
export interface PhysicsSettings {
|
||||
/**
|
||||
* Ideal length for links (springs in physical model).
|
||||
*/
|
||||
springLength: number;
|
||||
|
||||
/**
|
||||
* Hook's law coefficient. 1 - solid spring.
|
||||
*/
|
||||
springCoefficient: number;
|
||||
|
||||
/**
|
||||
* Coulomb's law coefficient. It's used to repel nodes thus should be negative
|
||||
* if you make it positive nodes start attract each other :).
|
||||
*/
|
||||
gravity: number;
|
||||
|
||||
/**
|
||||
* Theta coefficient from Barnes Hut simulation. Ranged between (0, 1).
|
||||
* The closer it's to 1 the more nodes algorithm will have to go through.
|
||||
* Setting it to one makes Barnes Hut simulation no different from
|
||||
* brute-force forces calculation (each node is considered).
|
||||
*/
|
||||
theta: number;
|
||||
|
||||
/**
|
||||
* Drag force coefficient. Used to slow down system, thus should be less than 1.
|
||||
* The closer it is to 0 the less tight system will be.
|
||||
*/
|
||||
dragCoefficient: number;
|
||||
|
||||
/**
|
||||
* Default time step (dt) for forces integration
|
||||
*/
|
||||
timeStep: number;
|
||||
|
||||
/**
|
||||
* Adaptive time step uses average spring length to compute actual time step:
|
||||
* See: https://twitter.com/anvaka/status/1293067160755957760
|
||||
*/
|
||||
adaptiveTimeStepWeight: number;
|
||||
|
||||
/**
|
||||
* This parameter defines number of dimensions of the space where simulation
|
||||
* is performed.
|
||||
*/
|
||||
dimensions: number;
|
||||
|
||||
/**
|
||||
* In debug mode more checks are performed, this will help you catch errors
|
||||
* quickly, however for production build it is recommended to turn off this flag
|
||||
* to speed up computation.
|
||||
*/
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages a simulation of physical forces acting on bodies and springs.
|
||||
*/
|
||||
export interface PhysicsSimulator {
|
||||
/**
|
||||
* Array of bodies, registered with current simulator
|
||||
*
|
||||
* Note: To add new body, use addBody() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
bodies: Body[];
|
||||
|
||||
quadTree: QuadTree;
|
||||
|
||||
/**
|
||||
* Array of springs, registered with current simulator
|
||||
*
|
||||
* Note: To add new spring, use addSpring() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
springs: Spring[];
|
||||
|
||||
/**
|
||||
* Returns settings with which current simulator was initialized
|
||||
*/
|
||||
settings: PhysicsSettings;
|
||||
|
||||
/**
|
||||
* Adds a new force to simulation
|
||||
* @param forceName force identifier
|
||||
* @param forceFunction the function to apply
|
||||
*/
|
||||
addForce(forceName: string, forceFunction: ForceFunction): void;
|
||||
|
||||
/**
|
||||
* Removes a force from the simulation
|
||||
* @param forceName force identifier
|
||||
*/
|
||||
removeForce(forceName: string): void;
|
||||
|
||||
/**
|
||||
* Returns a map of all registered forces
|
||||
*/
|
||||
getForces(): Map<string, ForceFunction>;
|
||||
|
||||
/**
|
||||
* Performs one step of force simulation.
|
||||
*
|
||||
* @returns true if system is considered stable; False otherwise.
|
||||
*/
|
||||
step(): boolean;
|
||||
|
||||
/**
|
||||
* Adds body to the system
|
||||
* @param body physical body
|
||||
* @returns added body
|
||||
*/
|
||||
addBody(body: Body): Body;
|
||||
|
||||
/**
|
||||
* Adds body to the system at given position
|
||||
* @param pos position of a body
|
||||
* @returns added body
|
||||
*/
|
||||
addBodyAt(pos: Vector): Body;
|
||||
|
||||
/**
|
||||
* Removes body from the system
|
||||
* @param body to remove
|
||||
* @returns true if body found and removed. falsy otherwise;
|
||||
*/
|
||||
removeBody(body: Body): boolean;
|
||||
|
||||
/**
|
||||
* Adds a spring to this simulation
|
||||
* @param body1 first body
|
||||
* @param body2 second body
|
||||
* @param springLength Ideal length for links
|
||||
* @param springCoefficient Hook's law coefficient. 1 - solid spring
|
||||
* @returns a handle for a spring. If you want to later remove
|
||||
* spring pass it to removeSpring() method.
|
||||
*/
|
||||
addSpring(body1: Body, body2: Body, springLength: number, springCoefficient: number): Spring;
|
||||
|
||||
/**
|
||||
* Returns amount of movement performed on last step() call
|
||||
*/
|
||||
getTotalMovement(): number;
|
||||
|
||||
/**
|
||||
* Removes spring from the system
|
||||
* @param spring to remove. Spring is an object returned by addSpring
|
||||
* @returns true if spring found and removed. falsy otherwise;
|
||||
*/
|
||||
removeSpring(spring: Spring): boolean;
|
||||
|
||||
getBestNewBodyPosition(neighbors: Body[]): Vector;
|
||||
|
||||
/**
|
||||
* Returns bounding box which covers all bodies
|
||||
*/
|
||||
getBBox(): BoundingBox;
|
||||
|
||||
/**
|
||||
* Returns bounding box which covers all bodies
|
||||
*/
|
||||
getBoundingBox(): BoundingBox;
|
||||
|
||||
/** @deprecated invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call */
|
||||
invalidateBBox(): void;
|
||||
|
||||
/**
|
||||
* Changes the gravity for the system
|
||||
* @param value Coulomb's law coefficient
|
||||
*/
|
||||
gravity(value: number): number;
|
||||
|
||||
/**
|
||||
* Changes the theta coeffitient for the system
|
||||
* @param value Theta coefficient from Barnes Hut simulation
|
||||
*/
|
||||
theta(value: number): number;
|
||||
|
||||
// TODO: create types declaration file for ngraph.random
|
||||
/**
|
||||
* Returns pseudo-random number generator instance
|
||||
*/
|
||||
random: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force based layout for a given graph.
|
||||
*/
|
||||
export interface Layout<T extends Graph> {
|
||||
/**
|
||||
* Performs one step of iterative layout algorithm
|
||||
* @returns true if the system should be considered stable; False otherwise.
|
||||
* The system is stable if no further call to `step()` can improve the layout.
|
||||
*/
|
||||
step(): boolean;
|
||||
|
||||
/**
|
||||
* For a given `nodeId` returns position
|
||||
* @param nodeId node identifier
|
||||
*/
|
||||
getNodePosition(nodeId: NodeId): Vector;
|
||||
|
||||
/**
|
||||
* Sets position of a node to a given coordinates
|
||||
* @param nodeId node identifier
|
||||
* @param x position of a node
|
||||
* @param y position of a node
|
||||
* @param z position of node (only if applicable to body)
|
||||
*/
|
||||
setNodePosition(nodeId: NodeId, x: number, y: number, z?: number, ...c: number[]): void;
|
||||
|
||||
/**
|
||||
* Gets Link position by link id
|
||||
* @param linkId link identifier
|
||||
* @returns from: {x, y} coordinates of link start
|
||||
* @returns to: {x, y} coordinates of link end
|
||||
*/
|
||||
getLinkPosition(linkId: LinkId): { from: Vector; to: Vector };
|
||||
|
||||
/**
|
||||
* @returns area required to fit in the graph. Object contains
|
||||
* `x1`, `y1` - top left coordinates
|
||||
* `x2`, `y2` - bottom right coordinates
|
||||
*/
|
||||
getGraphRect(): { x1: number; y1: number; x2: number; y2: number };
|
||||
|
||||
/**
|
||||
* Iterates over each body in the layout simulator and performs a callback(body, nodeId)
|
||||
* @param callbackfn the callback function
|
||||
*/
|
||||
forEachBody(callbackfn: (value: Body, key: NodeId, map: Map<NodeId, Body>) => void): void;
|
||||
|
||||
/**
|
||||
* Requests layout algorithm to pin/unpin node to its current position
|
||||
* Pinned nodes should not be affected by layout algorithm and always
|
||||
* remain at their position
|
||||
* @param node the node to pin/unpin
|
||||
* @param isPinned true to pin, false to unpin
|
||||
*/
|
||||
pinNode(node: Node, isPinned: boolean): void;
|
||||
|
||||
/**
|
||||
* Checks whether given graph's node is currently pinned
|
||||
* @param node the node to check
|
||||
*/
|
||||
isNodePinned(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Request to release all resources
|
||||
*/
|
||||
dispose(): void;
|
||||
|
||||
/**
|
||||
* Gets physical body for a given node id. If node is not found undefined
|
||||
* value is returned.
|
||||
* @param nodeId node identifier
|
||||
*/
|
||||
getBody(nodeId: NodeId): Body | undefined;
|
||||
|
||||
/**
|
||||
* Gets spring for a given edge.
|
||||
*
|
||||
* @param linkId link identifer.
|
||||
*/
|
||||
getSpring(linkId: LinkId | Link): Spring;
|
||||
|
||||
/**
|
||||
* Gets spring for a given edge.
|
||||
*
|
||||
* @param fromId node identifer - tail of the link
|
||||
* @param toId head of the link - head of the link
|
||||
*/
|
||||
getSpring(fromId: NodeId, toId: NodeId): Spring | undefined;
|
||||
|
||||
/**
|
||||
* Returns length of cumulative force vector. The closer this to zero - the more stable the system is
|
||||
*/
|
||||
getForceVectorLength(): number;
|
||||
|
||||
/**
|
||||
* @readonly Gets current physics simulator
|
||||
*/
|
||||
readonly simulator: PhysicsSimulator;
|
||||
|
||||
/**
|
||||
* Gets the graph that was used for layout
|
||||
*/
|
||||
graph: T;
|
||||
|
||||
/**
|
||||
* Gets amount of movement performed during last step operation
|
||||
*/
|
||||
lastMove: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates force based layout for a given graph.
|
||||
*
|
||||
* @param graph which needs to be laid out
|
||||
* @param physicsSettings if you need custom settings
|
||||
* for physics simulator you can pass your own settings here. If it's not passed
|
||||
* a default one will be created.
|
||||
*/
|
||||
export default function createLayout<T extends Graph>(
|
||||
graph: T,
|
||||
physicsSettings?: Partial<PhysicsSettings>
|
||||
): Layout<T> & EventedType;
|
||||
}
|
||||
399
VISUALIZACION/node_modules/ngraph.forcelayout/index.js
generated
vendored
Executable file
399
VISUALIZACION/node_modules/ngraph.forcelayout/index.js
generated
vendored
Executable file
|
|
@ -0,0 +1,399 @@
|
|||
module.exports = createLayout;
|
||||
module.exports.simulator = require('./lib/createPhysicsSimulator');
|
||||
|
||||
var eventify = require('ngraph.events');
|
||||
|
||||
/**
|
||||
* Creates force based layout for a given graph.
|
||||
*
|
||||
* @param {ngraph.graph} graph which needs to be laid out
|
||||
* @param {object} physicsSettings if you need custom settings
|
||||
* for physics simulator you can pass your own settings here. If it's not passed
|
||||
* a default one will be created.
|
||||
*/
|
||||
function createLayout(graph, physicsSettings) {
|
||||
if (!graph) {
|
||||
throw new Error('Graph structure cannot be undefined');
|
||||
}
|
||||
|
||||
var createSimulator = (physicsSettings && physicsSettings.createSimulator) || require('./lib/createPhysicsSimulator');
|
||||
var physicsSimulator = createSimulator(physicsSettings);
|
||||
if (Array.isArray(physicsSettings)) throw new Error('Physics settings is expected to be an object');
|
||||
|
||||
var nodeMass = graph.version > 19 ? defaultSetNodeMass : defaultArrayNodeMass;
|
||||
if (physicsSettings && typeof physicsSettings.nodeMass === 'function') {
|
||||
nodeMass = physicsSettings.nodeMass;
|
||||
}
|
||||
|
||||
var nodeBodies = new Map();
|
||||
var springs = {};
|
||||
var bodiesCount = 0;
|
||||
|
||||
var springTransform = physicsSimulator.settings.springTransform || noop;
|
||||
|
||||
// Initialize physics with what we have in the graph:
|
||||
initPhysics();
|
||||
listenToEvents();
|
||||
|
||||
var wasStable = false;
|
||||
|
||||
var api = {
|
||||
/**
|
||||
* Performs one step of iterative layout algorithm
|
||||
*
|
||||
* @returns {boolean} true if the system should be considered stable; False otherwise.
|
||||
* The system is stable if no further call to `step()` can improve the layout.
|
||||
*/
|
||||
step: function() {
|
||||
if (bodiesCount === 0) {
|
||||
updateStableStatus(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
var lastMove = physicsSimulator.step();
|
||||
|
||||
// Save the movement in case if someone wants to query it in the step
|
||||
// callback.
|
||||
api.lastMove = lastMove;
|
||||
|
||||
// Allow listeners to perform low-level actions after nodes are updated.
|
||||
api.fire('step');
|
||||
|
||||
var ratio = lastMove/bodiesCount;
|
||||
var isStableNow = ratio <= 0.01; // TODO: The number is somewhat arbitrary...
|
||||
updateStableStatus(isStableNow);
|
||||
|
||||
|
||||
return isStableNow;
|
||||
},
|
||||
|
||||
/**
|
||||
* For a given `nodeId` returns position
|
||||
*/
|
||||
getNodePosition: function (nodeId) {
|
||||
return getInitializedBody(nodeId).pos;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets position of a node to a given coordinates
|
||||
* @param {string} nodeId node identifier
|
||||
* @param {number} x position of a node
|
||||
* @param {number} y position of a node
|
||||
* @param {number=} z position of node (only if applicable to body)
|
||||
*/
|
||||
setNodePosition: function (nodeId) {
|
||||
var body = getInitializedBody(nodeId);
|
||||
body.setPosition.apply(body, Array.prototype.slice.call(arguments, 1));
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Object} Link position by link id
|
||||
* @returns {Object.from} {x, y} coordinates of link start
|
||||
* @returns {Object.to} {x, y} coordinates of link end
|
||||
*/
|
||||
getLinkPosition: function (linkId) {
|
||||
var spring = springs[linkId];
|
||||
if (spring) {
|
||||
return {
|
||||
from: spring.from.pos,
|
||||
to: spring.to.pos
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Object} area required to fit in the graph. Object contains
|
||||
* `x1`, `y1` - top left coordinates
|
||||
* `x2`, `y2` - bottom right coordinates
|
||||
*/
|
||||
getGraphRect: function () {
|
||||
return physicsSimulator.getBBox();
|
||||
},
|
||||
|
||||
/**
|
||||
* Iterates over each body in the layout simulator and performs a callback(body, nodeId)
|
||||
*/
|
||||
forEachBody: forEachBody,
|
||||
|
||||
/*
|
||||
* Requests layout algorithm to pin/unpin node to its current position
|
||||
* Pinned nodes should not be affected by layout algorithm and always
|
||||
* remain at their position
|
||||
*/
|
||||
pinNode: function (node, isPinned) {
|
||||
var body = getInitializedBody(node.id);
|
||||
body.isPinned = !!isPinned;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether given graph's node is currently pinned
|
||||
*/
|
||||
isNodePinned: function (node) {
|
||||
return getInitializedBody(node.id).isPinned;
|
||||
},
|
||||
|
||||
/**
|
||||
* Request to release all resources
|
||||
*/
|
||||
dispose: function() {
|
||||
graph.off('changed', onGraphChanged);
|
||||
api.fire('disposed');
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets physical body for a given node id. If node is not found undefined
|
||||
* value is returned.
|
||||
*/
|
||||
getBody: getBody,
|
||||
|
||||
/**
|
||||
* Gets spring for a given edge.
|
||||
*
|
||||
* @param {string} linkId link identifer. If two arguments are passed then
|
||||
* this argument is treated as formNodeId
|
||||
* @param {string=} toId when defined this parameter denotes head of the link
|
||||
* and first argument is treated as tail of the link (fromId)
|
||||
*/
|
||||
getSpring: getSpring,
|
||||
|
||||
/**
|
||||
* Returns length of cumulative force vector. The closer this to zero - the more stable the system is
|
||||
*/
|
||||
getForceVectorLength: getForceVectorLength,
|
||||
|
||||
/**
|
||||
* [Read only] Gets current physics simulator
|
||||
*/
|
||||
simulator: physicsSimulator,
|
||||
|
||||
/**
|
||||
* Gets the graph that was used for layout
|
||||
*/
|
||||
graph: graph,
|
||||
|
||||
/**
|
||||
* Gets amount of movement performed during last step operation
|
||||
*/
|
||||
lastMove: 0
|
||||
};
|
||||
|
||||
eventify(api);
|
||||
|
||||
return api;
|
||||
|
||||
function updateStableStatus(isStableNow) {
|
||||
if (wasStable !== isStableNow) {
|
||||
wasStable = isStableNow;
|
||||
onStableChanged(isStableNow);
|
||||
}
|
||||
}
|
||||
|
||||
function forEachBody(cb) {
|
||||
nodeBodies.forEach(cb);
|
||||
}
|
||||
|
||||
function getForceVectorLength() {
|
||||
var fx = 0, fy = 0;
|
||||
forEachBody(function(body) {
|
||||
fx += Math.abs(body.force.x);
|
||||
fy += Math.abs(body.force.y);
|
||||
});
|
||||
return Math.sqrt(fx * fx + fy * fy);
|
||||
}
|
||||
|
||||
function getSpring(fromId, toId) {
|
||||
var linkId;
|
||||
if (toId === undefined) {
|
||||
if (typeof fromId !== 'object') {
|
||||
// assume fromId as a linkId:
|
||||
linkId = fromId;
|
||||
} else {
|
||||
// assume fromId to be a link object:
|
||||
linkId = fromId.id;
|
||||
}
|
||||
} else {
|
||||
// toId is defined, should grab link:
|
||||
var link = graph.hasLink(fromId, toId);
|
||||
if (!link) return;
|
||||
linkId = link.id;
|
||||
}
|
||||
|
||||
return springs[linkId];
|
||||
}
|
||||
|
||||
function getBody(nodeId) {
|
||||
return nodeBodies.get(nodeId);
|
||||
}
|
||||
|
||||
function listenToEvents() {
|
||||
graph.on('changed', onGraphChanged);
|
||||
}
|
||||
|
||||
function onStableChanged(isStable) {
|
||||
api.fire('stable', isStable);
|
||||
}
|
||||
|
||||
function onGraphChanged(changes) {
|
||||
for (var i = 0; i < changes.length; ++i) {
|
||||
var change = changes[i];
|
||||
if (change.changeType === 'add') {
|
||||
if (change.node) {
|
||||
initBody(change.node.id);
|
||||
}
|
||||
if (change.link) {
|
||||
initLink(change.link);
|
||||
}
|
||||
} else if (change.changeType === 'remove') {
|
||||
if (change.node) {
|
||||
releaseNode(change.node);
|
||||
}
|
||||
if (change.link) {
|
||||
releaseLink(change.link);
|
||||
}
|
||||
}
|
||||
}
|
||||
bodiesCount = graph.getNodesCount();
|
||||
}
|
||||
|
||||
function initPhysics() {
|
||||
bodiesCount = 0;
|
||||
|
||||
graph.forEachNode(function (node) {
|
||||
initBody(node.id);
|
||||
bodiesCount += 1;
|
||||
});
|
||||
|
||||
graph.forEachLink(initLink);
|
||||
}
|
||||
|
||||
function initBody(nodeId) {
|
||||
var body = nodeBodies.get(nodeId);
|
||||
if (!body) {
|
||||
var node = graph.getNode(nodeId);
|
||||
if (!node) {
|
||||
throw new Error('initBody() was called with unknown node id');
|
||||
}
|
||||
|
||||
var pos = node.position;
|
||||
if (!pos) {
|
||||
var neighbors = getNeighborBodies(node);
|
||||
pos = physicsSimulator.getBestNewBodyPosition(neighbors);
|
||||
}
|
||||
|
||||
body = physicsSimulator.addBodyAt(pos);
|
||||
body.id = nodeId;
|
||||
|
||||
nodeBodies.set(nodeId, body);
|
||||
updateBodyMass(nodeId);
|
||||
|
||||
if (isNodeOriginallyPinned(node)) {
|
||||
body.isPinned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function releaseNode(node) {
|
||||
var nodeId = node.id;
|
||||
var body = nodeBodies.get(nodeId);
|
||||
if (body) {
|
||||
nodeBodies.delete(nodeId);
|
||||
physicsSimulator.removeBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
function initLink(link) {
|
||||
updateBodyMass(link.fromId);
|
||||
updateBodyMass(link.toId);
|
||||
|
||||
var fromBody = nodeBodies.get(link.fromId),
|
||||
toBody = nodeBodies.get(link.toId),
|
||||
spring = physicsSimulator.addSpring(fromBody, toBody, link.length);
|
||||
|
||||
springTransform(link, spring);
|
||||
|
||||
springs[link.id] = spring;
|
||||
}
|
||||
|
||||
function releaseLink(link) {
|
||||
var spring = springs[link.id];
|
||||
if (spring) {
|
||||
var from = graph.getNode(link.fromId),
|
||||
to = graph.getNode(link.toId);
|
||||
|
||||
if (from) updateBodyMass(from.id);
|
||||
if (to) updateBodyMass(to.id);
|
||||
|
||||
delete springs[link.id];
|
||||
|
||||
physicsSimulator.removeSpring(spring);
|
||||
}
|
||||
}
|
||||
|
||||
function getNeighborBodies(node) {
|
||||
// TODO: Could probably be done better on memory
|
||||
var neighbors = [];
|
||||
if (!node.links) {
|
||||
return neighbors;
|
||||
}
|
||||
var maxNeighbors = Math.min(node.links.length, 2);
|
||||
for (var i = 0; i < maxNeighbors; ++i) {
|
||||
var link = node.links[i];
|
||||
var otherBody = link.fromId !== node.id ? nodeBodies.get(link.fromId) : nodeBodies.get(link.toId);
|
||||
if (otherBody && otherBody.pos) {
|
||||
neighbors.push(otherBody);
|
||||
}
|
||||
}
|
||||
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
function updateBodyMass(nodeId) {
|
||||
var body = nodeBodies.get(nodeId);
|
||||
body.mass = nodeMass(nodeId);
|
||||
if (Number.isNaN(body.mass)) {
|
||||
throw new Error('Node mass should be a number');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether graph node has in its settings pinned attribute,
|
||||
* which means layout algorithm cannot move it. Node can be marked
|
||||
* as pinned, if it has "isPinned" attribute, or when node.data has it.
|
||||
*
|
||||
* @param {Object} node a graph node to check
|
||||
* @return {Boolean} true if node should be treated as pinned; false otherwise.
|
||||
*/
|
||||
function isNodeOriginallyPinned(node) {
|
||||
return (node && (node.isPinned || (node.data && node.data.isPinned)));
|
||||
}
|
||||
|
||||
function getInitializedBody(nodeId) {
|
||||
var body = nodeBodies.get(nodeId);
|
||||
if (!body) {
|
||||
initBody(nodeId);
|
||||
body = nodeBodies.get(nodeId);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates mass of a body, which corresponds to node with given id.
|
||||
*
|
||||
* @param {String|Number} nodeId identifier of a node, for which body mass needs to be calculated
|
||||
* @returns {Number} recommended mass of the body;
|
||||
*/
|
||||
function defaultArrayNodeMass(nodeId) {
|
||||
// This function is for older versions of ngraph.graph.
|
||||
var links = graph.getLinks(nodeId);
|
||||
if (!links) return 1;
|
||||
return 1 + links.length / 3.0;
|
||||
}
|
||||
|
||||
function defaultSetNodeMass(nodeId) {
|
||||
var links = graph.getLinks(nodeId);
|
||||
if (!links) return 1;
|
||||
return 1 + links.size / 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
function noop() { }
|
||||
369
VISUALIZACION/node_modules/ngraph.forcelayout/index.v43.d.ts
generated
vendored
Executable file
369
VISUALIZACION/node_modules/ngraph.forcelayout/index.v43.d.ts
generated
vendored
Executable file
|
|
@ -0,0 +1,369 @@
|
|||
declare module "ngraph.forcelayout" {
|
||||
import { Graph, NodeId, LinkId, Node, Link } from "ngraph.graph";
|
||||
import { EventedType } from "ngraph.events";
|
||||
|
||||
export type ForceFunction = (iterationNumber: number) => void;
|
||||
|
||||
export interface Vector {
|
||||
x: number;
|
||||
y: number;
|
||||
z?: number;
|
||||
[coord: string]: number | undefined;
|
||||
}
|
||||
|
||||
export interface Body {
|
||||
isPinned: boolean;
|
||||
pos: Vector;
|
||||
force: Vector;
|
||||
velocity: Vector;
|
||||
mass: number;
|
||||
springCount: number;
|
||||
springLength: number;
|
||||
reset(): void;
|
||||
setPosition(x: number, y: number, z?: number, ...c: number[]): void;
|
||||
}
|
||||
|
||||
export interface Spring {
|
||||
from: Body;
|
||||
to: Body;
|
||||
length: number;
|
||||
coefficient: number;
|
||||
}
|
||||
|
||||
export interface QuadNode {
|
||||
body: Body | null;
|
||||
mass: number;
|
||||
mass_x: number;
|
||||
mass_y: number;
|
||||
mass_z?: number;
|
||||
}
|
||||
|
||||
export interface QuadTree {
|
||||
insertBodies(bodies: Body[]): void;
|
||||
getRoot(): QuadNode & Record<string, number | null>;
|
||||
updateBodyForce(sourceBody: Body): void;
|
||||
options(newOptions: { gravity: number; theta: number }): { gravity: number; theta: number };
|
||||
}
|
||||
|
||||
export interface BoundingBox {
|
||||
min_x: number;
|
||||
max_x: number;
|
||||
min_y: number;
|
||||
max_y: number;
|
||||
min_z?: number;
|
||||
max_z?: number;
|
||||
[min_max: string]: number | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings for a PhysicsSimulator
|
||||
*/
|
||||
export interface PhysicsSettings {
|
||||
/**
|
||||
* Ideal length for links (springs in physical model).
|
||||
*/
|
||||
springLength: number;
|
||||
|
||||
/**
|
||||
* Hook's law coefficient. 1 - solid spring.
|
||||
*/
|
||||
springCoefficient: number;
|
||||
|
||||
/**
|
||||
* Coulomb's law coefficient. It's used to repel nodes thus should be negative
|
||||
* if you make it positive nodes start attract each other :).
|
||||
*/
|
||||
gravity: number;
|
||||
|
||||
/**
|
||||
* Theta coefficient from Barnes Hut simulation. Ranged between (0, 1).
|
||||
* The closer it's to 1 the more nodes algorithm will have to go through.
|
||||
* Setting it to one makes Barnes Hut simulation no different from
|
||||
* brute-force forces calculation (each node is considered).
|
||||
*/
|
||||
theta: number;
|
||||
|
||||
/**
|
||||
* Drag force coefficient. Used to slow down system, thus should be less than 1.
|
||||
* The closer it is to 0 the less tight system will be.
|
||||
*/
|
||||
dragCoefficient: number;
|
||||
|
||||
/**
|
||||
* Default time step (dt) for forces integration
|
||||
*/
|
||||
timeStep: number;
|
||||
|
||||
/**
|
||||
* Adaptive time step uses average spring length to compute actual time step:
|
||||
* See: https://twitter.com/anvaka/status/1293067160755957760
|
||||
*/
|
||||
adaptiveTimeStepWeight: number;
|
||||
|
||||
/**
|
||||
* This parameter defines number of dimensions of the space where simulation
|
||||
* is performed.
|
||||
*/
|
||||
dimensions: number;
|
||||
|
||||
/**
|
||||
* In debug mode more checks are performed, this will help you catch errors
|
||||
* quickly, however for production build it is recommended to turn off this flag
|
||||
* to speed up computation.
|
||||
*/
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages a simulation of physical forces acting on bodies and springs.
|
||||
*/
|
||||
export interface PhysicsSimulator {
|
||||
/**
|
||||
* Array of bodies, registered with current simulator
|
||||
*
|
||||
* Note: To add new body, use addBody() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
bodies: Body[];
|
||||
|
||||
quadTree: QuadTree;
|
||||
|
||||
/**
|
||||
* Array of springs, registered with current simulator
|
||||
*
|
||||
* Note: To add new spring, use addSpring() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
springs: Spring[];
|
||||
|
||||
/**
|
||||
* Returns settings with which current simulator was initialized
|
||||
*/
|
||||
settings: PhysicsSettings;
|
||||
|
||||
/**
|
||||
* Adds a new force to simulation
|
||||
* @param forceName force identifier
|
||||
* @param forceFunction the function to apply
|
||||
*/
|
||||
addForce(forceName: string, forceFunction: ForceFunction): void;
|
||||
|
||||
/**
|
||||
* Removes a force from the simulation
|
||||
* @param forceName force identifier
|
||||
*/
|
||||
removeForce(forceName: string): void;
|
||||
|
||||
/**
|
||||
* Returns a map of all registered forces
|
||||
*/
|
||||
getForces(): Map<string, ForceFunction>;
|
||||
|
||||
/**
|
||||
* Performs one step of force simulation.
|
||||
*
|
||||
* @returns true if system is considered stable; False otherwise.
|
||||
*/
|
||||
step(): boolean;
|
||||
|
||||
/**
|
||||
* Adds body to the system
|
||||
* @param body physical body
|
||||
* @returns added body
|
||||
*/
|
||||
addBody(body: Body): Body;
|
||||
|
||||
/**
|
||||
* Adds body to the system at given position
|
||||
* @param pos position of a body
|
||||
* @returns added body
|
||||
*/
|
||||
addBodyAt(pos: Vector): Body;
|
||||
|
||||
/**
|
||||
* Removes body from the system
|
||||
* @param body to remove
|
||||
* @returns true if body found and removed. falsy otherwise;
|
||||
*/
|
||||
removeBody(body: Body): boolean;
|
||||
|
||||
/**
|
||||
* Adds a spring to this simulation
|
||||
* @param body1 first body
|
||||
* @param body2 second body
|
||||
* @param springLength Ideal length for links
|
||||
* @param springCoefficient Hook's law coefficient. 1 - solid spring
|
||||
* @returns a handle for a spring. If you want to later remove
|
||||
* spring pass it to removeSpring() method.
|
||||
*/
|
||||
addSpring(body1: Body, body2: Body, springLength: number, springCoefficient: number): Spring;
|
||||
|
||||
/**
|
||||
* Returns amount of movement performed on last step() call
|
||||
*/
|
||||
getTotalMovement(): number;
|
||||
|
||||
/**
|
||||
* Removes spring from the system
|
||||
* @param spring to remove. Spring is an object returned by addSpring
|
||||
* @returns true if spring found and removed. falsy otherwise;
|
||||
*/
|
||||
removeSpring(spring: Spring): boolean;
|
||||
|
||||
getBestNewBodyPosition(neighbors: Body[]): Vector;
|
||||
|
||||
/**
|
||||
* Returns bounding box which covers all bodies
|
||||
*/
|
||||
getBBox(): BoundingBox;
|
||||
|
||||
/**
|
||||
* Returns bounding box which covers all bodies
|
||||
*/
|
||||
getBoundingBox(): BoundingBox;
|
||||
|
||||
/** @deprecated invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call */
|
||||
invalidateBBox(): void;
|
||||
|
||||
/**
|
||||
* Changes the gravity for the system
|
||||
* @param value Coulomb's law coefficient
|
||||
*/
|
||||
gravity(value: number): number;
|
||||
|
||||
/**
|
||||
* Changes the theta coeffitient for the system
|
||||
* @param value Theta coefficient from Barnes Hut simulation
|
||||
*/
|
||||
theta(value: number): number;
|
||||
|
||||
// TODO: create types declaration file for ngraph.random
|
||||
/**
|
||||
* Returns pseudo-random number generator instance
|
||||
*/
|
||||
random: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force based layout for a given graph.
|
||||
*/
|
||||
export interface Layout<T extends Graph> {
|
||||
/**
|
||||
* Performs one step of iterative layout algorithm
|
||||
* @returns true if the system should be considered stable; False otherwise.
|
||||
* The system is stable if no further call to `step()` can improve the layout.
|
||||
*/
|
||||
step(): boolean;
|
||||
|
||||
/**
|
||||
* For a given `nodeId` returns position
|
||||
* @param nodeId node identifier
|
||||
*/
|
||||
getNodePosition(nodeId: NodeId): Vector;
|
||||
|
||||
/**
|
||||
* Sets position of a node to a given coordinates
|
||||
* @param nodeId node identifier
|
||||
* @param x position of a node
|
||||
* @param y position of a node
|
||||
* @param z position of node (only if applicable to body)
|
||||
*/
|
||||
setNodePosition(nodeId: NodeId, x: number, y: number, z?: number, ...c: number[]): void;
|
||||
|
||||
/**
|
||||
* Gets Link position by link id
|
||||
* @param linkId link identifier
|
||||
* @returns from: {x, y} coordinates of link start
|
||||
* @returns to: {x, y} coordinates of link end
|
||||
*/
|
||||
getLinkPosition(linkId: LinkId): { from: Vector; to: Vector };
|
||||
|
||||
/**
|
||||
* @returns area required to fit in the graph. Object contains
|
||||
* `x1`, `y1` - top left coordinates
|
||||
* `x2`, `y2` - bottom right coordinates
|
||||
*/
|
||||
getGraphRect(): { x1: number; y1: number; x2: number; y2: number };
|
||||
|
||||
/**
|
||||
* Iterates over each body in the layout simulator and performs a callback(body, nodeId)
|
||||
* @param callbackfn the callback function
|
||||
*/
|
||||
forEachBody(callbackfn: (value: Body, key: NodeId, map: Map<NodeId, Body>) => void): void;
|
||||
|
||||
/**
|
||||
* Requests layout algorithm to pin/unpin node to its current position
|
||||
* Pinned nodes should not be affected by layout algorithm and always
|
||||
* remain at their position
|
||||
* @param node the node to pin/unpin
|
||||
* @param isPinned true to pin, false to unpin
|
||||
*/
|
||||
pinNode(node: Node, isPinned: boolean): void;
|
||||
|
||||
/**
|
||||
* Checks whether given graph's node is currently pinned
|
||||
* @param node the node to check
|
||||
*/
|
||||
isNodePinned(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Request to release all resources
|
||||
*/
|
||||
dispose(): void;
|
||||
|
||||
/**
|
||||
* Gets physical body for a given node id. If node is not found undefined
|
||||
* value is returned.
|
||||
* @param nodeId node identifier
|
||||
*/
|
||||
getBody(nodeId: NodeId): Body | undefined;
|
||||
|
||||
/**
|
||||
* Gets spring for a given edge.
|
||||
*
|
||||
* @param linkId link identifer.
|
||||
*/
|
||||
getSpring(linkId: LinkId | Link): Spring;
|
||||
|
||||
/**
|
||||
* Gets spring for a given edge.
|
||||
*
|
||||
* @param fromId node identifer - tail of the link
|
||||
* @param toId head of the link - head of the link
|
||||
*/
|
||||
getSpring(fromId: NodeId, toId: NodeId): Spring | undefined;
|
||||
|
||||
/**
|
||||
* Returns length of cumulative force vector. The closer this to zero - the more stable the system is
|
||||
*/
|
||||
getForceVectorLength(): number;
|
||||
|
||||
/**
|
||||
* @readonly Gets current physics simulator
|
||||
*/
|
||||
readonly simulator: PhysicsSimulator;
|
||||
|
||||
/**
|
||||
* Gets the graph that was used for layout
|
||||
*/
|
||||
graph: T;
|
||||
|
||||
/**
|
||||
* Gets amount of movement performed during last step operation
|
||||
*/
|
||||
lastMove: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates force based layout for a given graph.
|
||||
*
|
||||
* @param graph which needs to be laid out
|
||||
* @param physicsSettings if you need custom settings
|
||||
* for physics simulator you can pass your own settings here. If it's not passed
|
||||
* a default one will be created.
|
||||
*/
|
||||
export default function createLayout<T extends Graph>(
|
||||
graph: T,
|
||||
physicsSettings?: Partial<PhysicsSettings>
|
||||
): Layout<T> & EventedType;
|
||||
}
|
||||
23
VISUALIZACION/node_modules/ngraph.forcelayout/inline-transform.js
generated
vendored
Executable file
23
VISUALIZACION/node_modules/ngraph.forcelayout/inline-transform.js
generated
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
var through = require('through2');
|
||||
|
||||
module.exports = function (file) {
|
||||
return through(function (buf, enc, next) {
|
||||
let originalContent = buf.toString('utf8');
|
||||
let dimensions = 2; // change this if you need different number of dimensions
|
||||
if (file.match(/codeGenerators\/generate/)) {
|
||||
let content = require(file);
|
||||
let matches = originalContent.match(/^\/\/ InlineTransform: (.+)$/gm);
|
||||
let additionalTransform = matches ? matches.map(name => {
|
||||
let f = name.substr('// InlineTransform: '.length);
|
||||
return content[f](dimensions);
|
||||
}).join('\n') : '';
|
||||
let exportCodeMatch = originalContent.match(/^\/\/ InlineTransformExport: (.+)$/m);
|
||||
let codeExport = exportCodeMatch ? exportCodeMatch[1] :
|
||||
`module.exports = function() { return ${content(dimensions).toString()} }`;
|
||||
this.push(`${additionalTransform}\n${codeExport}`);
|
||||
} else {
|
||||
this.push(originalContent);
|
||||
}
|
||||
next();
|
||||
});
|
||||
};
|
||||
3
VISUALIZACION/node_modules/ngraph.forcelayout/lib/bounds.js
generated
vendored
Executable file
3
VISUALIZACION/node_modules/ngraph.forcelayout/lib/bounds.js
generated
vendored
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
const generateBoundsFunction = require('./codeGenerators/generateBounds');
|
||||
|
||||
module.exports = generateBoundsFunction(2);
|
||||
19
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/createPatternBuilder.js
generated
vendored
Executable file
19
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/createPatternBuilder.js
generated
vendored
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
const getVariableName = require('./getVariableName');
|
||||
|
||||
module.exports = function createPatternBuilder(dimension) {
|
||||
|
||||
return pattern;
|
||||
|
||||
function pattern(template, config) {
|
||||
let indent = (config && config.indent) || 0;
|
||||
let join = (config && config.join !== undefined) ? config.join : '\n';
|
||||
let indentString = Array(indent + 1).join(' ');
|
||||
let buffer = [];
|
||||
for (let i = 0; i < dimension; ++i) {
|
||||
let variableName = getVariableName(i);
|
||||
let prefix = (i === 0) ? '' : indentString;
|
||||
buffer.push(prefix + template.replace(/{var}/g, variableName));
|
||||
}
|
||||
return buffer.join(join);
|
||||
}
|
||||
};
|
||||
71
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateBounds.js
generated
vendored
Executable file
71
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateBounds.js
generated
vendored
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
module.exports = generateBoundsFunction;
|
||||
module.exports.generateFunctionBody = generateBoundsFunctionBody;
|
||||
|
||||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
|
||||
function generateBoundsFunction(dimension) {
|
||||
let code = generateBoundsFunctionBody(dimension);
|
||||
return new Function('bodies', 'settings', 'random', code);
|
||||
}
|
||||
|
||||
function generateBoundsFunctionBody(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
|
||||
let code = `
|
||||
var boundingBox = {
|
||||
${pattern('min_{var}: 0, max_{var}: 0,', {indent: 4})}
|
||||
};
|
||||
|
||||
return {
|
||||
box: boundingBox,
|
||||
|
||||
update: updateBoundingBox,
|
||||
|
||||
reset: resetBoundingBox,
|
||||
|
||||
getBestNewPosition: function (neighbors) {
|
||||
var ${pattern('base_{var} = 0', {join: ', '})};
|
||||
|
||||
if (neighbors.length) {
|
||||
for (var i = 0; i < neighbors.length; ++i) {
|
||||
let neighborPos = neighbors[i].pos;
|
||||
${pattern('base_{var} += neighborPos.{var};', {indent: 10})}
|
||||
}
|
||||
|
||||
${pattern('base_{var} /= neighbors.length;', {indent: 8})}
|
||||
} else {
|
||||
${pattern('base_{var} = (boundingBox.min_{var} + boundingBox.max_{var}) / 2;', {indent: 8})}
|
||||
}
|
||||
|
||||
var springLength = settings.springLength;
|
||||
return {
|
||||
${pattern('{var}: base_{var} + (random.nextDouble() - 0.5) * springLength,', {indent: 8})}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function updateBoundingBox() {
|
||||
var i = bodies.length;
|
||||
if (i === 0) return; // No bodies - no borders.
|
||||
|
||||
${pattern('var max_{var} = -Infinity;', {indent: 4})}
|
||||
${pattern('var min_{var} = Infinity;', {indent: 4})}
|
||||
|
||||
while(i--) {
|
||||
// this is O(n), it could be done faster with quadtree, if we check the root node bounds
|
||||
var bodyPos = bodies[i].pos;
|
||||
${pattern('if (bodyPos.{var} < min_{var}) min_{var} = bodyPos.{var};', {indent: 6})}
|
||||
${pattern('if (bodyPos.{var} > max_{var}) max_{var} = bodyPos.{var};', {indent: 6})}
|
||||
}
|
||||
|
||||
${pattern('boundingBox.min_{var} = min_{var};', {indent: 4})}
|
||||
${pattern('boundingBox.max_{var} = max_{var};', {indent: 4})}
|
||||
}
|
||||
|
||||
function resetBoundingBox() {
|
||||
${pattern('boundingBox.min_{var} = boundingBox.max_{var} = 0;', {indent: 4})}
|
||||
}
|
||||
`;
|
||||
return code;
|
||||
}
|
||||
85
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateBody.js
generated
vendored
Executable file
85
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateBody.js
generated
vendored
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
|
||||
module.exports = generateCreateBodyFunction;
|
||||
module.exports.generateCreateBodyFunctionBody = generateCreateBodyFunctionBody;
|
||||
|
||||
// InlineTransform: getVectorCode
|
||||
module.exports.getVectorCode = getVectorCode;
|
||||
// InlineTransform: getBodyCode
|
||||
module.exports.getBodyCode = getBodyCode;
|
||||
// InlineTransformExport: module.exports = function() { return Body; }
|
||||
|
||||
function generateCreateBodyFunction(dimension, debugSetters) {
|
||||
let code = generateCreateBodyFunctionBody(dimension, debugSetters);
|
||||
let {Body} = (new Function(code))();
|
||||
return Body;
|
||||
}
|
||||
|
||||
function generateCreateBodyFunctionBody(dimension, debugSetters) {
|
||||
let code = `
|
||||
${getVectorCode(dimension, debugSetters)}
|
||||
${getBodyCode(dimension, debugSetters)}
|
||||
return {Body: Body, Vector: Vector};
|
||||
`;
|
||||
return code;
|
||||
}
|
||||
|
||||
function getBodyCode(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let variableList = pattern('{var}', {join: ', '});
|
||||
return `
|
||||
function Body(${variableList}) {
|
||||
this.isPinned = false;
|
||||
this.pos = new Vector(${variableList});
|
||||
this.force = new Vector();
|
||||
this.velocity = new Vector();
|
||||
this.mass = 1;
|
||||
|
||||
this.springCount = 0;
|
||||
this.springLength = 0;
|
||||
}
|
||||
|
||||
Body.prototype.reset = function() {
|
||||
this.force.reset();
|
||||
this.springCount = 0;
|
||||
this.springLength = 0;
|
||||
}
|
||||
|
||||
Body.prototype.setPosition = function (${variableList}) {
|
||||
${pattern('this.pos.{var} = {var} || 0;', {indent: 2})}
|
||||
};`;
|
||||
}
|
||||
|
||||
function getVectorCode(dimension, debugSetters) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let setters = '';
|
||||
if (debugSetters) {
|
||||
setters = `${pattern("\n\
|
||||
var v{var};\n\
|
||||
Object.defineProperty(this, '{var}', {\n\
|
||||
set: function(v) { \n\
|
||||
if (!Number.isFinite(v)) throw new Error('Cannot set non-numbers to {var}');\n\
|
||||
v{var} = v; \n\
|
||||
},\n\
|
||||
get: function() { return v{var}; }\n\
|
||||
});")}`;
|
||||
}
|
||||
|
||||
let variableList = pattern('{var}', {join: ', '});
|
||||
return `function Vector(${variableList}) {
|
||||
${setters}
|
||||
if (typeof arguments[0] === 'object') {
|
||||
// could be another vector
|
||||
let v = arguments[0];
|
||||
${pattern('if (!Number.isFinite(v.{var})) throw new Error("Expected value is not a finite number at Vector constructor ({var})");', {indent: 4})}
|
||||
${pattern('this.{var} = v.{var};', {indent: 4})}
|
||||
} else {
|
||||
${pattern('this.{var} = typeof {var} === "number" ? {var} : 0;', {indent: 4})}
|
||||
}
|
||||
}
|
||||
|
||||
Vector.prototype.reset = function () {
|
||||
${pattern('this.{var} = ', {join: ''})}0;
|
||||
};`;
|
||||
}
|
||||
23
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateDragForce.js
generated
vendored
Executable file
23
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateDragForce.js
generated
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
|
||||
module.exports = generateCreateDragForceFunction;
|
||||
module.exports.generateCreateDragForceFunctionBody = generateCreateDragForceFunctionBody;
|
||||
|
||||
function generateCreateDragForceFunction(dimension) {
|
||||
let code = generateCreateDragForceFunctionBody(dimension);
|
||||
return new Function('options', code);
|
||||
}
|
||||
|
||||
function generateCreateDragForceFunctionBody(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let code = `
|
||||
if (!Number.isFinite(options.dragCoefficient)) throw new Error('dragCoefficient is not a finite number');
|
||||
|
||||
return {
|
||||
update: function(body) {
|
||||
${pattern('body.force.{var} -= options.dragCoefficient * body.velocity.{var};', {indent: 6})}
|
||||
}
|
||||
};
|
||||
`;
|
||||
return code;
|
||||
}
|
||||
47
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateSpringForce.js
generated
vendored
Executable file
47
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateCreateSpringForce.js
generated
vendored
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
|
||||
module.exports = generateCreateSpringForceFunction;
|
||||
module.exports.generateCreateSpringForceFunctionBody = generateCreateSpringForceFunctionBody;
|
||||
|
||||
function generateCreateSpringForceFunction(dimension) {
|
||||
let code = generateCreateSpringForceFunctionBody(dimension);
|
||||
return new Function('options', 'random', code);
|
||||
}
|
||||
|
||||
function generateCreateSpringForceFunctionBody(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let code = `
|
||||
if (!Number.isFinite(options.springCoefficient)) throw new Error('Spring coefficient is not a number');
|
||||
if (!Number.isFinite(options.springLength)) throw new Error('Spring length is not a number');
|
||||
|
||||
return {
|
||||
/**
|
||||
* Updates forces acting on a spring
|
||||
*/
|
||||
update: function (spring) {
|
||||
var body1 = spring.from;
|
||||
var body2 = spring.to;
|
||||
var length = spring.length < 0 ? options.springLength : spring.length;
|
||||
${pattern('var d{var} = body2.pos.{var} - body1.pos.{var};', {indent: 6})}
|
||||
var r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
|
||||
if (r === 0) {
|
||||
${pattern('d{var} = (random.nextDouble() - 0.5) / 50;', {indent: 8})}
|
||||
r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
}
|
||||
|
||||
var d = r - length;
|
||||
var coefficient = ((spring.coefficient > 0) ? spring.coefficient : options.springCoefficient) * d / r;
|
||||
|
||||
${pattern('body1.force.{var} += coefficient * d{var}', {indent: 6})};
|
||||
body1.springCount += 1;
|
||||
body1.springLength += r;
|
||||
|
||||
${pattern('body2.force.{var} -= coefficient * d{var}', {indent: 6})};
|
||||
body2.springCount += 1;
|
||||
body2.springLength += r;
|
||||
}
|
||||
};
|
||||
`;
|
||||
return code;
|
||||
}
|
||||
49
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateIntegrator.js
generated
vendored
Executable file
49
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateIntegrator.js
generated
vendored
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
|
||||
module.exports = generateIntegratorFunction;
|
||||
module.exports.generateIntegratorFunctionBody = generateIntegratorFunctionBody;
|
||||
|
||||
function generateIntegratorFunction(dimension) {
|
||||
let code = generateIntegratorFunctionBody(dimension);
|
||||
return new Function('bodies', 'timeStep', 'adaptiveTimeStepWeight', code);
|
||||
}
|
||||
|
||||
function generateIntegratorFunctionBody(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let code = `
|
||||
var length = bodies.length;
|
||||
if (length === 0) return 0;
|
||||
|
||||
${pattern('var d{var} = 0, t{var} = 0;', {indent: 2})}
|
||||
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var body = bodies[i];
|
||||
if (body.isPinned) continue;
|
||||
|
||||
if (adaptiveTimeStepWeight && body.springCount) {
|
||||
timeStep = (adaptiveTimeStepWeight * body.springLength/body.springCount);
|
||||
}
|
||||
|
||||
var coeff = timeStep / body.mass;
|
||||
|
||||
${pattern('body.velocity.{var} += coeff * body.force.{var};', {indent: 4})}
|
||||
${pattern('var v{var} = body.velocity.{var};', {indent: 4})}
|
||||
var v = Math.sqrt(${pattern('v{var} * v{var}', {join: ' + '})});
|
||||
|
||||
if (v > 1) {
|
||||
// We normalize it so that we move within timeStep range.
|
||||
// for the case when v <= 1 - we let velocity to fade out.
|
||||
${pattern('body.velocity.{var} = v{var} / v;', {indent: 6})}
|
||||
}
|
||||
|
||||
${pattern('d{var} = timeStep * body.velocity.{var};', {indent: 4})}
|
||||
|
||||
${pattern('body.pos.{var} += d{var};', {indent: 4})}
|
||||
|
||||
${pattern('t{var} += Math.abs(d{var});', {indent: 4})}
|
||||
}
|
||||
|
||||
return (${pattern('t{var} * t{var}', {join: ' + '})})/length;
|
||||
`;
|
||||
return code;
|
||||
}
|
||||
461
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateQuadTree.js
generated
vendored
Executable file
461
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/generateQuadTree.js
generated
vendored
Executable file
|
|
@ -0,0 +1,461 @@
|
|||
const createPatternBuilder = require('./createPatternBuilder');
|
||||
const getVariableName = require('./getVariableName');
|
||||
|
||||
module.exports = generateQuadTreeFunction;
|
||||
module.exports.generateQuadTreeFunctionBody = generateQuadTreeFunctionBody;
|
||||
|
||||
// These exports are for InlineTransform tool.
|
||||
// InlineTransform: getInsertStackCode
|
||||
module.exports.getInsertStackCode = getInsertStackCode;
|
||||
// InlineTransform: getQuadNodeCode
|
||||
module.exports.getQuadNodeCode = getQuadNodeCode;
|
||||
// InlineTransform: isSamePosition
|
||||
module.exports.isSamePosition = isSamePosition;
|
||||
// InlineTransform: getChildBodyCode
|
||||
module.exports.getChildBodyCode = getChildBodyCode;
|
||||
// InlineTransform: setChildBodyCode
|
||||
module.exports.setChildBodyCode = setChildBodyCode;
|
||||
|
||||
function generateQuadTreeFunction(dimension) {
|
||||
let code = generateQuadTreeFunctionBody(dimension);
|
||||
return (new Function(code))();
|
||||
}
|
||||
|
||||
function generateQuadTreeFunctionBody(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let quadCount = Math.pow(2, dimension);
|
||||
|
||||
let code = `
|
||||
${getInsertStackCode()}
|
||||
${getQuadNodeCode(dimension)}
|
||||
${isSamePosition(dimension)}
|
||||
${getChildBodyCode(dimension)}
|
||||
${setChildBodyCode(dimension)}
|
||||
|
||||
function createQuadTree(options, random) {
|
||||
options = options || {};
|
||||
options.gravity = typeof options.gravity === 'number' ? options.gravity : -1;
|
||||
options.theta = typeof options.theta === 'number' ? options.theta : 0.8;
|
||||
|
||||
var gravity = options.gravity;
|
||||
var updateQueue = [];
|
||||
var insertStack = new InsertStack();
|
||||
var theta = options.theta;
|
||||
|
||||
var nodesCache = [];
|
||||
var currentInCache = 0;
|
||||
var root = newNode();
|
||||
|
||||
return {
|
||||
insertBodies: insertBodies,
|
||||
|
||||
/**
|
||||
* Gets root node if it is present
|
||||
*/
|
||||
getRoot: function() {
|
||||
return root;
|
||||
},
|
||||
|
||||
updateBodyForce: update,
|
||||
|
||||
options: function(newOptions) {
|
||||
if (newOptions) {
|
||||
if (typeof newOptions.gravity === 'number') {
|
||||
gravity = newOptions.gravity;
|
||||
}
|
||||
if (typeof newOptions.theta === 'number') {
|
||||
theta = newOptions.theta;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
return {
|
||||
gravity: gravity,
|
||||
theta: theta
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function newNode() {
|
||||
// To avoid pressure on GC we reuse nodes.
|
||||
var node = nodesCache[currentInCache];
|
||||
if (node) {
|
||||
${assignQuads(' node.')}
|
||||
node.body = null;
|
||||
node.mass = ${pattern('node.mass_{var} = ', {join: ''})}0;
|
||||
${pattern('node.min_{var} = node.max_{var} = ', {join: ''})}0;
|
||||
} else {
|
||||
node = new QuadNode();
|
||||
nodesCache[currentInCache] = node;
|
||||
}
|
||||
|
||||
++currentInCache;
|
||||
return node;
|
||||
}
|
||||
|
||||
function update(sourceBody) {
|
||||
var queue = updateQueue;
|
||||
var v;
|
||||
${pattern('var d{var};', {indent: 4})}
|
||||
var r;
|
||||
${pattern('var f{var} = 0;', {indent: 4})}
|
||||
var queueLength = 1;
|
||||
var shiftIdx = 0;
|
||||
var pushIdx = 1;
|
||||
|
||||
queue[0] = root;
|
||||
|
||||
while (queueLength) {
|
||||
var node = queue[shiftIdx];
|
||||
var body = node.body;
|
||||
|
||||
queueLength -= 1;
|
||||
shiftIdx += 1;
|
||||
var differentBody = (body !== sourceBody);
|
||||
if (body && differentBody) {
|
||||
// If the current node is a leaf node (and it is not source body),
|
||||
// calculate the force exerted by the current node on body, and add this
|
||||
// amount to body's net force.
|
||||
${pattern('d{var} = body.pos.{var} - sourceBody.pos.{var};', {indent: 8})}
|
||||
r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
|
||||
if (r === 0) {
|
||||
// Poor man's protection against zero distance.
|
||||
${pattern('d{var} = (random.nextDouble() - 0.5) / 50;', {indent: 10})}
|
||||
r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
}
|
||||
|
||||
// This is standard gravitation force calculation but we divide
|
||||
// by r^3 to save two operations when normalizing force vector.
|
||||
v = gravity * body.mass * sourceBody.mass / (r * r * r);
|
||||
${pattern('f{var} += v * d{var};', {indent: 8})}
|
||||
} else if (differentBody) {
|
||||
// Otherwise, calculate the ratio s / r, where s is the width of the region
|
||||
// represented by the internal node, and r is the distance between the body
|
||||
// and the node's center-of-mass
|
||||
${pattern('d{var} = node.mass_{var} / node.mass - sourceBody.pos.{var};', {indent: 8})}
|
||||
r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
|
||||
if (r === 0) {
|
||||
// Sorry about code duplication. I don't want to create many functions
|
||||
// right away. Just want to see performance first.
|
||||
${pattern('d{var} = (random.nextDouble() - 0.5) / 50;', {indent: 10})}
|
||||
r = Math.sqrt(${pattern('d{var} * d{var}', {join: ' + '})});
|
||||
}
|
||||
// If s / r < θ, treat this internal node as a single body, and calculate the
|
||||
// force it exerts on sourceBody, and add this amount to sourceBody's net force.
|
||||
if ((node.max_${getVariableName(0)} - node.min_${getVariableName(0)}) / r < theta) {
|
||||
// in the if statement above we consider node's width only
|
||||
// because the region was made into square during tree creation.
|
||||
// Thus there is no difference between using width or height.
|
||||
v = gravity * node.mass * sourceBody.mass / (r * r * r);
|
||||
${pattern('f{var} += v * d{var};', {indent: 10})}
|
||||
} else {
|
||||
// Otherwise, run the procedure recursively on each of the current node's children.
|
||||
|
||||
// I intentionally unfolded this loop, to save several CPU cycles.
|
||||
${runRecursiveOnChildren()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
${pattern('sourceBody.force.{var} += f{var};', {indent: 4})}
|
||||
}
|
||||
|
||||
function insertBodies(bodies) {
|
||||
${pattern('var {var}min = Number.MAX_VALUE;', {indent: 4})}
|
||||
${pattern('var {var}max = Number.MIN_VALUE;', {indent: 4})}
|
||||
var i = bodies.length;
|
||||
|
||||
// To reduce quad tree depth we are looking for exact bounding box of all particles.
|
||||
while (i--) {
|
||||
var pos = bodies[i].pos;
|
||||
${pattern('if (pos.{var} < {var}min) {var}min = pos.{var};', {indent: 6})}
|
||||
${pattern('if (pos.{var} > {var}max) {var}max = pos.{var};', {indent: 6})}
|
||||
}
|
||||
|
||||
// Makes the bounds square.
|
||||
var maxSideLength = -Infinity;
|
||||
${pattern('if ({var}max - {var}min > maxSideLength) maxSideLength = {var}max - {var}min ;', {indent: 4})}
|
||||
|
||||
currentInCache = 0;
|
||||
root = newNode();
|
||||
${pattern('root.min_{var} = {var}min;', {indent: 4})}
|
||||
${pattern('root.max_{var} = {var}min + maxSideLength;', {indent: 4})}
|
||||
|
||||
i = bodies.length - 1;
|
||||
if (i >= 0) {
|
||||
root.body = bodies[i];
|
||||
}
|
||||
while (i--) {
|
||||
insert(bodies[i], root);
|
||||
}
|
||||
}
|
||||
|
||||
function insert(newBody) {
|
||||
insertStack.reset();
|
||||
insertStack.push(root, newBody);
|
||||
|
||||
while (!insertStack.isEmpty()) {
|
||||
var stackItem = insertStack.pop();
|
||||
var node = stackItem.node;
|
||||
var body = stackItem.body;
|
||||
|
||||
if (!node.body) {
|
||||
// This is internal node. Update the total mass of the node and center-of-mass.
|
||||
${pattern('var {var} = body.pos.{var};', {indent: 8})}
|
||||
node.mass += body.mass;
|
||||
${pattern('node.mass_{var} += body.mass * {var};', {indent: 8})}
|
||||
|
||||
// Recursively insert the body in the appropriate quadrant.
|
||||
// But first find the appropriate quadrant.
|
||||
var quadIdx = 0; // Assume we are in the 0's quad.
|
||||
${pattern('var min_{var} = node.min_{var};', {indent: 8})}
|
||||
${pattern('var max_{var} = (min_{var} + node.max_{var}) / 2;', {indent: 8})}
|
||||
|
||||
${assignInsertionQuadIndex(8)}
|
||||
|
||||
var child = getChild(node, quadIdx);
|
||||
|
||||
if (!child) {
|
||||
// The node is internal but this quadrant is not taken. Add
|
||||
// subnode to it.
|
||||
child = newNode();
|
||||
${pattern('child.min_{var} = min_{var};', {indent: 10})}
|
||||
${pattern('child.max_{var} = max_{var};', {indent: 10})}
|
||||
child.body = body;
|
||||
|
||||
setChild(node, quadIdx, child);
|
||||
} else {
|
||||
// continue searching in this quadrant.
|
||||
insertStack.push(child, body);
|
||||
}
|
||||
} else {
|
||||
// We are trying to add to the leaf node.
|
||||
// We have to convert current leaf into internal node
|
||||
// and continue adding two nodes.
|
||||
var oldBody = node.body;
|
||||
node.body = null; // internal nodes do not cary bodies
|
||||
|
||||
if (isSamePosition(oldBody.pos, body.pos)) {
|
||||
// Prevent infinite subdivision by bumping one node
|
||||
// anywhere in this quadrant
|
||||
var retriesCount = 3;
|
||||
do {
|
||||
var offset = random.nextDouble();
|
||||
${pattern('var d{var} = (node.max_{var} - node.min_{var}) * offset;', {indent: 12})}
|
||||
|
||||
${pattern('oldBody.pos.{var} = node.min_{var} + d{var};', {indent: 12})}
|
||||
retriesCount -= 1;
|
||||
// Make sure we don't bump it out of the box. If we do, next iteration should fix it
|
||||
} while (retriesCount > 0 && isSamePosition(oldBody.pos, body.pos));
|
||||
|
||||
if (retriesCount === 0 && isSamePosition(oldBody.pos, body.pos)) {
|
||||
// This is very bad, we ran out of precision.
|
||||
// if we do not return from the method we'll get into
|
||||
// infinite loop here. So we sacrifice correctness of layout, and keep the app running
|
||||
// Next layout iteration should get larger bounding box in the first step and fix this
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Next iteration should subdivide node further.
|
||||
insertStack.push(node, oldBody);
|
||||
insertStack.push(node, body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return createQuadTree;
|
||||
|
||||
`;
|
||||
return code;
|
||||
|
||||
|
||||
function assignInsertionQuadIndex(indentCount) {
|
||||
let insertionCode = [];
|
||||
let indent = Array(indentCount + 1).join(' ');
|
||||
for (let i = 0; i < dimension; ++i) {
|
||||
insertionCode.push(indent + `if (${getVariableName(i)} > max_${getVariableName(i)}) {`);
|
||||
insertionCode.push(indent + ` quadIdx = quadIdx + ${Math.pow(2, i)};`);
|
||||
insertionCode.push(indent + ` min_${getVariableName(i)} = max_${getVariableName(i)};`);
|
||||
insertionCode.push(indent + ` max_${getVariableName(i)} = node.max_${getVariableName(i)};`);
|
||||
insertionCode.push(indent + `}`);
|
||||
}
|
||||
return insertionCode.join('\n');
|
||||
// if (x > max_x) { // somewhere in the eastern part.
|
||||
// quadIdx = quadIdx + 1;
|
||||
// left = right;
|
||||
// right = node.right;
|
||||
// }
|
||||
}
|
||||
|
||||
function runRecursiveOnChildren() {
|
||||
let indent = Array(11).join(' ');
|
||||
let recursiveCode = [];
|
||||
for (let i = 0; i < quadCount; ++i) {
|
||||
recursiveCode.push(indent + `if (node.quad${i}) {`);
|
||||
recursiveCode.push(indent + ` queue[pushIdx] = node.quad${i};`);
|
||||
recursiveCode.push(indent + ` queueLength += 1;`);
|
||||
recursiveCode.push(indent + ` pushIdx += 1;`);
|
||||
recursiveCode.push(indent + `}`);
|
||||
}
|
||||
return recursiveCode.join('\n');
|
||||
// if (node.quad0) {
|
||||
// queue[pushIdx] = node.quad0;
|
||||
// queueLength += 1;
|
||||
// pushIdx += 1;
|
||||
// }
|
||||
}
|
||||
|
||||
function assignQuads(indent) {
|
||||
// this.quad0 = null;
|
||||
// this.quad1 = null;
|
||||
// this.quad2 = null;
|
||||
// this.quad3 = null;
|
||||
let quads = [];
|
||||
for (let i = 0; i < quadCount; ++i) {
|
||||
quads.push(`${indent}quad${i} = null;`);
|
||||
}
|
||||
return quads.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
function isSamePosition(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
return `
|
||||
function isSamePosition(point1, point2) {
|
||||
${pattern('var d{var} = Math.abs(point1.{var} - point2.{var});', {indent: 2})}
|
||||
|
||||
return ${pattern('d{var} < 1e-8', {join: ' && '})};
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function setChildBodyCode(dimension) {
|
||||
var quadCount = Math.pow(2, dimension);
|
||||
return `
|
||||
function setChild(node, idx, child) {
|
||||
${setChildBody()}
|
||||
}`;
|
||||
function setChildBody() {
|
||||
let childBody = [];
|
||||
for (let i = 0; i < quadCount; ++i) {
|
||||
let prefix = (i === 0) ? ' ' : ' else ';
|
||||
childBody.push(`${prefix}if (idx === ${i}) node.quad${i} = child;`);
|
||||
}
|
||||
|
||||
return childBody.join('\n');
|
||||
// if (idx === 0) node.quad0 = child;
|
||||
// else if (idx === 1) node.quad1 = child;
|
||||
// else if (idx === 2) node.quad2 = child;
|
||||
// else if (idx === 3) node.quad3 = child;
|
||||
}
|
||||
}
|
||||
|
||||
function getChildBodyCode(dimension) {
|
||||
return `function getChild(node, idx) {
|
||||
${getChildBody()}
|
||||
return null;
|
||||
}`;
|
||||
|
||||
function getChildBody() {
|
||||
let childBody = [];
|
||||
let quadCount = Math.pow(2, dimension);
|
||||
for (let i = 0; i < quadCount; ++i) {
|
||||
childBody.push(` if (idx === ${i}) return node.quad${i};`);
|
||||
}
|
||||
|
||||
return childBody.join('\n');
|
||||
// if (idx === 0) return node.quad0;
|
||||
// if (idx === 1) return node.quad1;
|
||||
// if (idx === 2) return node.quad2;
|
||||
// if (idx === 3) return node.quad3;
|
||||
}
|
||||
}
|
||||
|
||||
function getQuadNodeCode(dimension) {
|
||||
let pattern = createPatternBuilder(dimension);
|
||||
let quadCount = Math.pow(2, dimension);
|
||||
var quadNodeCode = `
|
||||
function QuadNode() {
|
||||
// body stored inside this node. In quad tree only leaf nodes (by construction)
|
||||
// contain bodies:
|
||||
this.body = null;
|
||||
|
||||
// Child nodes are stored in quads. Each quad is presented by number:
|
||||
// 0 | 1
|
||||
// -----
|
||||
// 2 | 3
|
||||
${assignQuads(' this.')}
|
||||
|
||||
// Total mass of current node
|
||||
this.mass = 0;
|
||||
|
||||
// Center of mass coordinates
|
||||
${pattern('this.mass_{var} = 0;', {indent: 2})}
|
||||
|
||||
// bounding box coordinates
|
||||
${pattern('this.min_{var} = 0;', {indent: 2})}
|
||||
${pattern('this.max_{var} = 0;', {indent: 2})}
|
||||
}
|
||||
`;
|
||||
return quadNodeCode;
|
||||
|
||||
function assignQuads(indent) {
|
||||
// this.quad0 = null;
|
||||
// this.quad1 = null;
|
||||
// this.quad2 = null;
|
||||
// this.quad3 = null;
|
||||
let quads = [];
|
||||
for (let i = 0; i < quadCount; ++i) {
|
||||
quads.push(`${indent}quad${i} = null;`);
|
||||
}
|
||||
return quads.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
function getInsertStackCode() {
|
||||
return `
|
||||
/**
|
||||
* Our implementation of QuadTree is non-recursive to avoid GC hit
|
||||
* This data structure represent stack of elements
|
||||
* which we are trying to insert into quad tree.
|
||||
*/
|
||||
function InsertStack () {
|
||||
this.stack = [];
|
||||
this.popIdx = 0;
|
||||
}
|
||||
|
||||
InsertStack.prototype = {
|
||||
isEmpty: function() {
|
||||
return this.popIdx === 0;
|
||||
},
|
||||
push: function (node, body) {
|
||||
var item = this.stack[this.popIdx];
|
||||
if (!item) {
|
||||
// we are trying to avoid memory pressure: create new element
|
||||
// only when absolutely necessary
|
||||
this.stack[this.popIdx] = new InsertStackElement(node, body);
|
||||
} else {
|
||||
item.node = node;
|
||||
item.body = body;
|
||||
}
|
||||
++this.popIdx;
|
||||
},
|
||||
pop: function () {
|
||||
if (this.popIdx > 0) {
|
||||
return this.stack[--this.popIdx];
|
||||
}
|
||||
},
|
||||
reset: function () {
|
||||
this.popIdx = 0;
|
||||
}
|
||||
};
|
||||
|
||||
function InsertStackElement(node, body) {
|
||||
this.node = node; // QuadTree node
|
||||
this.body = body; // physical body which needs to be inserted to node
|
||||
}
|
||||
`;
|
||||
}
|
||||
6
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/getVariableName.js
generated
vendored
Executable file
6
VISUALIZACION/node_modules/ngraph.forcelayout/lib/codeGenerators/getVariableName.js
generated
vendored
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = function getVariableName(index) {
|
||||
if (index === 0) return 'x';
|
||||
if (index === 1) return 'y';
|
||||
if (index === 2) return 'z';
|
||||
return 'c' + (index + 1);
|
||||
};
|
||||
399
VISUALIZACION/node_modules/ngraph.forcelayout/lib/createPhysicsSimulator.js
generated
vendored
Executable file
399
VISUALIZACION/node_modules/ngraph.forcelayout/lib/createPhysicsSimulator.js
generated
vendored
Executable file
|
|
@ -0,0 +1,399 @@
|
|||
/**
|
||||
* Manages a simulation of physical forces acting on bodies and springs.
|
||||
*/
|
||||
module.exports = createPhysicsSimulator;
|
||||
|
||||
var generateCreateBodyFunction = require('./codeGenerators/generateCreateBody');
|
||||
var generateQuadTreeFunction = require('./codeGenerators/generateQuadTree');
|
||||
var generateBoundsFunction = require('./codeGenerators/generateBounds');
|
||||
var generateCreateDragForceFunction = require('./codeGenerators/generateCreateDragForce');
|
||||
var generateCreateSpringForceFunction = require('./codeGenerators/generateCreateSpringForce');
|
||||
var generateIntegratorFunction = require('./codeGenerators/generateIntegrator');
|
||||
|
||||
var dimensionalCache = {};
|
||||
|
||||
function createPhysicsSimulator(settings) {
|
||||
var Spring = require('./spring');
|
||||
var merge = require('ngraph.merge');
|
||||
var eventify = require('ngraph.events');
|
||||
if (settings) {
|
||||
// Check for names from older versions of the layout
|
||||
if (settings.springCoeff !== undefined) throw new Error('springCoeff was renamed to springCoefficient');
|
||||
if (settings.dragCoeff !== undefined) throw new Error('dragCoeff was renamed to dragCoefficient');
|
||||
}
|
||||
|
||||
settings = merge(settings, {
|
||||
/**
|
||||
* Ideal length for links (springs in physical model).
|
||||
*/
|
||||
springLength: 10,
|
||||
|
||||
/**
|
||||
* Hook's law coefficient. 1 - solid spring.
|
||||
*/
|
||||
springCoefficient: 0.8,
|
||||
|
||||
/**
|
||||
* Coulomb's law coefficient. It's used to repel nodes thus should be negative
|
||||
* if you make it positive nodes start attract each other :).
|
||||
*/
|
||||
gravity: -12,
|
||||
|
||||
/**
|
||||
* Theta coefficient from Barnes Hut simulation. Ranged between (0, 1).
|
||||
* The closer it's to 1 the more nodes algorithm will have to go through.
|
||||
* Setting it to one makes Barnes Hut simulation no different from
|
||||
* brute-force forces calculation (each node is considered).
|
||||
*/
|
||||
theta: 0.8,
|
||||
|
||||
/**
|
||||
* Drag force coefficient. Used to slow down system, thus should be less than 1.
|
||||
* The closer it is to 0 the less tight system will be.
|
||||
*/
|
||||
dragCoefficient: 0.9, // TODO: Need to rename this to something better. E.g. `dragCoefficient`
|
||||
|
||||
/**
|
||||
* Default time step (dt) for forces integration
|
||||
*/
|
||||
timeStep : 0.5,
|
||||
|
||||
/**
|
||||
* Adaptive time step uses average spring length to compute actual time step:
|
||||
* See: https://twitter.com/anvaka/status/1293067160755957760
|
||||
*/
|
||||
adaptiveTimeStepWeight: 0,
|
||||
|
||||
/**
|
||||
* This parameter defines number of dimensions of the space where simulation
|
||||
* is performed.
|
||||
*/
|
||||
dimensions: 2,
|
||||
|
||||
/**
|
||||
* In debug mode more checks are performed, this will help you catch errors
|
||||
* quickly, however for production build it is recommended to turn off this flag
|
||||
* to speed up computation.
|
||||
*/
|
||||
debug: false
|
||||
});
|
||||
|
||||
var factory = dimensionalCache[settings.dimensions];
|
||||
if (!factory) {
|
||||
var dimensions = settings.dimensions;
|
||||
factory = {
|
||||
Body: generateCreateBodyFunction(dimensions, settings.debug),
|
||||
createQuadTree: generateQuadTreeFunction(dimensions),
|
||||
createBounds: generateBoundsFunction(dimensions),
|
||||
createDragForce: generateCreateDragForceFunction(dimensions),
|
||||
createSpringForce: generateCreateSpringForceFunction(dimensions),
|
||||
integrate: generateIntegratorFunction(dimensions),
|
||||
};
|
||||
dimensionalCache[dimensions] = factory;
|
||||
}
|
||||
|
||||
var Body = factory.Body;
|
||||
var createQuadTree = factory.createQuadTree;
|
||||
var createBounds = factory.createBounds;
|
||||
var createDragForce = factory.createDragForce;
|
||||
var createSpringForce = factory.createSpringForce;
|
||||
var integrate = factory.integrate;
|
||||
var createBody = pos => new Body(pos);
|
||||
|
||||
var random = require('ngraph.random').random(42);
|
||||
var bodies = []; // Bodies in this simulation.
|
||||
var springs = []; // Springs in this simulation.
|
||||
|
||||
var quadTree = createQuadTree(settings, random);
|
||||
var bounds = createBounds(bodies, settings, random);
|
||||
var springForce = createSpringForce(settings, random);
|
||||
var dragForce = createDragForce(settings);
|
||||
|
||||
var totalMovement = 0; // how much movement we made on last step
|
||||
var forces = [];
|
||||
var forceMap = new Map();
|
||||
var iterationNumber = 0;
|
||||
|
||||
addForce('nbody', nbodyForce);
|
||||
addForce('spring', updateSpringForce);
|
||||
|
||||
var publicApi = {
|
||||
/**
|
||||
* Array of bodies, registered with current simulator
|
||||
*
|
||||
* Note: To add new body, use addBody() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
bodies: bodies,
|
||||
|
||||
quadTree: quadTree,
|
||||
|
||||
/**
|
||||
* Array of springs, registered with current simulator
|
||||
*
|
||||
* Note: To add new spring, use addSpring() method. This property is only
|
||||
* exposed for testing/performance purposes.
|
||||
*/
|
||||
springs: springs,
|
||||
|
||||
/**
|
||||
* Returns settings with which current simulator was initialized
|
||||
*/
|
||||
settings: settings,
|
||||
|
||||
/**
|
||||
* Adds a new force to simulation
|
||||
*/
|
||||
addForce: addForce,
|
||||
|
||||
/**
|
||||
* Removes a force from the simulation.
|
||||
*/
|
||||
removeForce: removeForce,
|
||||
|
||||
/**
|
||||
* Returns a map of all registered forces.
|
||||
*/
|
||||
getForces: getForces,
|
||||
|
||||
/**
|
||||
* Performs one step of force simulation.
|
||||
*
|
||||
* @returns {boolean} true if system is considered stable; False otherwise.
|
||||
*/
|
||||
step: function () {
|
||||
for (var i = 0; i < forces.length; ++i) {
|
||||
forces[i](iterationNumber);
|
||||
}
|
||||
var movement = integrate(bodies, settings.timeStep, settings.adaptiveTimeStepWeight);
|
||||
iterationNumber += 1;
|
||||
return movement;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds body to the system
|
||||
*
|
||||
* @param {ngraph.physics.primitives.Body} body physical body
|
||||
*
|
||||
* @returns {ngraph.physics.primitives.Body} added body
|
||||
*/
|
||||
addBody: function (body) {
|
||||
if (!body) {
|
||||
throw new Error('Body is required');
|
||||
}
|
||||
bodies.push(body);
|
||||
|
||||
return body;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds body to the system at given position
|
||||
*
|
||||
* @param {Object} pos position of a body
|
||||
*
|
||||
* @returns {ngraph.physics.primitives.Body} added body
|
||||
*/
|
||||
addBodyAt: function (pos) {
|
||||
if (!pos) {
|
||||
throw new Error('Body position is required');
|
||||
}
|
||||
var body = createBody(pos);
|
||||
bodies.push(body);
|
||||
|
||||
return body;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes body from the system
|
||||
*
|
||||
* @param {ngraph.physics.primitives.Body} body to remove
|
||||
*
|
||||
* @returns {Boolean} true if body found and removed. falsy otherwise;
|
||||
*/
|
||||
removeBody: function (body) {
|
||||
if (!body) { return; }
|
||||
|
||||
var idx = bodies.indexOf(body);
|
||||
if (idx < 0) { return; }
|
||||
|
||||
bodies.splice(idx, 1);
|
||||
if (bodies.length === 0) {
|
||||
bounds.reset();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a spring to this simulation.
|
||||
*
|
||||
* @returns {Object} - a handle for a spring. If you want to later remove
|
||||
* spring pass it to removeSpring() method.
|
||||
*/
|
||||
addSpring: function (body1, body2, springLength, springCoefficient) {
|
||||
if (!body1 || !body2) {
|
||||
throw new Error('Cannot add null spring to force simulator');
|
||||
}
|
||||
|
||||
if (typeof springLength !== 'number') {
|
||||
springLength = -1; // assume global configuration
|
||||
}
|
||||
|
||||
var spring = new Spring(body1, body2, springLength, springCoefficient >= 0 ? springCoefficient : -1);
|
||||
springs.push(spring);
|
||||
|
||||
// TODO: could mark simulator as dirty.
|
||||
return spring;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns amount of movement performed on last step() call
|
||||
*/
|
||||
getTotalMovement: function () {
|
||||
return totalMovement;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes spring from the system
|
||||
*
|
||||
* @param {Object} spring to remove. Spring is an object returned by addSpring
|
||||
*
|
||||
* @returns {Boolean} true if spring found and removed. falsy otherwise;
|
||||
*/
|
||||
removeSpring: function (spring) {
|
||||
if (!spring) { return; }
|
||||
var idx = springs.indexOf(spring);
|
||||
if (idx > -1) {
|
||||
springs.splice(idx, 1);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
getBestNewBodyPosition: function (neighbors) {
|
||||
return bounds.getBestNewPosition(neighbors);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns bounding box which covers all bodies
|
||||
*/
|
||||
getBBox: getBoundingBox,
|
||||
getBoundingBox: getBoundingBox,
|
||||
|
||||
invalidateBBox: function () {
|
||||
console.warn('invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call');
|
||||
},
|
||||
|
||||
// TODO: Move the force specific stuff to force
|
||||
gravity: function (value) {
|
||||
if (value !== undefined) {
|
||||
settings.gravity = value;
|
||||
quadTree.options({gravity: value});
|
||||
return this;
|
||||
} else {
|
||||
return settings.gravity;
|
||||
}
|
||||
},
|
||||
|
||||
theta: function (value) {
|
||||
if (value !== undefined) {
|
||||
settings.theta = value;
|
||||
quadTree.options({theta: value});
|
||||
return this;
|
||||
} else {
|
||||
return settings.theta;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns pseudo-random number generator instance.
|
||||
*/
|
||||
random: random
|
||||
};
|
||||
|
||||
// allow settings modification via public API:
|
||||
expose(settings, publicApi);
|
||||
|
||||
eventify(publicApi);
|
||||
|
||||
return publicApi;
|
||||
|
||||
function getBoundingBox() {
|
||||
bounds.update();
|
||||
return bounds.box;
|
||||
}
|
||||
|
||||
function addForce(forceName, forceFunction) {
|
||||
if (forceMap.has(forceName)) throw new Error('Force ' + forceName + ' is already added');
|
||||
|
||||
forceMap.set(forceName, forceFunction);
|
||||
forces.push(forceFunction);
|
||||
}
|
||||
|
||||
function removeForce(forceName) {
|
||||
var forceIndex = forces.indexOf(forceMap.get(forceName));
|
||||
if (forceIndex < 0) return;
|
||||
forces.splice(forceIndex, 1);
|
||||
forceMap.delete(forceName);
|
||||
}
|
||||
|
||||
function getForces() {
|
||||
// TODO: Should I trust them or clone the forces?
|
||||
return forceMap;
|
||||
}
|
||||
|
||||
function nbodyForce(/* iterationUmber */) {
|
||||
if (bodies.length === 0) return;
|
||||
|
||||
quadTree.insertBodies(bodies);
|
||||
var i = bodies.length;
|
||||
while (i--) {
|
||||
var body = bodies[i];
|
||||
if (!body.isPinned) {
|
||||
body.reset();
|
||||
quadTree.updateBodyForce(body);
|
||||
dragForce.update(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateSpringForce() {
|
||||
var i = springs.length;
|
||||
while (i--) {
|
||||
springForce.update(springs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function expose(settings, target) {
|
||||
for (var key in settings) {
|
||||
augment(settings, target, key);
|
||||
}
|
||||
}
|
||||
|
||||
function augment(source, target, key) {
|
||||
if (!source.hasOwnProperty(key)) return;
|
||||
if (typeof target[key] === 'function') {
|
||||
// this accessor is already defined. Ignore it
|
||||
return;
|
||||
}
|
||||
var sourceIsNumber = Number.isFinite(source[key]);
|
||||
|
||||
if (sourceIsNumber) {
|
||||
target[key] = function (value) {
|
||||
if (value !== undefined) {
|
||||
if (!Number.isFinite(value)) throw new Error('Value of ' + key + ' should be a valid number.');
|
||||
source[key] = value;
|
||||
return target;
|
||||
}
|
||||
return source[key];
|
||||
};
|
||||
} else {
|
||||
target[key] = function (value) {
|
||||
if (value !== undefined) {
|
||||
source[key] = value;
|
||||
return target;
|
||||
}
|
||||
return source[key];
|
||||
};
|
||||
}
|
||||
}
|
||||
45
VISUALIZACION/node_modules/ngraph.forcelayout/lib/kdForce.js
generated
vendored
Executable file
45
VISUALIZACION/node_modules/ngraph.forcelayout/lib/kdForce.js
generated
vendored
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This is not used anywhere, but it is a good exploration into kd-tree based
|
||||
* simulation.
|
||||
*/
|
||||
module.exports = createKDForce;
|
||||
|
||||
function createKDForce(bodies, settings) {
|
||||
var KDBush = require('kdbush').default;
|
||||
var random = require('ngraph.random').random(1984);
|
||||
|
||||
return kdForce;
|
||||
|
||||
function kdForce(iterationNumber) {
|
||||
if (iterationNumber < 500) return;
|
||||
var gravity = settings.gravity;
|
||||
var points = new KDBush(bodies, p => p.pos.x0, p => p.pos.x1);
|
||||
var i = bodies.length;
|
||||
while (i--) {
|
||||
var body = bodies[i];
|
||||
body.reset();
|
||||
var neighbors = points.within(body.pos.x0, body.pos.x1, settings.springLength);
|
||||
var fx = 0, fy = 0;
|
||||
for (var j = 0; j < neighbors.length; ++j) {
|
||||
var other = bodies[neighbors[j]];
|
||||
if (other === body) continue;
|
||||
|
||||
var dx = other.pos.x0 - body.pos.x0;
|
||||
var dy = other.pos.x1 - body.pos.x1;
|
||||
var r = Math.sqrt(dx * dx + dy * dy);
|
||||
if (r === 0) {
|
||||
// Poor man's protection against zero distance.
|
||||
dx = (random.nextDouble() - 0.5) / 50;
|
||||
dy = (random.nextDouble() - 0.5) / 50;
|
||||
r = Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
var v = gravity * other.mass * body.mass / (r * r * r);
|
||||
fx += v * dx;
|
||||
fy += v * dy;
|
||||
}
|
||||
body.force.x0 = fx;
|
||||
body.force.x1 = fy;
|
||||
//dragForce.update(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
VISUALIZACION/node_modules/ngraph.forcelayout/lib/spring.js
generated
vendored
Executable file
12
VISUALIZACION/node_modules/ngraph.forcelayout/lib/spring.js
generated
vendored
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = Spring;
|
||||
|
||||
/**
|
||||
* Represents a physical spring. Spring connects two bodies, has rest length
|
||||
* stiffness coefficient and optional weight
|
||||
*/
|
||||
function Spring(fromBody, toBody, length, springCoefficient) {
|
||||
this.from = fromBody;
|
||||
this.to = toBody;
|
||||
this.length = length;
|
||||
this.coefficient = springCoefficient;
|
||||
}
|
||||
51
VISUALIZACION/node_modules/ngraph.forcelayout/package.json
generated
vendored
Executable file
51
VISUALIZACION/node_modules/ngraph.forcelayout/package.json
generated
vendored
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"name": "ngraph.forcelayout",
|
||||
"version": "3.3.1",
|
||||
"description": "Force directed graph drawing layout",
|
||||
"main": "index.js",
|
||||
"jsdelivr": "dist/ngraph.forcelayout.min.js",
|
||||
"unpkg": "dist/ngraph.forcelayout.min.js",
|
||||
"types": "./index.d.ts",
|
||||
"typesVersions": {
|
||||
"<=4.3": {
|
||||
"index.d.ts": [
|
||||
"index.v43.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap --branches=80 --lines=80 --statements=80 --functions=80 test/*.js",
|
||||
"lint": "eslint .",
|
||||
"perf": "npm version && node perf/test.js",
|
||||
"build": "browserify index.js -s ngraphCreateLayout -o dist/ngraph.forcelayout.js && terser --compress -o dist/ngraph.forcelayout.min.js -- dist/ngraph.forcelayout.js",
|
||||
"build2d": "browserify index.js -t ./inline-transform.js -s ngraphCreate2dLayout > dist/ngraph.forcelayout2d.js && terser --compress -o dist/ngraph.forcelayout2d.min.js -- dist/ngraph.forcelayout2d.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/anvaka/ngraph.forcelayout.git"
|
||||
},
|
||||
"keywords": [
|
||||
"ngraph",
|
||||
"ngraphjs"
|
||||
],
|
||||
"author": "Andrei Kashcha",
|
||||
"license": "BSD-3-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/anvaka/ngraph.forcelayout/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmark": "~1.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"eslint": "^7.12.1",
|
||||
"ngraph.generators": "^20.0.0",
|
||||
"ngraph.graph": "^20.0.0",
|
||||
"tap": "^16.3.0",
|
||||
"terser": "^5.3.0",
|
||||
"through2": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ngraph.events": "^1.0.0",
|
||||
"ngraph.merge": "^1.0.0",
|
||||
"ngraph.random": "^1.0.0"
|
||||
}
|
||||
}
|
||||
2
VISUALIZACION/node_modules/ngraph.forcelayout/perf/experimental/README.md
generated
vendored
Executable file
2
VISUALIZACION/node_modules/ngraph.forcelayout/perf/experimental/README.md
generated
vendored
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
This folder contains my experiments with performance, trying to figure out the
|
||||
most efficient way of performing simulation
|
||||
110
VISUALIZACION/node_modules/ngraph.forcelayout/perf/experimental/staticOrDynamic.js
generated
vendored
Executable file
110
VISUALIZACION/node_modules/ngraph.forcelayout/perf/experimental/staticOrDynamic.js
generated
vendored
Executable file
|
|
@ -0,0 +1,110 @@
|
|||
// Comparing the difference of compiled adhoc vs compiled in runtime function execution
|
||||
// This should let build functions specific to dimension, without affecting performance.
|
||||
|
||||
var Benchmark = require('benchmark');
|
||||
var suite = new Benchmark.Suite;
|
||||
let bodies;
|
||||
let total = 0;
|
||||
|
||||
let srcCode = staticCompiled.toString().split('\n').slice(1, -1).join('\n');
|
||||
let dynamicCompiled = compile(srcCode);
|
||||
resetBodies();
|
||||
|
||||
suite.add('static compiled', function() {
|
||||
for (var i = 0; i < 2000; ++i) {
|
||||
if (staticCompiled(bodies, 0.5, 0) > 0) {
|
||||
total = 1;
|
||||
}
|
||||
}
|
||||
})
|
||||
.add('dynamic pre-compiled', function() {
|
||||
for (var i = 0; i < 2000; ++i) {
|
||||
if (dynamicCompiled(bodies, 0.5, 0) > 0) {
|
||||
total = 1;
|
||||
}
|
||||
}
|
||||
})
|
||||
.add('dynamic ad-hoc pre-compiled', function() {
|
||||
let fn = compile(srcCode);
|
||||
for (var i = 0; i < 2000; ++i) {
|
||||
if (fn(bodies, 0.5, 0) > 0) {
|
||||
total = 1;
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('cycle', function(event) {
|
||||
console.log(String(event.target), total);
|
||||
total = 0;
|
||||
resetBodies();
|
||||
})
|
||||
.on('complete', function() {
|
||||
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
|
||||
function resetBodies() {
|
||||
bodies = [];
|
||||
for (let i = 0; i < 100; ++i) {
|
||||
bodies.push(createBody(i));
|
||||
}
|
||||
}
|
||||
|
||||
function createBody(i) {
|
||||
return {
|
||||
springCount: 0,
|
||||
springLength: 10,
|
||||
mass: 1,
|
||||
force: {x: i, y: i},
|
||||
velocity: {x: 0, y: 0},
|
||||
pos: {x: i, y: i}
|
||||
};
|
||||
}
|
||||
|
||||
function staticCompiled(bodyCollection, timeStep, adaptiveTimeStepWeight) {
|
||||
var dx = 0, tx = 0,
|
||||
dy = 0, ty = 0,
|
||||
i,
|
||||
max = bodyCollection.length;
|
||||
|
||||
if (max === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < max; ++i) {
|
||||
var body = bodyCollection[i];
|
||||
if (adaptiveTimeStepWeight && body.springCount) {
|
||||
timeStep = (adaptiveTimeStepWeight * body.springLength/body.springCount);
|
||||
}
|
||||
|
||||
var coefficient = timeStep / body.mass;
|
||||
|
||||
body.velocity.x += coefficient * body.force.x;
|
||||
body.velocity.y += coefficient * body.force.y;
|
||||
var vx = body.velocity.x,
|
||||
vy = body.velocity.y,
|
||||
v = Math.sqrt(vx * vx + vy * vy);
|
||||
|
||||
if (v > 1) {
|
||||
// We normalize it so that we move within timeStep range.
|
||||
// for the case when v <= 1 - we let velocity to fade out.
|
||||
body.velocity.x = vx / v;
|
||||
body.velocity.y = vy / v;
|
||||
}
|
||||
|
||||
dx = timeStep * body.velocity.x;
|
||||
dy = timeStep * body.velocity.y;
|
||||
|
||||
body.pos.x += dx;
|
||||
body.pos.y += dy;
|
||||
|
||||
tx += Math.abs(dx); ty += Math.abs(dy);
|
||||
}
|
||||
|
||||
return (tx * tx + ty * ty)/max;
|
||||
}
|
||||
|
||||
function compile(body) {
|
||||
return new Function('bodies', 'timeStep', 'adaptiveTimeStepWeight', body);
|
||||
|
||||
}
|
||||
23
VISUALIZACION/node_modules/ngraph.forcelayout/perf/perfresults.txt
generated
vendored
Executable file
23
VISUALIZACION/node_modules/ngraph.forcelayout/perf/perfresults.txt
generated
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
> npm version && node perf/test.js
|
||||
|
||||
{
|
||||
'ngraph.forcelayout': '1.0.0',
|
||||
npm: '6.13.1',
|
||||
ares: '1.15.0',
|
||||
brotli: '1.0.7',
|
||||
cldr: '35.1',
|
||||
icu: '64.2',
|
||||
llhttp: '1.1.4',
|
||||
modules: '79',
|
||||
napi: '5',
|
||||
nghttp2: '1.40.0',
|
||||
node: '13.2.0',
|
||||
openssl: '1.1.1d',
|
||||
tz: '2019c',
|
||||
unicode: '12.1',
|
||||
uv: '1.33.1',
|
||||
v8: '7.9.317.23-node.20',
|
||||
zlib: '1.2.11'
|
||||
}
|
||||
Run default x 58.06 ops/sec ±2.20% (61 runs sampled)
|
||||
Fastest is Run default
|
||||
20
VISUALIZACION/node_modules/ngraph.forcelayout/perf/test.js
generated
vendored
Executable file
20
VISUALIZACION/node_modules/ngraph.forcelayout/perf/test.js
generated
vendored
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
var graph = require('ngraph.generators').grid(20, 20);
|
||||
|
||||
var Benchmark = require('benchmark');
|
||||
var suite = new Benchmark.Suite;
|
||||
|
||||
// add tests
|
||||
suite.add('Run default', function() {
|
||||
var layout = require('../')(graph);
|
||||
for (var i = 0; i < 20; ++i) {
|
||||
layout.step();
|
||||
}
|
||||
})
|
||||
.on('cycle', function(event) {
|
||||
console.log(String(event.target));
|
||||
})
|
||||
.on('complete', function() {
|
||||
console.log('Fastest is ' + this.filter('fastest').pluck('name'));
|
||||
})
|
||||
// run async
|
||||
.run({ 'async': true });
|
||||
10
VISUALIZACION/node_modules/ngraph.forcelayout/stress.sh
generated
vendored
Executable file
10
VISUALIZACION/node_modules/ngraph.forcelayout/stress.sh
generated
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
node perf/test.js
|
||||
10
VISUALIZACION/node_modules/ngraph.forcelayout/test/createBody.js
generated
vendored
Executable file
10
VISUALIZACION/node_modules/ngraph.forcelayout/test/createBody.js
generated
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
var test = require('tap').test;
|
||||
var dimensions = 2;
|
||||
|
||||
test('can debug setters', function (t) {
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions, true);
|
||||
let b = new Body();
|
||||
t.throws(() => b.pos.x = 'foo', /Cannot set non-numbers to x/);
|
||||
t.end();
|
||||
});
|
||||
21
VISUALIZACION/node_modules/ngraph.forcelayout/test/dragForce.js
generated
vendored
Executable file
21
VISUALIZACION/node_modules/ngraph.forcelayout/test/dragForce.js
generated
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
var test = require('tap').test;
|
||||
var dimensions = 2;
|
||||
var createDragForce = require('../lib/codeGenerators/generateCreateDragForce')(dimensions);
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions);
|
||||
|
||||
test('reduces force value', function (t) {
|
||||
var body = new Body();
|
||||
body.force.x = 1; body.force.y = 1;
|
||||
body.velocity.x = 1; body.velocity.y = 1;
|
||||
|
||||
var dragForce = createDragForce({ dragCoefficient: 0.1 });
|
||||
dragForce.update(body);
|
||||
|
||||
t.ok(body.force.x < 1 && body.force.y < 1, 'Force value is reduced');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Initialized with default value', function (t) {
|
||||
t.throws(() => createDragForce());
|
||||
t.end();
|
||||
});
|
||||
68
VISUALIZACION/node_modules/ngraph.forcelayout/test/eulerIntegrator.js
generated
vendored
Executable file
68
VISUALIZACION/node_modules/ngraph.forcelayout/test/eulerIntegrator.js
generated
vendored
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
var test = require('tap').test;
|
||||
var dimensions = 2;
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions);
|
||||
var integrate = require('../lib/codeGenerators/generateIntegrator')(dimensions);
|
||||
|
||||
test('Body preserves velocity without forces', function (t) {
|
||||
var body = new Body();
|
||||
var timeStep = 1;
|
||||
body.mass = 1; body.velocity.x = 1;
|
||||
|
||||
integrate([body], timeStep);
|
||||
t.equal(body.pos.x, 1, 'Should move by 1 pixel on first iteration');
|
||||
|
||||
timeStep = 2; // let's increase time step:
|
||||
integrate([body], timeStep);
|
||||
t.equal(body.pos.x, 3, 'Should move by 2 pixel on second iteration');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Body gains velocity under force', function (t) {
|
||||
var body = new Body();
|
||||
var timeStep = 1;
|
||||
body.mass = 1; body.force.x = 0.1;
|
||||
|
||||
// F = m * a;
|
||||
// since mass = 1 => F = a = y';
|
||||
integrate([body], timeStep);
|
||||
t.equal(body.velocity.x, 0.1, 'Should increase velocity');
|
||||
|
||||
integrate([body], timeStep);
|
||||
t.equal(body.velocity.x, 0.2, 'Should increase velocity');
|
||||
// floating point math:
|
||||
t.ok(0.29 < body.pos.x && body.pos.x < 0.31, 'Position should be at 0.3 now');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('No bodies yield 0 movement', function (t) {
|
||||
var movement = integrate([], 2);
|
||||
t.equal(movement, 0, 'Nothing has moved');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Body does not move faster than 1px', function (t) {
|
||||
var body = new Body();
|
||||
var timeStep = 1;
|
||||
body.mass = 1; body.force.x = 2;
|
||||
|
||||
integrate([body], timeStep);
|
||||
t.ok(body.velocity.x <= 1, 'Velocity should be within speed limit');
|
||||
|
||||
integrate([body], timeStep);
|
||||
t.ok(body.velocity.x <= 1, 'Velocity should be within speed limit');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can get total system movement', function (t) {
|
||||
var body = new Body();
|
||||
var timeStep = 1;
|
||||
body.mass = 1; body.velocity.x = 0.2;
|
||||
|
||||
var movement = integrate([body], timeStep);
|
||||
// to improve performance, integrator does not take square root, thus
|
||||
// total movement is .2 * .2 = 0.04;
|
||||
t.ok(0.04 <= movement && movement <= 0.041, 'System should travel by 0.2 pixels');
|
||||
t.end();
|
||||
});
|
||||
78
VISUALIZACION/node_modules/ngraph.forcelayout/test/insert.js
generated
vendored
Executable file
78
VISUALIZACION/node_modules/ngraph.forcelayout/test/insert.js
generated
vendored
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
var test = require('tap').test;
|
||||
|
||||
var dimensions = 2;
|
||||
var createQuadTree = require('../lib/codeGenerators/generateQuadTree')(dimensions);
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions);
|
||||
var random = require('ngraph.random').random(42);
|
||||
|
||||
test('insert and update update forces', function (t) {
|
||||
var tree = createQuadTree({}, random);
|
||||
var body = new Body();
|
||||
var clone = JSON.parse(JSON.stringify(body));
|
||||
|
||||
tree.insertBodies([body]);
|
||||
tree.updateBodyForce(body);
|
||||
t.same(body, clone, 'The body should not be changed - there are no forces acting on it');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can get root', function (t) {
|
||||
var tree = createQuadTree({}, random);
|
||||
var body = new Body();
|
||||
|
||||
tree.insertBodies([body]);
|
||||
var root = tree.getRoot();
|
||||
t.ok(root, 'Root is present');
|
||||
t.equal(root.body, body, 'Body is initialized');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Two bodies repel each other', function (t) {
|
||||
var tree = createQuadTree({}, random);
|
||||
var bodyA = new Body(); bodyA.pos.x = 1; bodyA.pos.y = 0;
|
||||
var bodyB = new Body(); bodyB.pos.x = 2; bodyB.pos.y = 0;
|
||||
|
||||
tree.insertBodies([bodyA, bodyB]);
|
||||
tree.updateBodyForce(bodyA);
|
||||
tree.updateBodyForce(bodyB);
|
||||
// based on our physical model construction forces should be equivalent, with
|
||||
// opposite sign:
|
||||
t.ok(bodyA.force.x + bodyB.force.x === 0, 'Forces should be same, with opposite sign');
|
||||
t.ok(bodyA.force.x !== 0, 'X-force for body A should not be zero');
|
||||
t.ok(bodyB.force.x !== 0, 'X-force for body B should not be zero');
|
||||
// On the other hand, our bodies should not move by Y axis:
|
||||
t.ok(bodyA.force.y === 0, 'Y-force for body A should be zero');
|
||||
t.ok(bodyB.force.y === 0, 'Y-force for body B should be zero');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can handle two bodies at the same location', function (t) {
|
||||
var tree = createQuadTree({}, random);
|
||||
var bodyA = new Body();
|
||||
var bodyB = new Body();
|
||||
|
||||
tree.insertBodies([bodyA, bodyB]);
|
||||
tree.updateBodyForce(bodyA);
|
||||
tree.updateBodyForce(bodyB);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it does not stuck', function(t) {
|
||||
var count = 60000;
|
||||
var bodies = [];
|
||||
|
||||
for (var i = 0; i < count; ++i) {
|
||||
bodies.push(new Body(Math.random(), Math.random()));
|
||||
}
|
||||
|
||||
var quadTree = createQuadTree({}, random);
|
||||
quadTree.insertBodies(bodies);
|
||||
|
||||
bodies.forEach(function(body) {
|
||||
quadTree.updateBodyForce(body);
|
||||
});
|
||||
t.ok(1);
|
||||
t.end();
|
||||
});
|
||||
463
VISUALIZACION/node_modules/ngraph.forcelayout/test/layout.js
generated
vendored
Executable file
463
VISUALIZACION/node_modules/ngraph.forcelayout/test/layout.js
generated
vendored
Executable file
|
|
@ -0,0 +1,463 @@
|
|||
/* eslint-disable no-shadow */
|
||||
var test = require('tap').test,
|
||||
createGraph = require('ngraph.graph'),
|
||||
createLayout = require('..');
|
||||
|
||||
test('it exposes simulator', function(t) {
|
||||
t.ok(typeof createLayout.simulator === 'function', 'Simulator is exposed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it returns spring', function(t) {
|
||||
var g = createGraph();
|
||||
var layout = createLayout(g);
|
||||
|
||||
var link = g.addLink(1, 2);
|
||||
|
||||
var springForLink = layout.getSpring(link);
|
||||
var springForLinkId = layout.getSpring(link.id);
|
||||
var springForFromTo = layout.getSpring(1, 2);
|
||||
|
||||
t.ok(springForLink, 'spring is here');
|
||||
t.ok(springForLinkId === springForLink, 'Spring is the same');
|
||||
t.ok(springForFromTo === springForLink, 'Spring is the same');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it returns same position', function(t) {
|
||||
var g = createGraph();
|
||||
var layout = createLayout(g);
|
||||
|
||||
g.addLink(1, 2);
|
||||
|
||||
var firstNodePos = layout.getNodePosition(1);
|
||||
layout.step();
|
||||
t.ok(firstNodePos === layout.getNodePosition(1), 'Position is the same object');
|
||||
layout.step();
|
||||
t.ok(firstNodePos === layout.getNodePosition(1), 'Position is the same object after multiple steps');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it returns body', function(t) {
|
||||
var g = createGraph();
|
||||
var layout = createLayout(g);
|
||||
|
||||
g.addLink(1, 2);
|
||||
|
||||
t.ok(layout.getBody(1), 'node 1 has body');
|
||||
t.ok(layout.getBody(2), 'node 2 has body');
|
||||
t.notOk(layout.getBody(4), 'there is no node 4');
|
||||
|
||||
var body = layout.getBody(1);
|
||||
t.ok(body.pos.x && body.pos.y, 'Body has a position');
|
||||
t.ok(body.mass, 'Body has a mass');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can set node mass', function(t) {
|
||||
var g = createGraph();
|
||||
g.addNode('anvaka');
|
||||
|
||||
var layout = createLayout(g, {
|
||||
nodeMass: function (nodeId) {
|
||||
t.equal(nodeId, 'anvaka', 'correct node is called');
|
||||
return 84; // my mass in kilograms :P
|
||||
}
|
||||
});
|
||||
|
||||
var body = layout.getBody('anvaka');
|
||||
t.equal(body.mass, 84, 'Mass is okay');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('does not tolerate bad input', function (t) {
|
||||
t.throws(missingGraph);
|
||||
t.throws(invalidNodeId);
|
||||
t.end();
|
||||
|
||||
function missingGraph() {
|
||||
// graph is missing:
|
||||
createLayout();
|
||||
}
|
||||
|
||||
function invalidNodeId() {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
|
||||
// we don't have nodes in the graph. This should throw:
|
||||
layout.getNodePosition(1);
|
||||
}
|
||||
});
|
||||
|
||||
test('it fires stable on empty graph', function(t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
layout.on('stable', endTest);
|
||||
layout.step();
|
||||
|
||||
function endTest() {
|
||||
t.end();
|
||||
}
|
||||
});
|
||||
|
||||
test('can add bodies which are standard prototype names', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink('constructor', 'watch');
|
||||
|
||||
var layout = createLayout(graph);
|
||||
layout.step();
|
||||
|
||||
graph.forEachNode(function (node) {
|
||||
var pos = layout.getNodePosition(node.id);
|
||||
t.ok(pos && typeof pos.x === 'number' &&
|
||||
typeof pos.y === 'number', 'Position is defined');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can step when no links present', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addNode('constructor');
|
||||
graph.addNode('watch');
|
||||
|
||||
var layout = createLayout(graph);
|
||||
layout.step();
|
||||
|
||||
graph.forEachNode(function (node) {
|
||||
var pos = layout.getNodePosition(node.id);
|
||||
t.ok(pos && typeof pos.x === 'number' &&
|
||||
typeof pos.y === 'number', 'Position is defined');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('layout initializes nodes positions', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
|
||||
// perform one iteration of layout:
|
||||
layout.step();
|
||||
|
||||
graph.forEachNode(function (node) {
|
||||
var pos = layout.getNodePosition(node.id);
|
||||
t.ok(pos && typeof pos.x === 'number' &&
|
||||
typeof pos.y === 'number', 'Position is defined');
|
||||
});
|
||||
|
||||
graph.forEachLink(function (link) {
|
||||
var linkPos = layout.getLinkPosition(link.id);
|
||||
t.ok(linkPos && linkPos.from && linkPos.to, 'Link position is defined');
|
||||
var fromPos = layout.getNodePosition(link.fromId);
|
||||
t.ok(linkPos.from === fromPos, '"From" should be identical to getNodePosition');
|
||||
var toPos = layout.getNodePosition(link.toId);
|
||||
t.ok(linkPos.to === toPos, '"To" should be identical to getNodePosition');
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Layout can set node position', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
|
||||
layout.pinNode(graph.getNode(1), true);
|
||||
layout.setNodePosition(1, 42, 42);
|
||||
|
||||
// perform one iteration of layout:
|
||||
layout.step();
|
||||
|
||||
// and make sure node 1 was not moved:
|
||||
var actualPosition = layout.getNodePosition(1);
|
||||
t.equal(actualPosition.x, 42, 'X has not changed');
|
||||
t.equal(actualPosition.y, 42, 'Y has not changed');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Layout updates bounding box when it sets node position', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
layout.setNodePosition(1, 42, 42);
|
||||
layout.setNodePosition(2, 40, 40);
|
||||
var rect = layout.getGraphRect();
|
||||
t.ok(rect.max_x <= 42); t.ok(rect.max_y <= 42);
|
||||
t.ok(rect.min_x >= 40); t.ok(rect.min_y >= 40);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('layout initializes links', function (t) {
|
||||
var graph = createGraph();
|
||||
var node1 = graph.addNode(1); node1.position = {x : -1000, y: 0};
|
||||
var node2 = graph.addNode(2); node2.position = {x : 1000, y: 0};
|
||||
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
|
||||
// perform one iteration of layout:
|
||||
layout.step();
|
||||
|
||||
// since both nodes are connected by spring and distance is too large between
|
||||
// them, they should start attracting each other
|
||||
var pos1 = layout.getNodePosition(1);
|
||||
var pos2 = layout.getNodePosition(2);
|
||||
|
||||
t.ok(pos1.x > -1000, 'Node 1 moves towards node 2');
|
||||
t.ok(pos2.x < 1000, 'Node 1 moves towards node 2');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('layout respects proposed original position', function (t) {
|
||||
var graph = createGraph();
|
||||
var node = graph.addNode(1);
|
||||
|
||||
var initialPosition = {x: 100, y: 100};
|
||||
node.position = copy(initialPosition);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
layout.step();
|
||||
|
||||
t.same(layout.getNodePosition(node.id), initialPosition, 'original position preserved');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('layout has defined graph rectangle', function (t) {
|
||||
t.test('empty graph', function (t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
|
||||
var rect = layout.getGraphRect();
|
||||
var expectedProperties = ['min_x', 'min_y', 'max_x', 'max_y'];
|
||||
t.ok(rect && expectedProperties.reduce(hasProperties, true), 'Values are present before step()');
|
||||
|
||||
layout.step();
|
||||
|
||||
t.ok(rect && expectedProperties.reduce(hasProperties, true), 'Values are present after step()');
|
||||
t.end();
|
||||
|
||||
function hasProperties(result, key) {
|
||||
return result && typeof rect[key] === 'number';
|
||||
}
|
||||
});
|
||||
|
||||
t.test('two nodes', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
var layout = createLayout(graph);
|
||||
layout.step();
|
||||
|
||||
var rect = layout.getGraphRect();
|
||||
t.ok(!rectangleIsEmpty(rect), 'Graph rectangle is not empty');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it does not move pinned nodes', function (t) {
|
||||
t.test('respects original data.isPinned attribute', function (t) {
|
||||
var graph = createGraph();
|
||||
var testNode = graph.addNode(1, { isPinned: true });
|
||||
var layout = createLayout(graph);
|
||||
t.ok(layout.isNodePinned(testNode), 'Node is pinned');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('respects node.isPinned attribute', function (t) {
|
||||
var graph = createGraph();
|
||||
var testNode = graph.addNode(1);
|
||||
|
||||
// this was possible in vivagraph. Port it over to ngraph:
|
||||
testNode.isPinned = true;
|
||||
var layout = createLayout(graph);
|
||||
t.ok(layout.isNodePinned(testNode), 'Node is pinned');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('can pin nodes after graph is initialized', function (t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
|
||||
var layout = createLayout(graph);
|
||||
layout.pinNode(graph.getNode(1), true);
|
||||
layout.step();
|
||||
var pos1 = copy(layout.getNodePosition(1));
|
||||
var pos2 = copy(layout.getNodePosition(2));
|
||||
|
||||
// make one more step and make sure node 1 did not move:
|
||||
layout.step();
|
||||
|
||||
t.ok(!positionChanged(pos1, layout.getNodePosition(1)), 'Node 1 was not moved');
|
||||
t.ok(positionChanged(pos2, layout.getNodePosition(2)), 'Node 2 has moved');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it listens to graph events', function (t) {
|
||||
// we first initialize with empty graph:
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
|
||||
// and only then add nodes:
|
||||
graph.addLink(1, 2);
|
||||
|
||||
// make two iterations
|
||||
layout.step();
|
||||
var pos1 = copy(layout.getNodePosition(1));
|
||||
var pos2 = copy(layout.getNodePosition(2));
|
||||
|
||||
layout.step();
|
||||
|
||||
t.ok(positionChanged(pos1, layout.getNodePosition(1)), 'Node 1 has moved');
|
||||
t.ok(positionChanged(pos2, layout.getNodePosition(2)), 'Node 2 has moved');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('can stop listen to events', function (t) {
|
||||
// we first initialize with empty graph:
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
layout.dispose();
|
||||
|
||||
graph.addLink(1, 2);
|
||||
layout.step();
|
||||
t.ok(layout.simulator.bodies.length === 0, 'No bodies in the simulator');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('physics simulator', function (t) {
|
||||
t.test('has default simulator', function (t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
|
||||
t.ok(layout.simulator, 'physics simulator is present');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('can override default settings', function (t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph, {
|
||||
theta: 1.5
|
||||
});
|
||||
t.equal(layout.simulator.theta(), 1.5, 'Simulator settings are overridden');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it removes removed nodes', function (t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
graph.addLink(1, 2);
|
||||
|
||||
layout.step();
|
||||
graph.clear();
|
||||
|
||||
// since we removed everything from graph rect should be empty:
|
||||
var rect = layout.getGraphRect();
|
||||
|
||||
t.ok(rectangleIsEmpty(rect), 'Graph rect is empty');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can iterate over bodies', function(t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
graph.addLink(1, 2);
|
||||
var calledCount = 0;
|
||||
|
||||
layout.forEachBody(function(body, bodyId) {
|
||||
t.ok(body.pos, bodyId + ' has position');
|
||||
t.ok(graph.getNode(bodyId), bodyId + ' matches a graph node');
|
||||
calledCount += 1;
|
||||
});
|
||||
|
||||
t.equal(calledCount, 2, 'Both bodies are visited');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it handles large graphs', function (t) {
|
||||
var graph = createGraph();
|
||||
var layout = createLayout(graph);
|
||||
|
||||
var count = 60000;
|
||||
|
||||
var i = count;
|
||||
while (i--) {
|
||||
graph.addNode(i);
|
||||
}
|
||||
|
||||
// link each node to 2 other random nodes
|
||||
i = count;
|
||||
while (i--) {
|
||||
graph.addLink(i, Math.ceil(Math.random() * count));
|
||||
graph.addLink(i, Math.ceil(Math.random() * count));
|
||||
}
|
||||
|
||||
layout.step();
|
||||
|
||||
t.ok(layout.simulator.bodies.length !== 0, 'Bodies in the simulator');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can create high dimensional layout', function(t) {
|
||||
var graph = createGraph();
|
||||
graph.addLink(1, 2);
|
||||
var layout = createLayout(graph, {dimensions: 6});
|
||||
layout.step();
|
||||
|
||||
var pos = layout.getNodePosition(1);
|
||||
t.ok(pos.x !== undefined, 'Position has x');
|
||||
t.ok(pos.y !== undefined, 'Position has y');
|
||||
t.ok(pos.z !== undefined, 'Position has z');
|
||||
t.ok(pos.c4 !== undefined, 'Position has c4');
|
||||
t.ok(pos.c5 !== undefined, 'Position has c5');
|
||||
t.ok(pos.c6 !== undefined, 'Position has c6');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can layout two graphs independently', function(t) {
|
||||
var graph1 = createGraph();
|
||||
var graph2 = createGraph();
|
||||
var layout1 = createLayout(graph1);
|
||||
var layout2 = createLayout(graph2);
|
||||
graph1.addLink(1, 2);
|
||||
graph2.addLink(1, 2);
|
||||
layout1.step();
|
||||
layout2.step();
|
||||
layout2.step();
|
||||
t.ok(layout1.getNodePosition(1).x !== layout2.getNodePosition(1).x, 'Positions are different');
|
||||
t.end();
|
||||
});
|
||||
|
||||
function positionChanged(pos1, pos2) {
|
||||
return (pos1.x !== pos2.x) || (pos1.y !== pos2.y);
|
||||
}
|
||||
|
||||
function copy(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
function rectangleIsEmpty(rect) {
|
||||
return rect.min_x === 0 && rect.min_y === 0 && rect.max_x === 0 && rect.max_y === 0;
|
||||
}
|
||||
100
VISUALIZACION/node_modules/ngraph.forcelayout/test/primitives.js
generated
vendored
Executable file
100
VISUALIZACION/node_modules/ngraph.forcelayout/test/primitives.js
generated
vendored
Executable file
|
|
@ -0,0 +1,100 @@
|
|||
var test = require('tap').test;
|
||||
var {generateCreateBodyFunctionBody} = require('../lib/codeGenerators/generateCreateBody');
|
||||
|
||||
function primitive(dimension) {
|
||||
let res = (new Function(generateCreateBodyFunctionBody(dimension)))();
|
||||
return res;
|
||||
}
|
||||
|
||||
test('Body has properties force, pos and mass', function(t) {
|
||||
debugger;
|
||||
var body = new (primitive(2).Body)();
|
||||
t.ok(body.force, 'Force attribute is missing on body');
|
||||
t.ok(body.pos, 'Pos attribute is missing on body');
|
||||
t.ok(body.velocity, 'Velocity attribute is missing on body');
|
||||
t.ok(typeof body.mass === 'number' && body.mass !== 0, 'Body should have a mass');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Vector has x and y', function(t) {
|
||||
var vector = new (primitive(2).Vector)();
|
||||
t.ok(typeof vector.x === 'number', 'Vector has x coordinates');
|
||||
t.ok(typeof vector.y === 'number', 'Vector has y coordinates');
|
||||
|
||||
var initialized = new (primitive(2).Vector)(1, 2);
|
||||
t.equal(initialized.x, 1, 'Vector initialized properly');
|
||||
t.equal(initialized.y, 2, 'Vector initialized properly');
|
||||
|
||||
var badInput = new (primitive(2).Vector)('hello world');
|
||||
t.equal(badInput.x, 0, 'Vector should be resilient to bed input');
|
||||
t.equal(badInput.y, 0, 'Vector should be resilient to bed input');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Body3d has properties force, pos and mass', function(t) {
|
||||
var body = new (primitive(3).Body)();
|
||||
t.ok(body.force, 'Force attribute is missing on body');
|
||||
t.ok(body.pos, 'Pos attribute is missing on body');
|
||||
t.ok(body.velocity, 'Velocity attribute is missing on body');
|
||||
t.ok(typeof body.mass === 'number' && body.mass !== 0, 'Body should have a mass');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Vector3d has x and y and z', function(t) {
|
||||
var vector = new (primitive(3).Vector)();
|
||||
t.ok(typeof vector.x === 'number', 'Vector has x coordinates');
|
||||
t.ok(typeof vector.y === 'number', 'Vector has y coordinates');
|
||||
t.ok(typeof vector.z === 'number', 'Vector has z coordinates');
|
||||
|
||||
var initialized = new (primitive(3).Vector)(1, 2, 3);
|
||||
t.equal(initialized.x, 1, 'Vector initialized properly');
|
||||
t.equal(initialized.y, 2, 'Vector initialized properly');
|
||||
t.equal(initialized.z, 3, 'Vector initialized properly');
|
||||
|
||||
var badInput = new (primitive(3).Vector)('hello world');
|
||||
t.equal(badInput.x, 0, 'Vector should be resilient to bed input');
|
||||
t.equal(badInput.y, 0, 'Vector should be resilient to bed input');
|
||||
t.equal(badInput.z, 0, 'Vector should be resilient to bed input');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('reset vector', function(t) {
|
||||
var v3 = new (primitive(3).Vector)(1, 2, 3);
|
||||
v3.reset();
|
||||
t.equal(v3.x, 0, 'Reset to 0');
|
||||
t.equal(v3.y, 0, 'Reset to 0');
|
||||
t.equal(v3.z, 0, 'Reset to 0');
|
||||
var v2 = new (primitive(2).Vector)(1, 2);
|
||||
v2.reset();
|
||||
t.equal(v2.x, 0, 'Reset to 0');
|
||||
t.equal(v2.y, 0, 'Reset to 0');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('vector can use copy constructor', function(t) {
|
||||
var a = new (primitive(3).Vector)(1, 2, 3);
|
||||
var b = new (primitive(3).Vector)(a);
|
||||
t.equal(b.x, a.x, 'Value copied');
|
||||
t.equal(b.y, a.y, 'Value copied');
|
||||
t.equal(b.z, a.z, 'Value copied');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Body3d can set position', function(t) {
|
||||
var body = new (primitive(3).Body)();
|
||||
body.setPosition(10, 11, 12);
|
||||
t.equal(body.pos.x, 10, 'x is correct');
|
||||
t.equal(body.pos.y, 11, 'y is correct');
|
||||
t.equal(body.pos.z, 12, 'z is correct');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Body can set position', function(t) {
|
||||
var body = new (primitive(2).Body)();
|
||||
body.setPosition(10, 11);
|
||||
t.equal(body.pos.x, 10, 'x is correct');
|
||||
t.equal(body.pos.y, 11, 'y is correct');
|
||||
|
||||
t.end();
|
||||
});
|
||||
336
VISUALIZACION/node_modules/ngraph.forcelayout/test/simulator.js
generated
vendored
Executable file
336
VISUALIZACION/node_modules/ngraph.forcelayout/test/simulator.js
generated
vendored
Executable file
|
|
@ -0,0 +1,336 @@
|
|||
/* eslint-disable no-shadow */
|
||||
var test = require('tap').test;
|
||||
var dimensions = 2;
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions);
|
||||
var createSimulator = require('../lib/createPhysicsSimulator');
|
||||
|
||||
test('Can step without bodies', function (t) {
|
||||
var simulator = createSimulator();
|
||||
t.equal(simulator.bodies.length, 0, 'There should be no bodies');
|
||||
t.equal(simulator.springs.length, 0, 'There should be no springs');
|
||||
simulator.step();
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it has settings exposed', function(t) {
|
||||
var mySettings = { };
|
||||
var simulator = createSimulator(mySettings);
|
||||
t.ok(mySettings === simulator.settings, 'settings are exposed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it gives amount of total movement', function(t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(-10, 0);
|
||||
var body2 = new Body(10, 0);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
simulator.step();
|
||||
|
||||
var totalMoved = simulator.getTotalMovement();
|
||||
t.ok(!isNaN(totalMoved), 'Amount of total movement is returned');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can add a body at given position', function(t) {
|
||||
var simulator = createSimulator();
|
||||
var pos1 = {x: -10, y: 0};
|
||||
var pos2 = {x: 10, y: 0};
|
||||
simulator.addBodyAt(pos1);
|
||||
simulator.addBodyAt(pos2);
|
||||
|
||||
t.equal(simulator.bodies.length, 2, 'All bodies are added');
|
||||
var body1 = simulator.bodies[0];
|
||||
|
||||
t.equal(body1.pos.x, -10, 'X is there');
|
||||
t.equal(body1.pos.y, 0, 'Y is there');
|
||||
|
||||
var body2 = simulator.bodies[1];
|
||||
t.equal(body2.pos.x, 10, 'X is there');
|
||||
t.equal(body2.pos.y, 0, 'Y is there');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Does not update position of one body', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body = new Body(0, 0);
|
||||
simulator.addBody(body);
|
||||
|
||||
simulator.step(1);
|
||||
t.equal(simulator.bodies.length, 1, 'Number of bodies is 1');
|
||||
t.equal(simulator.springs.length, 0, 'Number of springs is 0');
|
||||
t.equal(simulator.bodies[0], body, 'Body points to actual object');
|
||||
t.equal(body.pos.x, 0, 'X is not changed');
|
||||
t.equal(body.pos.y, 0, 'Y is not changed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('throws on no body or no pos', t => {
|
||||
var simulator = createSimulator();
|
||||
t.throws(() => simulator.addBody(), /Body is required/);
|
||||
t.throws(() => simulator.addBodyAt(), /Body position is required/);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('throws on no spring', t => {
|
||||
var simulator = createSimulator();
|
||||
t.throws(() => simulator.addSpring(), /Cannot add null spring to force simulator/);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can add and remove forces', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var testForce = function () {};
|
||||
simulator.addForce('foo', testForce);
|
||||
t.equal(simulator.getForces().get('foo'), testForce);
|
||||
|
||||
simulator.removeForce('foo');
|
||||
t.equal(simulator.getForces().get('foo'), undefined);
|
||||
|
||||
simulator.removeForce('foo');
|
||||
// should still be good
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can configure forces', function (t) {
|
||||
t.test('Gravity', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(0, 0);
|
||||
var body2 = new Body(1, 0);
|
||||
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
|
||||
simulator.step();
|
||||
// by default gravity is negative, bodies should repel each other:
|
||||
var x1 = body1.pos.x;
|
||||
var x2 = body2.pos.x;
|
||||
t.ok(x1 < 0, 'Body 1 moves away from body 2');
|
||||
t.ok(x2 > 1, 'Body 2 moves away from body 1');
|
||||
|
||||
// now reverse gravity, and bodies should attract each other:
|
||||
simulator.gravity(100);
|
||||
simulator.step();
|
||||
t.ok(body1.pos.x > x1, 'Body 1 moved towards body 2');
|
||||
t.ok(body2.pos.x < x2, 'Body 2 moved towards body 1');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('Drag', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(0, 0);
|
||||
body1.velocity.x = -1; // give it small impulse
|
||||
simulator.addBody(body1);
|
||||
|
||||
simulator.step();
|
||||
|
||||
var x1 = body1.velocity.x;
|
||||
// by default drag force will slow down entire system:
|
||||
t.ok(x1 > -1, 'Body 1 moves at reduced speed');
|
||||
|
||||
// Restore original velocity, but now set drag force to 0
|
||||
body1.velocity.x = -1;
|
||||
simulator.dragCoefficient(0);
|
||||
simulator.step();
|
||||
t.ok(body1.velocity.x === -1, 'Velocity should remain unchanged');
|
||||
t.end();
|
||||
});
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can remove bodies', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body = new Body(0, 0);
|
||||
simulator.addBody(body);
|
||||
t.equal(simulator.bodies.length, 1, 'Number of bodies is 1');
|
||||
var result = simulator.removeBody(body);
|
||||
t.equal(result, true, 'body successfully removed');
|
||||
t.equal(simulator.bodies.length, 0, 'Number of bodies is 0');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Updates position for two bodies', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(-1, 0);
|
||||
var body2 = new Body(1, 0);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
|
||||
simulator.step();
|
||||
t.equal(simulator.bodies.length, 2, 'Number of bodies is 2');
|
||||
t.ok(body1.pos.x !== 0, 'Body1.X has changed');
|
||||
t.ok(body2.pos.x !== 0, 'Body2.X has changed');
|
||||
|
||||
t.equal(body1.pos.y, 0, 'Body1.Y has not changed');
|
||||
t.equal(body2.pos.y, 0, 'Body2.Y has not changed');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('add spring should not add bodies', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(-1, 0);
|
||||
var body2 = new Body(1, 0);
|
||||
|
||||
simulator.addSpring(body1, body2, 10);
|
||||
|
||||
t.equal(simulator.bodies.length, 0, 'Should not add two bodies');
|
||||
t.equal(simulator.bodies.length, 0, 'Should not add two bodies');
|
||||
t.equal(simulator.springs.length, 1, 'Should have a spring');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Spring affects bodies positions', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(-10, 0);
|
||||
var body2 = new Body(10, 0);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
// If you take this out, bodies will repel each other:
|
||||
simulator.addSpring(body1, body2, 1);
|
||||
|
||||
simulator.step();
|
||||
|
||||
t.ok(body1.pos.x > -10, 'Body 1 should move towards body 2');
|
||||
t.ok(body2.pos.x < 10, 'Body 2 should move towards body 1');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Can remove springs', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(-10, 0);
|
||||
var body2 = new Body(10, 0);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
var spring = simulator.addSpring(body1, body2, 1);
|
||||
simulator.removeSpring(spring);
|
||||
|
||||
simulator.step();
|
||||
|
||||
t.ok(body1.pos.x < -10, 'Body 1 should move away from body 2');
|
||||
t.ok(body2.pos.x > 10, 'Body 2 should move away from body 1');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Get bounding box', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(0, 0);
|
||||
var body2 = new Body(10, 10);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
simulator.step(); // this will move bodies farther away
|
||||
var bbox = simulator.getBBox();
|
||||
t.ok(bbox.min_x <= 0, 'Left is 0');
|
||||
t.ok(bbox.min_y <= 0, 'Top is 0');
|
||||
t.ok(bbox.max_x >= 10, 'right is 10');
|
||||
t.ok(bbox.max_y >= 10, 'bottom is 10');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it updates bounding box', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var body1 = new Body(0, 0);
|
||||
var body2 = new Body(10, 10);
|
||||
simulator.addBody(body1);
|
||||
simulator.addBody(body2);
|
||||
var bbox = simulator.getBBox();
|
||||
|
||||
t.ok(bbox.min_x === 0, 'Left is 0');
|
||||
t.ok(bbox.min_y === 0, 'Top is 0');
|
||||
t.ok(bbox.max_x === 10, 'right is 10');
|
||||
t.ok(bbox.max_y === 10, 'bottom is 10');
|
||||
|
||||
body1.setPosition(15, 15);
|
||||
simulator.invalidateBBox();
|
||||
bbox = simulator.getBBox();
|
||||
|
||||
t.ok(bbox.min_x === 10, 'Left is 10');
|
||||
t.ok(bbox.min_y === 10, 'Top is 10');
|
||||
t.ok(bbox.max_x === 15, 'right is 15');
|
||||
t.ok(bbox.max_y === 15, 'bottom is 15');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Get best position', function (t) {
|
||||
t.test('can get with empty simulator', function (t) {
|
||||
var simulator = createSimulator();
|
||||
var empty = simulator.getBestNewBodyPosition([]);
|
||||
t.ok(typeof empty.x === 'number', 'Has X');
|
||||
t.ok(typeof empty.y === 'number', 'Has Y');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can change settings', function(t) {
|
||||
var simulator = createSimulator();
|
||||
|
||||
var currentTheta = simulator.theta();
|
||||
t.ok(typeof currentTheta === 'number', 'theta is here');
|
||||
simulator.theta(1.2);
|
||||
t.equal(simulator.theta(), 1.2, 'theta is changed');
|
||||
|
||||
var currentSpringCoefficient = simulator.springCoefficient();
|
||||
t.ok(typeof currentSpringCoefficient === 'number', 'springCoefficient is here');
|
||||
simulator.springCoefficient(0.8);
|
||||
t.equal(simulator.springCoefficient(), 0.8, 'springCoefficient is changed');
|
||||
|
||||
var gravity = simulator.gravity();
|
||||
t.ok(typeof gravity === 'number', 'gravity is here');
|
||||
simulator.gravity(-0.8);
|
||||
t.equal(simulator.gravity(), -0.8, 'gravity is changed');
|
||||
|
||||
var springLength = simulator.springLength();
|
||||
t.ok(typeof springLength === 'number', 'springLength is here');
|
||||
simulator.springLength(80);
|
||||
t.equal(simulator.springLength(), 80, 'springLength is changed');
|
||||
|
||||
var dragCoefficient = simulator.dragCoefficient();
|
||||
t.ok(typeof dragCoefficient === 'number', 'dragCoefficient is here');
|
||||
simulator.dragCoefficient(0.8);
|
||||
t.equal(simulator.dragCoefficient(), 0.8, 'dragCoefficient is changed');
|
||||
|
||||
var timeStep = simulator.timeStep();
|
||||
t.ok(typeof timeStep === 'number', 'timeStep is here');
|
||||
simulator.timeStep(8);
|
||||
t.equal(simulator.timeStep(), 8, 'timeStep is changed');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it can augment string setter values', function (t) {
|
||||
var simulator = createSimulator({
|
||||
name: 'John'
|
||||
});
|
||||
|
||||
simulator.name('Alisa');
|
||||
t.equal(simulator.name(), 'Alisa', 'name is Alisa');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it ignores body that does not exist', function(t) {
|
||||
var simulator = createSimulator();
|
||||
var body = new Body(0, 0);
|
||||
simulator.addBody(body);
|
||||
simulator.removeBody({});
|
||||
t.equal(simulator.bodies.length, 1, 'Should ignore body that does not exist');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it throws on springCoeff', function (t) {
|
||||
t.throws(function () {
|
||||
createSimulator({springCoeff: 1});
|
||||
}, 'springCoeff was renamed to springCoefficient');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('it throws on dragCoeff', function (t) {
|
||||
t.throws(function () {
|
||||
createSimulator({dragCoeff: 1});
|
||||
}, 'dragCoeff was renamed to dragCoefficient');
|
||||
t.end();
|
||||
});
|
||||
63
VISUALIZACION/node_modules/ngraph.forcelayout/test/springForce.js
generated
vendored
Executable file
63
VISUALIZACION/node_modules/ngraph.forcelayout/test/springForce.js
generated
vendored
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
/* eslint-disable no-shadow */
|
||||
var test = require('tap').test;
|
||||
|
||||
var dimensions = 2;
|
||||
var createSpringForce = require('../lib/codeGenerators/generateCreateSpringForce')(dimensions);
|
||||
var Body = require('../lib/codeGenerators/generateCreateBody')(dimensions);
|
||||
var Spring = require('../lib/spring');
|
||||
var random = require('ngraph.random')(42);
|
||||
|
||||
test('Initialized with default value', function (t) {
|
||||
t.throws(() => createSpringForce());
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
||||
test('Should bump bodies at same position', function (t) {
|
||||
var body1 = new Body(0, 0);
|
||||
var body2 = new Body(0, 0);
|
||||
// length between two bodies is 2, while ideal length is 1. Each body
|
||||
// should start moving towards each other after force update
|
||||
var idealLength = 1;
|
||||
var spring = new Spring(body1, body2, idealLength);
|
||||
var springForce = createSpringForce({springCoefficient: 0.1, springLength: 1}, random);
|
||||
springForce.update(spring);
|
||||
|
||||
t.ok(body1.force.x > 0, 'Body 1 should go right');
|
||||
t.ok(body2.force.x < 0, 'Body 2 should go left');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('Check spring force direction', function (t) {
|
||||
var springForce = createSpringForce({springCoefficient: 0.1, springLength: 1});
|
||||
|
||||
t.test('Should contract two bodies when ideal length is smaller than actual', function (t) {
|
||||
var body1 = new Body(-1, 0);
|
||||
var body2 = new Body(+1, 0);
|
||||
// length between two bodies is 2, while ideal length is 1. Each body
|
||||
// should start moving towards each other after force update
|
||||
var idealLength = 1;
|
||||
var spring = new Spring(body1, body2, idealLength);
|
||||
springForce.update(spring);
|
||||
|
||||
t.ok(body1.force.x > 0, 'Body 1 should go right');
|
||||
t.ok(body2.force.x < 0, 'Body 2 should go left');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.test('Should repel two bodies when ideal length is larger than actual', function (t) {
|
||||
var body1 = new Body(-1, 0);
|
||||
var body2 = new Body(+1, 0);
|
||||
// length between two bodies is 2, while ideal length is 1. Each body
|
||||
// should start moving towards each other after force update
|
||||
var idealLength = 3;
|
||||
var spring = new Spring(body1, body2, idealLength);
|
||||
springForce.update(spring);
|
||||
|
||||
t.ok(body1.force.x < 0, 'Body 1 should go left');
|
||||
t.ok(body2.force.x > 0, 'Body 2 should go right');
|
||||
t.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue