Browse Source

start of configuration system

flowchartTest
Alex de Mulder 9 years ago
parent
commit
b954d9c9eb
10 changed files with 29560 additions and 28880 deletions
  1. +29188
    -28832
      dist/vis.js
  2. +3
    -14
      examples/network/01_basic_usage.html
  3. +7
    -1
      lib/network/Network.js
  4. +11
    -0
      lib/network/css/configuration.css
  5. +6
    -0
      lib/network/modules/Clustering.js
  6. +316
    -0
      lib/network/modules/ConfigurationSystem.js
  7. +17
    -21
      lib/network/modules/PhysicsEngine.js
  8. +1
    -2
      lib/network/modules/SelectionHandler.js
  9. +1
    -1
      lib/network/modules/components/edges/util/EdgeBase.js
  10. +10
    -9
      lib/network/modules/components/physics/BarnesHutSolver.js

+ 29188
- 28832
dist/vis.js
File diff suppressed because it is too large
View File


+ 3
- 14
examples/network/01_basic_usage.html View File

@ -44,20 +44,9 @@
nodes: nodes,
edges: edges
};
var options = {edges:{arrows:'to'},
manipulation:{
initiallyVisible: true,
handlerFunctions: {
editNode: function(data, callback) {
console.log(data)
data.label = data.label + "i"
callback(data)
}
},
controlNodeStyle: {
shape:'square'
}
}}//{physics:{stabilization:false}};
var options = {
configure:true
}//{physics:{stabilization:false}};
var network = new vis.Network(container, data, options);
</script>

+ 7
- 1
lib/network/Network.js View File

@ -23,6 +23,7 @@ import InteractionHandler from './modules/InteractionHandler';
import SelectionHandler from "./modules/SelectionHandler";
import LayoutEngine from "./modules/LayoutEngine";
import ManipulationSystem from "./modules/ManipulationSystem";
import ConfigurationSystem from "./modules/ConfigurationSystem";
/**
* @constructor Network
@ -93,7 +94,6 @@ function Network (container, data, options) {
// setting up all modules
var images = new Images(() => this.body.emitter.emit("_requestRedraw")); // object with images
this.groups = new Groups(); // object with groups
this.canvas = new Canvas(this.body); // DOM handler
this.selectionHandler = new SelectionHandler(this.body, this.canvas); // Selection handler
@ -108,6 +108,8 @@ function Network (container, data, options) {
this.nodesHandler = new NodesHandler(this.body, images, this.groups, this.layoutEngine); // Handle adding, deleting and updating of nodes as well as global options
this.edgesHandler = new EdgesHandler(this.body, images, this.groups); // Handle adding, deleting and updating of edges as well as global options
this.configurationSystem = new ConfigurationSystem(this);
// create the DOM elements
this.canvas.create();
@ -133,6 +135,8 @@ Network.prototype.setOptions = function (options) {
// the hierarchical system can adapt the edges and the physics to it's own options because not all combinations work with the hierarichical system.
options = this.layoutEngine.setOptions(options.layout, options);
// pass the options to the modules
this.groups.setOptions(options.groups);
this.nodesHandler.setOptions(options.nodes);
this.edgesHandler.setOptions(options.edges);
@ -145,7 +149,9 @@ Network.prototype.setOptions = function (options) {
this.clustering.setOptions(options.clustering);
this.manipulation.setOptions(options.manipulation);
this.configurationSystem.setOptions(options);
// handle network global options
if (options.clickToUse !== undefined) {
if (options.clickToUse === true) {
if (this.activator === undefined) {

+ 11
- 0
lib/network/css/configuration.css View File

@ -0,0 +1,11 @@
vis-network-configuration {
}
vis-network-configuration.header{
}
vis-network-configuration.label{
}

+ 6
- 0
lib/network/modules/Clustering.js View File

@ -9,10 +9,16 @@ class ClusterEngine {
constructor(body) {
this.body = body;
this.clusteredNodes = {};
this.options = {};
this.defaultOptions = {};
util.extend(this.options, this.defaultOptions);
}
setOptions(options) {
if (options !== undefined) {
}
}
/**

+ 316
- 0
lib/network/modules/ConfigurationSystem.js View File

@ -0,0 +1,316 @@
/**
* Created by Alex on 3/26/2015.
*/
var util = require('../../util');
class ConfigurationSystem {
constructor(network) {
this.network = network;
this.possibleOptions = {
nodesHandler: {
borderWidth: 1,
borderWidthSelected: 2,
color: {
border: 'color',
background: 'color',
highlight: {
border: 'color',
background: '#D2E5FF'
},
hover: {
border: 'color',
background: 'color'
}
},
fixed: {
x:false,
y:false
},
font: {
color: 'color',
size: [14,0,100,1], // px
face: ['arial','verdana','tahoma'],
background: 'color',
stroke: [0,0,50,1], // px
strokeColor: 'color'
},
group: 'string',
hidden: false,
icon: {
face: 'string', //'FontAwesome',
code: 'string', //'\uf007',
size: [50,0,200,1], //50,
color:'color' //'#aa00ff'
},
image: 'string', // --> URL
physics: true,
scaling: {
min: [10,0,200,1],
max: [30,0,200,1],
label: {
enabled: true,
min: [14,0,200,1],
max: [30,0,200,1],
maxVisible: [30,0,200,1],
drawThreshold: [3,0,20,1]
}
},
shape: ['ellipse','box','circle','circularImage','database','diamond','dot','icon','image','square','star','text','triangle','triangleDown'],
size: [25,0,200,1]
},
edgesHandler: {
arrows: {
to: {enabled: false, scaleFactor:[1,0,3,0.05]}, // boolean / {arrowScaleFactor:1} / {enabled: false, arrowScaleFactor:1}
middle: {enabled: false, scaleFactor:[1,0,3,0.05]},
from: {enabled: false, scaleFactor:[1,0,3,0.05]}
},
color: {
color:'color',
highlight:'color',
hover: 'color',
inherit: {
enabled: true,
source: ['from','to'], // from / to
useGradients: false
},
opacity:[1,0,1,0.05]
},
dashes:{
enabled: false,
length: [5,0,50,1],
gap: [5,0,50,1],
altLength: [5,0,50,1]
},
font: {
color: 'color',
size: [14,0,100,1], // px
face: ['arial','verdana','tahoma'],
background: 'color',
stroke: [0,0,50,1], // px
strokeColor: 'color',
align:['horizontal','top','middle','bottom']
},
hidden: false,
hoverWidth: [1.5,0,10,0.1],
physics: true,
scaling: {
min: [10,0,200,1],
max: [30,0,200,1],
label: {
enabled: true,
min: [14,0,200,1],
max: [30,0,200,1],
maxVisible: [30,0,200,1],
drawThreshold: [3,0,20,1]
}
},
selfReferenceSize:[20,0,200,1],
smooth: {
enabled: true,
dynamic: true,
type: ["continuous",'discrete','diagonalCross','straightCross','horizontal','vertical','curvedCW','curvedCCW'],
roundness: [0.5,0,1,0.05]
},
width: [1,0,30,1],
widthSelectionMultiplier: [2,0,5,0.1]
},
layout:{
randomSeed: [0,0,500,1],
hierarchical: {
enabled:false,
levelSeparation: [150,20,500,5],
direction: ["UD",'DU','LR','RL'], // UD, DU, LR, RL
sortMethod: ["hubsize",'directed'] // hubsize, directed
}
},
interaction: {
dragNodes:true,
dragView: true,
zoomView: true,
hoverEnabled: false,
showNavigationIcons: false,
tooltip: {
delay: [300,0,1000,25],
fontColor: 'color',
fontSize: [14,0,40,1], // px
fontFace: ['arial','verdana','tahoma'],
color: {
border: 'color',
background: 'color'
}
},
keyboard: {
enabled: false,
speed: {x: [10,0,40,1], y: [10,0,40,1], zoom: [0.02,0,0.1,0.005]},
bindToWindow: true
}
},
manipulation:{
enabled: false,
initiallyVisible: false,
locale: ['en','nl'],
functionality:{
addNode: true,
addEdge: true,
editNode: true,
editEdge: true,
deleteNode: true,
deleteEdge: true
}
},
physics: {
barnesHut: {
theta: [0.5,0.1,1,0.05],
gravitationalConstant: [-2000,-300000,0,50],
centralGravity: [0.3,0,10,0.05],
springLength: [95,0,500,5],
springConstant: [0.04,0,5,0.005],
damping: [0.09,0,1,0.01]
},
repulsion: {
centralGravity: [0.2,0,10,0.05],
springLength: [200,0,500,5],
springConstant: [0.05,0,5,0.005],
nodeDistance: [100,0,500,5],
damping: [0.09,0,1,0.01]
},
hierarchicalRepulsion: {
centralGravity: 0.2,
springLength: [100,0,500,5],
springConstant: [0.01,0,5,0.005],
nodeDistance: [120,0,500,5],
damping: [0.09,0,1,0.01]
},
maxVelocity: [50,0,150,1],
minVelocity: [0.1,0.01,0.5,0.01],
solver: ['BarnesHut','Repulsion','HierarchicalRepulsion'],
timestep: [0.5,0,1,0.05]
},
selection:{
select: true,
selectConnectedEdges: true
},
renderer: {
hideEdgesOnDrag: false,
hideNodesOnDrag: false
}
}
this.actualOptions = {};
this.domElements = [];
}
setOptions(options) {
if (options !== undefined) {
util.deepExtend(this.actualOptions, options);
if (options.configure !== undefined && options.configure !== false) {
let config;
if (options.configure instanceof Array) {
config = options.configure.join();
}
else if (typeof options.configure === 'string') {
config = options.configure;
}
else if (typeof options.configure === 'boolean') {
config = options.configure;
}
else {
this._clean();
throw new Error("the option for configure has to be either a string, boolean or an array. Supplied:" + options.configure);
return;
}
this._create(config);
}
else {
this._clean();
}
}
}
/**
*
* @param {Boolean | String} config
* @private
*/
_create(config) {
this._clean();
for (let option in this.possibleOptions) {
if (this.possibleOptions.hasOwnProperty(option)) {
if (config === true || config.indexOf(option) !== -1) {
let optionObj = this.possibleOptions[option];
// a header for the category
this._makeHeader(option);
// get the suboptions
for (let subOption in optionObj) {
if (optionObj.hasOwnProperty(subOption)) {
this._makeLabel(subOption);
let subOptionObj = optionObj[subOption];
if (subOptionObj instanceof Array) {
this._handleArray(option, subOption, subOptionObj);
}
else if (subOptionObj instanceof Object) {
this._handleObject(option, subOption, subOptionObj);
}
else if (typeof subOptionObj === 'string') {
this._handleString(option, subOption, subOptionObj);
}
else if (typeof subOptionObj === 'boolean') {
this._handleBoolean(option, subOption, subOptionObj);
}
else {
console.error("dont know how to handle", subOptionObj);
}
}
}
}
}
}
}
_clean() {
}
_makeHeader(name) {
console.log("header",name);
//let div = document.createElement('div');
//div.className = 'vis-network-configuration header';
//div.innerHTML = name;
//this.domElements.push(div);
}
_makeLabel(name) {
console.log("label",name);
//let div = document.createElement('div');
//div.className = 'vis-network-configuration label';
//div.innerHTML = name;
//this.domElements.push(div);
}
_handleObject(category, subcategory, obj) {
console.log("obj",obj);
}
_handleArray(category, subcategory, arr) {
console.log("arr",arr);
}
_handleString(category, subcategory, string) {
console.log("string",string);
}
_handleBoolean(category, subcategory, boolean) {
console.log("boolean",boolean);
}
}
export default ConfigurationSystem;

+ 17
- 21
lib/network/modules/PhysicsEngine.js View File

@ -32,7 +32,7 @@ class PhysicsEngine {
this.options = {};
this.defaultOptions = {
barnesHut: {
thetaInverted: 1 / 0.5, // inverted to save time during calculation
theta: 0.5, // inverted to save time during calculation
gravitationalConstant: -2000,
centralGravity: 0.3,
springLength: 95,
@ -40,7 +40,7 @@ class PhysicsEngine {
damping: 0.09
},
repulsion: {
centralGravity: 0.0,
centralGravity: 0.2,
springLength: 200,
springConstant: 0.05,
nodeDistance: 100,
@ -53,17 +53,17 @@ class PhysicsEngine {
nodeDistance: 120,
damping: 0.09
},
solver: 'BarnesHut',
timestep: 0.5,
maxVelocity: 50,
minVelocity: 0.1, // px/s
solver: 'BarnesHut',
stabilization: {
enabled: true,
iterations: 1000, // maximum number of iteration to stabilize
updateInterval: 100,
onlyDynamicEdges: false,
zoomExtent: true
}
},
timestep: 0.5
}
util.extend(this.options, this.defaultOptions);
@ -87,17 +87,19 @@ class PhysicsEngine {
}
setOptions(options) {
if (options === false) {
this.physicsEnabled = false;
this.stopSimulation();
}
else {
this.physicsEnabled = true;
if (options !== undefined) {
util.selectiveNotDeepExtend(['stabilization'],this.options, options);
util.mergeOptions(this.options, options, 'stabilization')
if (options !== undefined) {
if (options === false) {
this.physicsEnabled = false;
this.stopSimulation();
}
else {
this.physicsEnabled = true;
if (options !== undefined) {
util.selectiveNotDeepExtend(['stabilization'], this.options, options);
util.mergeOptions(this.options, options, 'stabilization')
}
this.init();
}
this.init();
}
}
@ -371,12 +373,6 @@ class PhysicsEngine {
/**
* When initializing and stabilizing, we can freeze nodes with a predefined position. This greatly speeds up stabilization
* because only the supportnodes for the smoothCurves have to settle.

+ 1
- 2
lib/network/modules/SelectionHandler.js View File

@ -16,7 +16,7 @@ class SelectionHandler {
this.defaultOptions = {
select: true,
selectConnectedEdges: true
}
};
util.extend(this.options, this.defaultOptions);
this.body.emitter.on("_dataChanged", () => {
@ -32,7 +32,6 @@ class SelectionHandler {
}
/**
* handles the selection part of the tap;
*

+ 1
- 1
lib/network/modules/components/edges/util/EdgeBase.js View File

@ -51,7 +51,7 @@ class EdgeBase {
_drawDashedLine(ctx) {
let via = undefined;
// only firefox and chrome support this method, else we use the legacy one.
if (ctx.setLineDash !== undefined) {
if (ctx.setLineDash !== undefined && this.options.dashes.altLength === undefined) {
ctx.save();
// configure the dash pattern
var pattern = [0];

+ 10
- 9
lib/network/modules/components/physics/BarnesHutSolver.js View File

@ -12,6 +12,7 @@ class BarnesHutSolver {
setOptions(options) {
this.options = options;
this.thetaInversed = 1/ this.options.theta;
}
@ -68,11 +69,11 @@ class BarnesHutSolver {
distance = Math.sqrt(dx * dx + dy * dy);
// BarnesHutSolver condition
// original condition : s/d < thetaInverted = passed === d/s > 1/theta = passed
// original condition : s/d < theta = passed === d/s > 1/theta = passed
// calcSize = 1/s --> d * 1/s > 1/theta = passed
if (distance * parentBranch.calcSize > this.options.thetaInverted) {
if (distance * parentBranch.calcSize > this.thetaInversed) {
// duplicate code to reduce function calls to speed up program
if (distance == 0) {
if (distance === 0) {
distance = 0.1 * Math.random();
dx = distance;
}
@ -85,7 +86,7 @@ class BarnesHutSolver {
}
else {
// Did not pass the condition, go into children if available
if (parentBranch.childrenCount == 4) {
if (parentBranch.childrenCount === 4) {
this._getForceContribution(parentBranch.children.NW, node);
this._getForceContribution(parentBranch.children.NE, node);
this._getForceContribution(parentBranch.children.SW, node);
@ -94,7 +95,7 @@ class BarnesHutSolver {
else { // parentBranch must have only one node, if it was empty we wouldnt be here
if (parentBranch.children.data.id != node.id) { // if it is not self
// duplicate code to reduce function calls to speed up program
if (distance == 0) {
if (distance === 0) {
distance = 0.5 * Math.random();
dx = distance;
}
@ -270,8 +271,8 @@ class BarnesHutSolver {
case 1: // convert into children
// if there are two nodes exactly overlapping (on init, on opening of cluster etc.)
// we move one node a pixel and we do not put it in the tree.
if (parentBranch.children[region].children.data.x == node.x &&
parentBranch.children[region].children.data.y == node.y) {
if (parentBranch.children[region].children.data.x === node.x &&
parentBranch.children[region].children.data.y === node.y) {
node.x += Math.random();
node.y += Math.random();
}
@ -297,7 +298,7 @@ class BarnesHutSolver {
_splitBranch(parentBranch) {
// if the branch is shaded with a node, replace the node in the new subset.
var containedNode = null;
if (parentBranch.childrenCount == 1) {
if (parentBranch.childrenCount === 1) {
containedNode = parentBranch.children.data;
parentBranch.mass = 0;
parentBranch.centerOfMass.x = 0;
@ -406,7 +407,7 @@ class BarnesHutSolver {
color = "#FF0000";
}
if (branch.childrenCount == 4) {
if (branch.childrenCount === 4) {
this._drawBranch(branch.children.NW, ctx);
this._drawBranch(branch.children.NE, ctx);
this._drawBranch(branch.children.SE, ctx);

Loading…
Cancel
Save