diff --git a/alerts.php b/alerts.php
index 1035214c0..6d791d213 100755
--- a/alerts.php
+++ b/alerts.php
@@ -182,7 +182,7 @@ function RunFollowUp() {
}
$alert['details'] = json_decode(gzuncompress($alert['details']), true);
- $rextra = json_decode(htmlspecialchars_decode($alert['extra']), true);
+ $rextra = json_decode($alert['extra'], true);
if ($rextra['invert']) {
continue;
}
@@ -237,7 +237,7 @@ function RunAlerts() {
$noiss = false;
$noacc = false;
$updet = false;
- $rextra = json_decode(htmlspecialchars_decode($alert['extra']), true);
+ $rextra = json_decode($alert['extra'], true);
$chk = dbFetchRow('SELECT alerts.alerted,devices.ignore,devices.disabled FROM alerts,devices WHERE alerts.device_id = ? && devices.device_id = alerts.device_id && alerts.rule_id = ?', array($alert['device_id'], $alert['rule_id']));
if ($chk['alerted'] == $alert['state']) {
$noiss = true;
diff --git a/html/ajax_dash.php b/html/ajax_dash.php
index e5622c732..0ffc58067 100644
--- a/html/ajax_dash.php
+++ b/html/ajax_dash.php
@@ -39,7 +39,7 @@ elseif (is_file('includes/common/'.$type.'.inc.php')) {
$title = ucfirst($type);
$unique_id = str_replace(array("-","."),"_",uniqid($type,true));
$widget_id = mres($_POST['id']);
- $widget_settings = json_decode(htmlspecialchars_decode(dbFetchCell('select settings from users_widgets where user_widget_id = ?',array($widget_id))),true);
+ $widget_settings = json_decode(dbFetchCell('select settings from users_widgets where user_widget_id = ?',array($widget_id)),true);
$widget_dimensions = $_POST['dimensions'];
if( !empty($_POST['settings']) ) {
define('show_settings',true);
diff --git a/html/ajax_form.php b/html/ajax_form.php
index 3851d5b4f..999a43a4d 100644
--- a/html/ajax_form.php
+++ b/html/ajax_form.php
@@ -29,7 +29,6 @@ if (!$_SESSION['authenticated']) {
if (preg_match('/^[a-zA-Z0-9\-]+$/', $_POST['type']) == 1) {
if (file_exists('includes/forms/'.$_POST['type'].'.inc.php')) {
- header('Content-type: application/json');
include_once 'includes/forms/'.$_POST['type'].'.inc.php';
}
}
diff --git a/html/ajax_search.php b/html/ajax_search.php
index cb8d012a3..ba9dc79b7 100644
--- a/html/ajax_search.php
+++ b/html/ajax_search.php
@@ -16,6 +16,7 @@ if (!$_SESSION['authenticated']) {
$device = array();
$ports = array();
$bgp = array();
+$limit = $config['webui']['global_search_result_limit'];
if (isset($_REQUEST['search'])) {
$search = mres($_REQUEST['search']);
@@ -49,10 +50,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'device') {
// Device search
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT * FROM `devices` WHERE `hostname` LIKE '%".$search."%' OR `location` LIKE '%".$search."%' ORDER BY hostname LIMIT 8");
+ $results = dbFetchRows("SELECT * FROM `devices` WHERE `hostname` LIKE '%".$search."%' OR `location` LIKE '%".$search."%' ORDER BY hostname LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT * FROM `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND (`hostname` LIKE '%".$search."%' OR `location` LIKE '%".$search."%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
+ $results = dbFetchRows("SELECT * FROM `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND (`hostname` LIKE '%".$search."%' OR `location` LIKE '%".$search."%') ORDER BY hostname LIMIT ".$limit, array($_SESSION['user_id']));
}
if (count($results)) {
@@ -102,10 +103,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'ports') {
// Search ports
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%' ORDER BY ifDescr LIMIT 8");
+ $results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%' ORDER BY ifDescr LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT DISTINCT(`I`.`port_id`), `I`.*, `D`.`hostname` FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%') ORDER BY ifDescr LIMIT 8", array($_SESSION['user_id'], $_SESSION['user_id']));
+ $results = dbFetchRows("SELECT DISTINCT(`I`.`port_id`), `I`.*, `D`.`hostname` FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifAlias` LIKE '%".$search."%' OR `ifDescr` LIKE '%".$search."%' OR `ifName` LIKE '%".$search."%') ORDER BY ifDescr LIMIT ".$limit, array($_SESSION['user_id'], $_SESSION['user_id']));
}
if (count($results)) {
@@ -154,10 +155,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'bgp') {
// Search bgp peers
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT `bgpPeers`.*,`devices`.* FROM `bgpPeers` LEFT JOIN `devices` ON `bgpPeers`.`device_id` = `devices`.`device_id` WHERE `astext` LIKE '%".$search."%' OR `bgpPeerIdentifier` LIKE '%".$search."%' OR `bgpPeerRemoteAs` LIKE '%".$search."%' ORDER BY `astext` LIMIT 8");
+ $results = dbFetchRows("SELECT `bgpPeers`.*,`devices`.* FROM `bgpPeers` LEFT JOIN `devices` ON `bgpPeers`.`device_id` = `devices`.`device_id` WHERE `astext` LIKE '%".$search."%' OR `bgpPeerIdentifier` LIKE '%".$search."%' OR `bgpPeerRemoteAs` LIKE '%".$search."%' ORDER BY `astext` LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT `bgpPeers`.*,`D`.* FROM `bgpPeers`, `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND `bgpPeers`.`device_id`=`D`.`device_id` AND (`astext` LIKE '%".$search."%' OR `bgpPeerIdentifier` LIKE '%".$search."%' OR `bgpPeerRemoteAs` LIKE '%".$search."%') ORDER BY `astext` LIMIT 8", array($_SESSION['user_id']));
+ $results = dbFetchRows("SELECT `bgpPeers`.*,`D`.* FROM `bgpPeers`, `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND `bgpPeers`.`device_id`=`D`.`device_id` AND (`astext` LIKE '%".$search."%' OR `bgpPeerIdentifier` LIKE '%".$search."%' OR `bgpPeerRemoteAs` LIKE '%".$search."%') ORDER BY `astext` LIMIT ".$limit, array($_SESSION['user_id']));
}
if (count($results)) {
@@ -209,10 +210,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'applications') {
// Device search
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` ON devices.device_id = applications.device_id WHERE `app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT 8");
+ $results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` ON devices.device_id = applications.device_id WHERE `app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `applications`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
+ $results = dbFetchRows("SELECT * FROM `applications` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `applications`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`app_type` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT ".$limit, array($_SESSION['user_id']));
}
if (count($results)) {
@@ -255,10 +256,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'munin') {
// Device search
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` ON devices.device_id = munin_plugins.device_id WHERE `mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT 8");
+ $results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` ON devices.device_id = munin_plugins.device_id WHERE `mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%' ORDER BY hostname LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `munin_plugins`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
+ $results = dbFetchRows("SELECT * FROM `munin_plugins` INNER JOIN `devices` AS `D` ON `D`.`device_id` = `munin_plugins`.`device_id` INNER JOIN `devices_perms` AS `P` ON `P`.`device_id` = `D`.`device_id` WHERE `P`.`user_id` = ? AND (`mplug_type` LIKE '%".$search."%' OR `mplug_title` LIKE '%".$search."%' OR `hostname` LIKE '%".$search."%') ORDER BY hostname LIMIT ".$limit, array($_SESSION['user_id']));
}
if (count($results)) {
@@ -301,10 +302,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'iftype') {
// Device search
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT `ports`.ifType FROM `ports` WHERE `ifType` LIKE '%".$search."%' GROUP BY ifType ORDER BY ifType LIMIT 8");
+ $results = dbFetchRows("SELECT `ports`.ifType FROM `ports` WHERE `ifType` LIKE '%".$search."%' GROUP BY ifType ORDER BY ifType LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT `I`.ifType FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifType` LIKE '%".$search."%') GROUP BY ifType ORDER BY ifType LIMIT 8", array($_SESSION['user_id'], $_SESSION['user_id']));
+ $results = dbFetchRows("SELECT `I`.ifType FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifType` LIKE '%".$search."%') GROUP BY ifType ORDER BY ifType LIMIT ".$limit, array($_SESSION['user_id'], $_SESSION['user_id']));
}
if (count($results)) {
$found = 1;
@@ -323,10 +324,10 @@ if (isset($_REQUEST['search'])) {
else if ($_REQUEST['type'] == 'bill') {
// Device search
if (is_admin() === true || is_read() === true) {
- $results = dbFetchRows("SELECT `bills`.bill_id, `bills`.bill_name FROM `bills` WHERE `bill_name` LIKE '%".$search."%' OR `bill_notes` LIKE '%".$search."%' LIMIT 8");
+ $results = dbFetchRows("SELECT `bills`.bill_id, `bills`.bill_name FROM `bills` WHERE `bill_name` LIKE '%".$search."%' OR `bill_notes` LIKE '%".$search."%' LIMIT ".$limit);
}
else {
- $results = dbFetchRows("SELECT `bills`.bill_id, `bills`.bill_name FROM `bills` INNER JOIN `bill_perms` ON `bills`.bill_id = `bill_perms`.bill_id WHERE `bill_perms`.user_id = ? AND (`bill_name` LIKE '%".$search."%' OR `bill_notes` LIKE '%".$search."%') LIMIT 8", array($_SESSION['user_id']));
+ $results = dbFetchRows("SELECT `bills`.bill_id, `bills`.bill_name FROM `bills` INNER JOIN `bill_perms` ON `bills`.bill_id = `bill_perms`.bill_id WHERE `bill_perms`.user_id = ? AND (`bill_name` LIKE '%".$search."%' OR `bill_notes` LIKE '%".$search."%') LIMIT ".$limit, array($_SESSION['user_id']));
}
$json = json_encode($results);
die($json);
diff --git a/html/graph.php b/html/graph.php
index 99c53bd29..0eff18fc3 100644
--- a/html/graph.php
+++ b/html/graph.php
@@ -40,8 +40,9 @@ require_once '../includes/dbFacile.php';
require_once '../includes/rewrites.php';
require_once 'includes/functions.inc.php';
require_once '../includes/rrdtool.inc.php';
-require_once 'includes/authenticate.inc.php';
-
+if($config['allow_unauth_graphs'] != true) {
+ require_once 'includes/authenticate.inc.php';
+}
require 'includes/graphs/graph.inc.php';
$console_color = new Console_Color2();
diff --git a/html/includes/common/alerts.inc.php b/html/includes/common/alerts.inc.php
index 44495f347..db87ba82d 100644
--- a/html/includes/common/alerts.inc.php
+++ b/html/includes/common/alerts.inc.php
@@ -156,7 +156,7 @@ else {
-
+
Status
@@ -171,7 +171,7 @@ else {
-
\ No newline at end of file
+
diff --git a/lib/vis/docs/data/dataview.html b/lib/vis/docs/data/dataview.html
index 1b1246b3d..9a98f7f2e 100644
--- a/lib/vis/docs/data/dataview.html
+++ b/lib/vis/docs/data/dataview.html
@@ -248,7 +248,7 @@ var data = new vis.DataView(dataset, options)
Object | Array
Get a single item, multiple items, or all items from the DataView.
- Usage examples can be found in section Getting Data, and the available options are described in section Data Selection.
+ Usage examples can be found in section Getting Data, and the available options are described in section Data Selection. When no item is found, null is returned when a single item was requested, and and empty Array is returned in case of multiple id's.
@@ -307,7 +307,7 @@ var view = new vis.DataView(data, {
Graph2d can load data from an Array, a DataSet (offering 2 way data binding), or a DataView (offering one way data binding).
Objects are added to this DataSet by using the add() function.
- Data points must have properties x, y, and z,
- and can optionally have a property style and filter.
Graph2d can be provided with two types of data:
@@ -383,8 +381,8 @@ groups.add({
visible
Boolean
-
true
-
This field is optional. If false, this group will not be drawn.
+
no
+
This field is optional. If false, this group will not be drawn. By default it is true.
@@ -436,7 +434,7 @@ var options = {
barChart.sideBySide
Boolean
false
-
If two datapoints of a barchart overlap, they are drawn over eachother by default. If sideBySide is set to true, they will be drawn side by side.
+
If two datapoints of a barchart overlap, they are drawn over eachother by default. If sideBySide is set to true, they will be drawn side by side, within the same width as a single bar..
See example 10 for more information.
When using groups, see example 11.
@@ -447,7 +445,12 @@ var options = {
50
The width of the bars.
-
+
+
barChart.minWidth
+
Number
+
+
The minimum width of the bars in pixels: by default the bars get smaller while zooming out to prevent overlap, this value is the minimum width of the bar. Default behavior (when minWidth is not set) is 10% of the bar width.
+
dataAxis
Object
@@ -472,12 +475,11 @@ var options = {
Function
Insert a custom function on how to format the label. The function will receive a numeric value and has to return a string. Default function is:
-
+
function (value) {
- return value;
-}
-
- which does nothing to it.
+ return ''+value.toPrecision(3);
+}
+
dataAxis.left.range.min
@@ -578,7 +580,7 @@ drawPoints: {
3. Function: If a function is provided it will be used as a callback. The function may return values from listing 1 or 2.
If stack is enabled, the graphs will be stacked upon eachother when applicable. This currently only works with bar graphs but linegraph support is being worked on.
+
If stack is enabled, the graphs will be stacked upon each-other when applicable. A group can opt-out of stacking through the "excludeFromStacking" option.
This determines if the shaded area is at the bottom or at the top of the curve. The options are 'bottom' or 'top'.
+
This determines if the shaded area is at the bottom or at the top of the curve, or always towards the zero-axis of the graph.
+ The options are 'zero', 'bottom', 'top', or the special case of 'group'. If group is chosen, the option groupId is required.
+ See Example 20 what these options look like.
+
+
+
+
shaded.groupId
+
String
+
undefined
+
The id of the group which should be used as the other shading limit.
+
This defines with which axis, left or right, the graph is coupled. Example 5 shows groups with different Y axis. If no groups are coupled
with an axis, it will not be shown.
+
+
excludeFromLegend
+
Boolean
+
false
+
Group option only. Excludes the group from being listed in the legend.
+
+
+
excludeFromStacking
+
Boolean
+
false
+
Group option only. Excludes the group from being included in the stacking.
+
Timeline Options
@@ -895,14 +919,14 @@ function (option, path) {
locale
String
none
-
Select a locale for the Graph2d. See section Localization for more information.
+
Select a locale for the Graph2d. See section Localization for more information.
locales
Object
none
-
A map with i18n locales. See section Localization for more information.
+
A map with i18n locales. See section Localization for more information.
@@ -921,6 +945,16 @@ function (option, path) {
Specifies the maximum height for the Timeline. Can be a number in pixels or a string like "300px".
+
+
maxMinorChars
+
number
+
7
+
+ Specifies the maximum number of characters that should fit in minor grid labels.
+ If larger, less and wider grids will be drawn.
+
+
+
min
Date or Number or String
@@ -991,22 +1025,6 @@ function (option, path) {
visible.
-
-
showMajorLines
-
Boolean
-
true
-
By default, the timeline shows both minor and major date lines on the
- time axis. You can use this option to hide the lines from the major dates.
-
-
-
-
showMinorLines
-
Boolean
-
true
-
By default, the timeline shows both minor and major date lines on the
- time axis. You can use this option to hide the lines from the minor dates.
-
Exactly the same as the to object but with an arrowhead at the from node of the edge.
+
+
arrowStrikethrough
+
Boolean
+
true
+
When false, the edge stops at the arrow. This can be useful if you have thick lines and you want the arrow to end in a point. Middle arrows are not affected by this.
+
color
Object or String
@@ -581,6 +589,12 @@ var options: {
in this object are defined.
+
+
shadow.color
+
String
+
'rgba(0,0,0,0.5)'
+
The color size of the shadow as a string. Supported formats are 'rgb(255,255,255)', 'rgba(255,255,255,1)' and '#FFFFFF'.
When a Network is configured to be clickToUse, it will react to mouse and touch events only when active. When active, a blue shadow border is displayed around the Network. The network is set active by clicking on it, and is changed to inactive again by clicking outside the Network or by pressing the ESC key.
configure
@@ -944,6 +940,28 @@ function releaseFunction (clusterPosition, containedNodesPositions) {
before selecting its own objects. Does not fire events.
@@ -968,8 +986,8 @@ function releaseFunction (clusterPosition, containedNodesPositions) {
getViewPosition()
-
Returns: Number
-
Returns the current central focus point of the view.
+
Returns: Object
+
Returns the current central focus point of the view in the form: { x: {Number}, y: {Number} }
@@ -1301,19 +1319,19 @@ var options = {
hoverNode
{node: nodeId}
-
Fired interaction:{hover:true} and the mouse hovers over a node.
+
Fired if the option interaction:{hover:true} is enabled and the mouse hovers over a node.
blurNode
{node: nodeId}
-
Fired interaction:{hover:true} and the mouse moved away from a node it was hovering over before.
+
Fired if the option interaction:{hover:true} is enabled and the mouse moved away from a node it was hovering over before.
hoverEdge
{edge: edgeId}
-
Fired interaction:{hover:true} and the mouse hovers over an edge.
+
Fired if the option interaction:{hover:true} is enabled and the mouse hovers over an edge.
blurEdge
{edge: edgeId}
-
Fired interaction:{hover:true} and the mouse moved away from an edge it was hovering over before.
+
Fired if the option interaction:{hover:true} is enabled and the mouse moved away from an edge it was hovering over before.
zoom
{direction:'+'/'-', scale: Number}
@@ -1557,4 +1575,4 @@ var network = new vis.Network(container, data, options);
-
\ No newline at end of file
+
diff --git a/lib/vis/docs/network/layout.html b/lib/vis/docs/network/layout.html
index ea33c7ddb..08f1eca98 100644
--- a/lib/vis/docs/network/layout.html
+++ b/lib/vis/docs/network/layout.html
@@ -101,11 +101,16 @@
var options = {
layout: {
randomSeed: undefined,
+ improvedLayout:true,
hierarchical: {
enabled:false,
levelSeparation: 150,
- direction: 'UD', // UD, DU, LR, RL
- sortMethod: 'hubsize' // hubsize, directed
+ nodeSpacing: 100,
+ treeSpacing: 200,
+ blockShifting: true,
+ edgeMinimization: true,
+ direction: 'UD', // UD, DU, LR, RL
+ sortMethod: 'hubsize' // hubsize, directed
}
}
}
@@ -127,9 +132,16 @@ network.setOptions(options);
Name
Type
Default
Description
randomSeed
Number
undefined
When NOT using the hierarchical layout, the nodes are randomly positioned initially. This means that the settled result is different every time. If you provide a random seed manually, the layout will be the same every time. Ideally you try with an undefined seed, reload until you are happy with the layout and use the getSeed() method to ascertain the seed.
+
improvedLayout
Boolean
true
When enabled, the network will use the Kamada Kawai algorithm for initial layout. For networks larger than 100 nodes, clustering will be performed automatically to reduce the amount of nodes. This can greatly improve the stabilization times. If the network is very interconnected (no or few leaf nodes), this may not work and it will revert back to the old method. Performance will be improved in the future.
hierarchical
Object or Boolean
Object
When true, the layout engine positions the nodes in a hierarchical fashion using default settings. For customization you can supply an object.
hierarchical.enabled
Boolean
false
Toggle the usage of the hierarchical layout system. If this option is not defined, it is set to true if any of the properties in this object are defined.
hierarchical.levelSeparation
Number
150
The distance between the different levels.
+
hierarchical.nodeSpacing
Number
100
Minimum distance between nodes on the free axis. This is only for the initial layout. If you enable physics, the node distance there will be the effective node distance.
+
hierarchical.treeSpacing
Number
200
Distance between different trees (independent networks). This is only for the initial layout. If you enable physics, the repulsion model will denote the distance between the trees.
+
hierarchical.blockShifting
Boolean
true
Method for reducing whitespace. Can be used alone or together with edge minimization. Each node will check for whitespace and will shift
+ it's branch along with it for as far as it can, respecting the nodeSpacing on any level. This is mainly for the initial layout. If you enable physics, they layout will be determined by the physics. This will greatly speed up the stabilization time though!
+
hierarchical.edgeMinimization
Boolean
true
Method for reducing whitespace. Can be used alone or together with block shifting. Enabling block shifting will usually speed up the layout process.
+ Each node will try to move along its free axis to reduce the total length of it's edges. This is mainly for the initial layout. If you enable physics, they layout will be determined by the physics. This will greatly speed up the stabilization time though!
hierarchical.direction
String
'UD'
The direction of the hierarchical layout. The available options are: UD, DU, LR, RL. To simplify: up-down, down-up, left-right, right-left.
hierarchical.sortMethod
String
'hubsize'
The algorithm used to ascertain the levels of the nodes based on the data. The possible options are: hubsize, directed.
Hubsize takes the nodes with the most edges and puts them at the top. From that the rest of the hierarchy is evaluated.
diff --git a/lib/vis/docs/network/manipulation.html b/lib/vis/docs/network/manipulation.html
index b83710dfe..7f8db9523 100644
--- a/lib/vis/docs/network/manipulation.html
+++ b/lib/vis/docs/network/manipulation.html
@@ -162,9 +162,9 @@ var options = {
}
}
- This example code will show a popup if you connect a node to itself to ask you if that was what you wanted. If you do not want the edge created, do not call the callback function or call the callback function null or no argument.
+ This example code will show a popup if you connect a node to itself to ask you if that was what you wanted. If you do not want the edge created, do not call the callback function or call the callback function null or no argument.
editNode
Function
undefined
Editing of nodes is only possible when a handling function is supplied. If this is not the case, editing of nodes will be disabled. The function will be called when a node is selected and the 'Edit Node' button on the toolbar is pressed. This function will be called like the addNode function with the node's data and a callback function.
-
editEdge
Boolean or Function
true
If boolean, toggle the editing of edges in the GUI. When a function is supplied, it will be called when an edge is selcted and the 'Edit Edge' button on the toolbar is pressed. This function will be called in the same way the addEdge function was called. If the callback is not performed, the edge will remain hanging where it was released. To cancel, call the callback function with null as argument or without arguments.
+
editEdge
Boolean or Function
true
If boolean, toggle the editing of edges in the GUI. When a function is supplied, it will be called when an edge is selected and the 'Edit Edge' button on the toolbar is pressed. This function will be called in the same way the addEdge function was called. If the callback is not performed, the edge will remain hanging where it was released. To cancel, call the callback function with null as argument or without arguments.
deleteNode
Boolean or Function
true
If boolean, toggle the deletion of nodes in the GUI. If function, it will be called when a node is selected and the 'Delete selected' button is pressed. When using a function, it will receive a callback and an object with an array of selected nodeIds and an array of selected edges Ids. These are the items that will be deleted if the callback is performed.
deleteEdge
Boolean or Function
true
If boolean, toggle the deletion of edges in the GUI. If function, it will be called when an edge is selected and the 'Delete selected' button is pressed. When using a function, it will receive a callback and an object with an array of selected nodeIds (empty) and an array of selected edges Ids. These are the items that will be deleted if the callback is performed.
controlNodeStyle
Object
Object
You can supply any styling information you'd like here. All fields described in the nodes module are allowed except obviously for id, x, y and fixed.
The options for the nodes have to be contained in an object titled 'nodes'. All of these options can be supplied per node as well. Obviously, 'id' should not be defined globally but per node. Options defined
in the global nodes object, are applied to all nodes. If a node has options of its own, those will be used instead of the global options.
-
When you have given a node an option, you will override the global option for that property. If you then set that option to null,
+
When you have given a node an option, you will override the global option for that property, and also the group option for that property if the node is in a group. If you then set that option to null,
it will revert back to the default value.
Click on the full options or shorthand options to show how these options are supposed to be used.
@@ -108,7 +108,7 @@
var options = {
nodes:{
borderWidth: 1,
- borderWidthSelected: undefined,
+ borderWidthSelected: 2,
brokenImage:undefined,
color: {
border: '#2B7CE9',
@@ -171,14 +171,17 @@ var options = {
},
shadow:{
enabled: false,
+ color: 'rgba(0,0,0,0.5)',
size:10,
x:5,
y:5
},
shape: 'ellipse',
shapeProperties: {
- borderDashes: false, // only for shapes with a border
- borderRadius: 6 // only for box shape
+ borderDashes: false, // only for borders
+ borderRadius: 6, // only for box shape
+ useImageSize: false, // only for image and circularImage shapes
+ useBorderWithImage: false // only for image shape
}
size: 25,
title: undefined,
@@ -224,8 +227,8 @@ network.setOptions(options);
borderWidthSelected
Number
-
undefined
-
The width of the border of the node when it is selected. When undefined, the borderWidth is used
+
2
+
The width of the border of the node when it is selected. When undefined, the borderWidth * 2 is used.
brokenImage
@@ -374,7 +377,9 @@ network.setOptions(options);
group
String
undefined
-
When not undefined, the
+
When not undefined, the node will belong to the defined group. Styling information of
+ that group will apply to this node. Node specific styling overrides group styling.
+
hidden
@@ -581,6 +586,12 @@ mySize = minSize + diff * scale;
in this object are defined.
+
+
shadow.color
+
String
+
'rgba(0,0,0,0.5)'
+
The color size of the shadow as a string. Supported formats are 'rgb(255,255,255)', 'rgba(255,255,255,1)' and '#FFFFFF'.
+
shadow.size
Number
@@ -642,6 +653,15 @@ mySize = minSize + diff * scale;
if this is set to true, the image cannot be scaled with the value option!
+
+
shapeProperties.useBorderWithImage
+
Boolean
+
false
+
This property only applies to the image shape.
+ When true, the color object is used. A rectangle with the background color is
+ drawn behind it and it has a border. This means all border options are taken into account.
+
+
size
Number
@@ -704,4 +724,4 @@ mySize = minSize + diff * scale;
-
\ No newline at end of file
+
diff --git a/lib/vis/docs/network/physics.html b/lib/vis/docs/network/physics.html
index cb9acb076..c8fe99208 100644
--- a/lib/vis/docs/network/physics.html
+++ b/lib/vis/docs/network/physics.html
@@ -138,7 +138,8 @@ var options = {
onlyDynamicEdges: false,
fit: true
},
- timestep: 0.5
+ timestep: 0.5,
+ adaptiveTimestep: true
}
}
@@ -201,6 +202,7 @@ network.setOptions(options);
stabilization.onlyDynamicEdges
Boolean
false
If you have predefined the position of all nodes and only want to stabilize the dynamic smooth edges, set this to true. It freezes all nodes except the invisible dynamic smooth curve support nodes. If you want the visible nodes to move and stabilize, do not use this.
stabilization.fit
Boolean
true
Toggle whether or not you want the view to zoom to fit all nodes when the stabilization is finished.
timestep
Number
0.5
The physics simulation is discrete. This means we take a step in time, calculate the forces, move the nodes and take another step. If you increase this number the steps will be too large and the network can get unstable. If you see a lot of jittery movement in the network, you may want to reduce this value a little.
+
adaptiveTimestep
Boolean
true
If this is enabled, the timestep will intelligently be adapted (only during the stabilization stage if stabilization is enabled!) to greatly decrease stabilization times. The timestep configured above is taken as the minimum timestep. This can be further improved by using the improvedLayout algorithm.
The following code shows how to create a Timeline and provide it with data.
- More examples can be found in the examples directory.
+ More examples can be found in the timeline examples page.
<!DOCTYPE HTML>
@@ -588,12 +588,51 @@ function (option, path) {
+
+
groupEditable
+
boolean or Object
+
false
+
If true, the groups in the timeline can be manipulated. See also the callbacks onAddGroup, onMoveGroup, and onRemoveGroup. When groupEditable is an object, one can enable or disable individual manipulation actions.
+ The editing of groups follows the same principles as for items, see section Editing Items for a detailed explanation.
+
+
+
+
groupEditable.add
+
boolean
+
false
+
If true, new groups can be created in the Timeline. For now adding new groups is done by the user.
+
+
+
groupEditable.remove
+
boolean
+
false
+
If true, groups can be deleted. For now removing groups is done by the user.
+
+
+
groupEditable.order
+
boolean
+
false
+
If true, groups can be dragged to change their order. Only applicable when the Timeline has groups. For this option to work properly the groupOrder and groupOrderSwap options have to be set as well.
+
+
groupOrder
String or Function
-
none
+
'order'
Order the groups by a field name or custom sort function.
- By default, groups are not ordered.
+ By default, groups are ordered by a property order (if set).
+ If no order properties are provided, the order will be undetermined.
+
+
+
+
+
groupOrderSwap
+
Function
+
none
+
Swaps the positions of two groups. If groups have a custom order (via groupOrder) and groups are configured to be reorderable (via groupEditable.order), the user has to provide a function that swaps the positions of two given groups.
+ If this option is not set, the default implementation assumes that groups hold an attribute order which values are changed. The signature of the groupOrderWap function is:
+
function groupOrderSwap(fromGroup: Object, toGroup: Object, groups: DataSet)
+ The first to arguments hold the groups of which the positions are to be swapped and the third argument holds the DataSet with all groups.
@@ -627,6 +666,14 @@ function (option, path) {
and set repeat to weekly.
+
+
+
itemsAlwaysDraggable
+
boolean
+
false
+
If true, all items in the Timeline are draggable without being selected. If false, only the selected item(s) are draggable.
+
+
locale
String
@@ -695,6 +742,16 @@ function (option, path) {
Specifies the maximum height for the Timeline. Can be a number in pixels or a string like "300px".
+
+
maxMinorChars
+
number
+
7
+
+ Specifies the maximum number of characters that should fit in minor grid labels.
+ If larger, less and wider grids will be drawn.
+
+
+
min
Date or Number or String or Moment
@@ -730,6 +787,16 @@ function (option, path) {
Only applicable when option selectable is true.
+
+
+
multiselectPerGroup
+
boolean
+
false
+
+ If true, selecting multiple items using shift+click will only select items residing in the same group as the first selected item.
+ Only applicable when option selectable and multiselect are true.
+
+
onAdd
@@ -738,6 +805,14 @@ function (option, path) {
Callback function triggered when an item is about to be added: when the user double taps an empty space in the Timeline. See section Editing Items for more information. Only applicable when both options selectable and editable.add are set true.
+
+
+
onAddGroup
+
function
+
none
+
Callback function triggered when a group is about to be added. The signature and semantics are the same as for onAdd.
+
+
onUpdate
@@ -754,6 +829,14 @@ function (option, path) {
Callback function triggered when an item has been moved: after the user has dragged the item to an other position. See section Editing Items for more information. Only applicable when both options selectable and editable.updateTime or editable.updateGroup are set true.
+
+
+
onMoveGroup
+
function
+
none
+
Callback function triggered when a group has been moved: after the user has dragged the group to an other position. The signature and semantics are the same as for onMove.
+
+
onMoving
@@ -770,6 +853,14 @@ function (option, path) {
Callback function triggered when an item is about to be removed: when the user tapped the delete button on the top right of a selected item. See section Editing Items for more information. Only applicable when both options selectable and editable.remove are set true.
+
+
+
onRemoveGroup
+
function
+
none
+
Callback function triggered when a group is about to be removed. The signature and semantics are the same as for onRemove.
+
+
order
@@ -876,6 +967,13 @@ function (option, path) {
A template function used to generate the contents of the items. The function is called by the Timeline with an items data as argument, and must return HTML code as result. When the option template is specified, the items do not need to have a field content. See section Templates for a detailed explanation.
+
+
throttleRedraw
+
number
+
0
+
Limit the maximum number of redraws to once every x milliseconds. For example setting throttleRedraw to `100` milliseconds will limit the number of redraws to 10 times per second.
+
+
timeAxis
Object
@@ -892,6 +990,7 @@ function (option, path) {
}
+
timeAxis.step
number
@@ -1125,6 +1224,15 @@ document.getElementById('myTimeline').onclick = function (event) {
+
+
setCustomTimeTitle(title [, id])
+
none
+
Adjust the title attribute of a custom time bar.
+ Parameter title is the string to be set as title. Use empty string to hide the title completely.
+ Parameter id is the id of the custom time bar, and is undefined by default.
+
+ This example shows the shading functionality within Graph2d.
+
+
+
+
+
+
+
+
diff --git a/lib/vis/examples/network/datasources/largeHierarchicalDataset.js b/lib/vis/examples/network/datasources/largeHierarchicalDataset.js
new file mode 100644
index 000000000..ddbb524e7
--- /dev/null
+++ b/lib/vis/examples/network/datasources/largeHierarchicalDataset.js
@@ -0,0 +1,2 @@
+var nodes = [{id:0,label:0},{id:1,label:1},{id:2,label:2},{id:3,label:3},{id:4,label:4},{id:5,label:5},{id:6,label:6},{id:7,label:7},{id:8,label:8},{id:9,label:9},{id:10,label:10},{id:11,label:11},{id:12,label:12},{id:13,label:13},{id:14,label:14},{id:15,label:15},{id:16,label:16},{id:17,label:17},{id:18,label:18},{id:19,label:19},{id:20,label:20},{id:21,label:21},{id:22,label:22},{id:23,label:23},{id:24,label:24},{id:25,label:25},{id:26,label:26},{id:27,label:27},{id:28,label:28},{id:29,label:29},{id:30,label:30},{id:31,label:31},{id:32,label:32},{id:33,label:33},{id:34,label:34},{id:35,label:35},{id:36,label:36},{id:37,label:37},{id:38,label:38},{id:39,label:39},{id:40,label:40},{id:41,label:41},{id:42,label:42},{id:43,label:43},{id:44,label:44},{id:45,label:45},{id:46,label:46},{id:47,label:47},{id:48,label:48},{id:49,label:49},{id:50,label:50},{id:51,label:51},{id:52,label:52},{id:53,label:53},{id:54,label:54},{id:55,label:55},{id:56,label:56},{id:57,label:57},{id:58,label:58},{id:59,label:59},{id:60,label:60},{id:61,label:61},{id:62,label:62},{id:63,label:63},{id:64,label:64},{id:65,label:65},{id:66,label:66},{id:67,label:67},{id:68,label:68},{id:69,label:69},{id:70,label:70},{id:71,label:71},{id:72,label:72},{id:73,label:73},{id:74,label:74},{id:75,label:75},{id:76,label:76},{id:77,label:77},{id:78,label:78},{id:79,label:79},{id:80,label:80},{id:81,label:81},{id:82,label:82},{id:83,label:83},{id:84,label:84},{id:85,label:85},{id:86,label:86},{id:87,label:87},{id:88,label:88},{id:89,label:89},{id:90,label:90},{id:91,label:91},{id:92,label:92},{id:93,label:93},{id:94,label:94},{id:95,label:95},{id:96,label:96},{id:97,label:97},{id:98,label:98},{id:99,label:99},{id:100,label:100},{id:101,label:101},{id:102,label:102},{id:103,label:103},{id:104,label:104},{id:105,label:105},{id:106,label:106},{id:107,label:107},{id:108,label:108},{id:109,label:109},{id:110,label:110},{id:111,label:111},{id:112,label:112},{id:113,label:113},{id:114,label:114},{id:115,label:115},{id:116,label:116},{id:117,label:117},{id:118,label:118},{id:119,label:119},{id:120,label:120},{id:121,label:121},{id:122,label:122},{id:123,label:123},{id:124,label:124},{id:125,label:125},{id:126,label:126},{id:127,label:127},{id:128,label:128},{id:129,label:129},{id:130,label:130},{id:131,label:131},{id:132,label:132},{id:133,label:133},{id:134,label:134},{id:135,label:135},{id:136,label:136},{id:137,label:137},{id:138,label:138},{id:139,label:139},{id:140,label:140},{id:141,label:141},{id:142,label:142},{id:143,label:143},{id:144,label:144},{id:145,label:145},{id:146,label:146},{id:147,label:147},{id:148,label:148},{id:149,label:149},{id:150,label:150},{id:151,label:151},{id:152,label:152},{id:153,label:153},{id:154,label:154},{id:155,label:155},{id:156,label:156},{id:157,label:157},{id:158,label:158},{id:159,label:159},{id:160,label:160},{id:161,label:161},{id:162,label:162},{id:163,label:163},{id:164,label:164},{id:165,label:165},{id:166,label:166},{id:167,label:167},{id:168,label:168},{id:169,label:169},{id:170,label:170},{id:171,label:171},{id:172,label:172},{id:173,label:173},{id:174,label:174},{id:175,label:175},{id:176,label:176},{id:177,label:177},{id:178,label:178},{id:179,label:179},{id:180,label:180},{id:181,label:181},{id:182,label:182},{id:183,label:183},{id:184,label:184},{id:185,label:185},{id:186,label:186},{id:187,label:187},{id:188,label:188},{id:189,label:189},{id:190,label:190},{id:191,label:191},{id:192,label:192},{id:193,label:193},{id:194,label:194},{id:195,label:195},{id:196,label:196},{id:197,label:197},{id:198,label:198},{id:199,label:199},{id:200,label:200},{id:201,label:201},{id:202,label:202},{id:203,label:203},{id:204,label:204},{id:205,label:205},{id:206,label:206},{id:207,label:207},{id:208,label:208},{id:209,label:209},{id:210,label:210},{id:211,label:211},{id:212,label:212},{id:213,label:213},{id:214,label:214},{id:215,label:215},{id:216,label:216},{id:217,label:217},{id:218,label:218},{id:219,label:219},{id:220,label:220},{id:221,label:221},{id:222,label:222},{id:223,label:223},{id:224,label:224},{id:225,label:225},{id:226,label:226},{id:227,label:227},{id:228,label:228},{id:229,label:229},{id:230,label:230},{id:231,label:231},{id:232,label:232},{id:233,label:233},{id:234,label:234},{id:235,label:235},{id:236,label:236},{id:237,label:237},{id:238,label:238},{id:239,label:239},{id:240,label:240},{id:241,label:241},{id:242,label:242},{id:243,label:243},{id:244,label:244},{id:245,label:245},{id:246,label:246},{id:247,label:247},{id:248,label:248},{id:249,label:249},{id:250,label:250},{id:251,label:251},{id:252,label:252},{id:253,label:253},{id:254,label:254},{id:255,label:255},{id:256,label:256},{id:257,label:257},{id:258,label:258},{id:259,label:259},{id:260,label:260},{id:261,label:261},{id:262,label:262},{id:263,label:263},{id:264,label:264},{id:265,label:265},{id:266,label:266},{id:267,label:267},{id:268,label:268},{id:269,label:269},{id:270,label:270},{id:271,label:271},{id:272,label:272},{id:273,label:273},{id:274,label:274},{id:275,label:275},{id:276,label:276},{id:277,label:277},{id:278,label:278},{id:279,label:279},{id:280,label:280},{id:281,label:281},{id:282,label:282},{id:283,label:283},{id:284,label:284},{id:285,label:285},{id:286,label:286},{id:287,label:287},{id:288,label:288},{id:289,label:289},{id:290,label:290},{id:291,label:291},{id:292,label:292},{id:293,label:293},{id:294,label:294},{id:295,label:295},{id:296,label:296},{id:297,label:297},{id:298,label:298},{id:299,label:299},{id:300,label:300},{id:301,label:301},{id:302,label:302},{id:303,label:303},{id:304,label:304},{id:305,label:305},{id:306,label:306},{id:307,label:307},{id:308,label:308},{id:309,label:309},{id:310,label:310},{id:311,label:311},{id:312,label:312},{id:313,label:313},{id:314,label:314},{id:315,label:315},{id:316,label:316},{id:317,label:317},{id:318,label:318},{id:319,label:319},{id:320,label:320},{id:321,label:321},{id:322,label:322},{id:323,label:323},{id:324,label:324},{id:325,label:325},{id:326,label:326},{id:327,label:327},{id:328,label:328},{id:329,label:329},{id:330,label:330},{id:331,label:331},{id:332,label:332},{id:333,label:333},{id:334,label:334},{id:335,label:335},{id:336,label:336},{id:337,label:337},{id:338,label:338},{id:339,label:339},{id:340,label:340},{id:341,label:341},{id:342,label:342},{id:343,label:343},{id:344,label:344},{id:345,label:345},{id:346,label:346},{id:347,label:347}];
+var edges = [{from:331,to:0,id:"e0"},{from:331,to:1,id:"e1"},{from:302,to:2,id:"e2"},{from:321,to:3,id:"e3"},{from:323,to:4,id:"e4"},{from:326,to:5,id:"e5"},{from:24,to:6,id:"e6"},{from:327,to:7,id:"e7"},{from:50,to:8,id:"e8"},{from:275,to:9,id:"e9"},{from:327,to:10,id:"e10"},{from:30,to:11,id:"e11"},{from:327,to:12,id:"e12"},{from:270,to:13,id:"e13"},{from:204,to:14,id:"e14"},{from:42,to:15,id:"e15"},{from:140,to:16,id:"e16"},{from:327,to:17,id:"e17"},{from:80,to:18,id:"e18"},{from:24,to:19,id:"e19"},{from:60,to:20,id:"e20"},{from:323,to:21,id:"e21"},{from:328,to:22,id:"e22"},{from:58,to:23,id:"e23"},{from:0,to:24,id:"e24"},{from:50,to:25,id:"e25"},{from:50,to:26,id:"e26"},{from:36,to:27,id:"e27"},{from:36,to:28,id:"e28"},{from:303,to:29,id:"e29"},{from:1,to:30,id:"e30"},{from:326,to:31,id:"e31"},{from:81,to:32,id:"e32"},{from:60,to:33,id:"e33"},{from:62,to:34,id:"e34"},{from:24,to:35,id:"e35"},{from:319,to:36,id:"e36"},{from:58,to:37,id:"e37"},{from:58,to:38,id:"e38"},{from:80,to:39,id:"e39"},{from:35,to:40,id:"e40"},{from:73,to:41,id:"e41"},{from:327,to:42,id:"e42"},{from:301,to:43,id:"e43"},{from:36,to:44,id:"e44"},{from:322,to:45,id:"e45"},{from:69,to:46,id:"e46"},{from:329,to:47,id:"e47"},{from:199,to:48,id:"e48"},{from:321,to:49,id:"e49"},{from:331,to:50,id:"e50"},{from:70,to:51,id:"e51"},{from:329,to:52,id:"e52"},{from:140,to:53,id:"e53"},{from:1,to:54,id:"e54"},{from:330,to:55,id:"e55"},{from:304,to:56,id:"e56"},{from:214,to:57,id:"e57"},{from:84,to:58,id:"e58"},{from:141,to:59,id:"e59"},{from:36,to:60,id:"e60"},{from:323,to:61,id:"e61"},{from:326,to:62,id:"e62"},{from:323,to:63,id:"e63"},{from:328,to:64,id:"e64"},{from:331,to:65,id:"e65"},{from:140,to:66,id:"e66"},{from:24,to:67,id:"e67"},{from:324,to:68,id:"e68"},{from:326,to:69,id:"e69"},{from:323,to:70,id:"e70"},{from:283,to:71,id:"e71"},{from:27,to:72,id:"e72"},{from:50,to:73,id:"e73"},{from:325,to:74,id:"e74"},{from:58,to:75,id:"e75"},{from:323,to:76,id:"e76"},{from:15,to:77,id:"e77"},{from:70,to:78,id:"e78"},{from:22,to:79,id:"e79"},{from:328,to:80,id:"e80"},{from:0,to:81,id:"e81"},{from:322,to:82,id:"e82"},{from:326,to:83,id:"e83"},{from:325,to:84,id:"e84"},{from:331,to:85,id:"e85"},{from:184,to:86,id:"e86"},{from:250,to:87,id:"e87"},{from:321,to:88,id:"e88"},{from:322,to:89,id:"e89"},{from:326,to:90,id:"e90"},{from:162,to:91,id:"e91"},{from:162,to:92,id:"e92"},{from:99,to:93,id:"e93"},{from:320,to:94,id:"e94"},{from:326,to:95,id:"e95"},{from:0,to:96,id:"e96"},{from:326,to:97,id:"e97"},{from:327,to:98,id:"e98"},{from:0,to:99,id:"e99"},{from:327,to:100,id:"e100"},{from:0,to:101,id:"e101"},{from:0,to:102,id:"e102"},{from:328,to:103,id:"e103"},{from:256,to:104,id:"e104"},{from:326,to:105,id:"e105"},{from:81,to:106,id:"e106"},{from:322,to:107,id:"e107"},{from:326,to:108,id:"e108"},{from:8,to:109,id:"e109"},{from:204,to:110,id:"e110"},{from:163,to:111,id:"e111"},{from:330,to:112,id:"e112"},{from:330,to:113,id:"e113"},{from:324,to:114,id:"e114"},{from:42,to:115,id:"e115"},{from:328,to:116,id:"e116"},{from:331,to:117,id:"e117"},{from:321,to:118,id:"e118"},{from:141,to:119,id:"e119"},{from:321,to:120,id:"e120"},{from:330,to:121,id:"e121"},{from:324,to:122,id:"e122"},{from:199,to:123,id:"e123"},{from:302,to:124,id:"e124"},{from:328,to:125,id:"e125"},{from:307,to:126,id:"e126"},{from:321,to:127,id:"e127"},{from:329,to:128,id:"e128"},{from:0,to:129,id:"e129"},{from:331,to:130,id:"e130"},{from:287,to:131,id:"e131"},{from:322,to:132,id:"e132"},{from:1,to:133,id:"e133"},{from:304,to:134,id:"e134"},{from:295,to:135,id:"e135"},{from:42,to:136,id:"e136"},{from:104,to:137,id:"e137"},{from:321,to:138,id:"e138"},{from:204,to:139,id:"e139"},{from:109,to:140,id:"e140"},{from:324,to:141,id:"e141"},{from:70,to:142,id:"e142"},{from:73,to:143,id:"e143"},{from:304,to:144,id:"e144"},{from:0,to:145,id:"e145"},{from:0,to:146,id:"e146"},{from:327,to:147,id:"e147"},{from:141,to:148,id:"e148"},{from:323,to:149,id:"e149"},{from:184,to:150,id:"e150"},{from:324,to:151,id:"e151"},{from:330,to:152,id:"e152"},{from:75,to:153,id:"e153"},{from:328,to:154,id:"e154"},{from:60,to:155,id:"e155"},{from:331,to:156,id:"e156"},{from:153,to:157,id:"e157"},{from:214,to:158,id:"e158"},{from:129,to:159,id:"e159"},{from:331,to:160,id:"e160"},{from:324,to:161,id:"e161"},{from:322,to:162,id:"e162"},{from:195,to:163,id:"e163"},{from:323,to:164,id:"e164"},{from:275,to:165,id:"e165"},{from:58,to:166,id:"e166"},{from:321,to:167,id:"e167"},{from:325,to:168,id:"e168"},{from:324,to:169,id:"e169"},{from:330,to:170,id:"e170"},{from:330,to:171,id:"e171"},{from:331,to:172,id:"e172"},{from:1,to:173,id:"e173"},{from:50,to:174,id:"e174"},{from:327,to:175,id:"e175"},{from:331,to:176,id:"e176"},{from:324,to:177,id:"e177"},{from:204,to:178,id:"e178"},{from:330,to:179,id:"e179"},{from:330,to:180,id:"e180"},{from:50,to:181,id:"e181"},{from:323,to:182,id:"e182"},{from:106,to:183,id:"e183"},{from:70,to:184,id:"e184"},{from:58,to:185,id:"e185"},{from:0,to:186,id:"e186"},{from:321,to:187,id:"e187"},{from:304,to:188,id:"e188"},{from:307,to:189,id:"e189"},{from:140,to:190,id:"e190"},{from:104,to:191,id:"e191"},{from:50,to:192,id:"e192"},{from:60,to:193,id:"e193"},{from:27,to:194,id:"e194"},{from:297,to:195,id:"e195"},{from:321,to:196,id:"e196"},{from:27,to:197,id:"e197"},{from:1,to:198,id:"e198"},{from:321,to:199,id:"e199"},{from:75,to:200,id:"e200"},{from:30,to:201,id:"e201"},{from:50,to:202,id:"e202"},{from:325,to:203,id:"e203"},{from:173,to:204,id:"e204"},{from:307,to:205,id:"e205"},{from:275,to:206,id:"e206"},{from:275,to:207,id:"e207"},{from:331,to:208,id:"e208"},{from:109,to:209,id:"e209"},{from:0,to:210,id:"e210"},{from:327,to:211,id:"e211"},{from:275,to:212,id:"e212"},{from:304,to:213,id:"e213"},{from:104,to:214,id:"e214"},{from:327,to:215,id:"e215"},{from:53,to:216,id:"e216"},{from:60,to:217,id:"e217"},{from:60,to:218,id:"e218"},{from:109,to:219,id:"e219"},{from:192,to:220,id:"e220"},{from:275,to:221,id:"e221"},{from:326,to:222,id:"e222"},{from:250,to:223,id:"e223"},{from:325,to:224,id:"e224"},{from:321,to:225,id:"e225"},{from:1,to:226,id:"e226"},{from:323,to:227,id:"e227"},{from:322,to:228,id:"e228"},{from:327,to:229,id:"e229"},{from:256,to:230,id:"e230"},{from:250,to:231,id:"e231"},{from:330,to:232,id:"e232"},{from:36,to:233,id:"e233"},{from:328,to:234,id:"e234"},{from:323,to:235,id:"e235"},{from:327,to:236,id:"e236"},{from:328,to:237,id:"e237"},{from:250,to:238,id:"e238"},{from:326,to:239,id:"e239"},{from:327,to:240,id:"e240"},{from:329,to:241,id:"e241"},{from:329,to:242,id:"e242"},{from:109,to:243,id:"e243"},{from:323,to:244,id:"e244"},{from:220,to:245,id:"e245"},{from:326,to:246,id:"e246"},{from:267,to:247,id:"e247"},{from:250,to:248,id:"e248"},{from:256,to:249,id:"e249"},{from:322,to:250,id:"e250"},{from:322,to:251,id:"e251"},{from:322,to:252,id:"e252"},{from:109,to:253,id:"e253"},{from:101,to:254,id:"e254"},{from:328,to:255,id:"e255"},{from:331,to:256,id:"e256"},{from:327,to:257,id:"e257"},{from:24,to:258,id:"e258"},{from:124,to:259,id:"e259"},{from:324,to:260,id:"e260"},{from:322,to:261,id:"e261"},{from:322,to:262,id:"e262"},{from:321,to:263,id:"e263"},{from:283,to:264,id:"e264"},{from:318,to:265,id:"e265"},{from:30,to:266,id:"e266"},{from:8,to:267,id:"e267"},{from:140,to:268,id:"e268"},{from:322,to:269,id:"e269"},{from:24,to:270,id:"e270"},{from:9,to:271,id:"e271"},{from:322,to:272,id:"e272"},{from:99,to:273,id:"e273"},{from:24,to:274,id:"e274"},{from:282,to:275,id:"e275"},{from:250,to:276,id:"e276"},{from:70,to:277,id:"e277"},{from:328,to:278,id:"e278"},{from:250,to:279,id:"e279"},{from:50,to:280,id:"e280"},{from:250,to:281,id:"e281"},{from:173,to:282,id:"e282"},{from:320,to:283,id:"e283"},{from:320,to:284,id:"e284"},{from:250,to:285,id:"e285"},{from:325,to:286,id:"e286"},{from:1,to:287,id:"e287"},{from:1,to:288,id:"e288"},{from:109,to:289,id:"e289"},{from:50,to:290,id:"e290"},{from:250,to:291,id:"e291"},{from:195,to:292,id:"e292"},{from:320,to:293,id:"e293"},{from:331,to:294,id:"e294"},{from:331,to:295,id:"e295"},{from:101,to:296,id:"e296"},{from:58,to:297,id:"e297"},{from:24,to:298,id:"e298"},{from:291,to:299,id:"e299"},{from:302,to:300,id:"e300"},{from:323,to:301,id:"e301"},{from:226,to:302,id:"e302"},{from:53,to:303,id:"e303"},{from:110,to:304,id:"e304"},{from:163,to:305,id:"e305"},{from:324,to:306,id:"e306"},{from:304,to:307,id:"e307"},{from:322,to:308,id:"e308"},{from:140,to:309,id:"e309"},{from:323,to:310,id:"e310"},{from:0,to:311,id:"e311"},{from:250,to:312,id:"e312"},{from:30,to:313,id:"e313"},{from:58,to:314,id:"e314"},{from:104,to:315,id:"e315"},{from:75,to:316,id:"e316"},{from:323,to:317,id:"e317"},{from:321,to:318,id:"e318"},{from:256,to:319,id:"e319"},{from:250,to:320,id:"e320"},{from:330,to:321,id:"e321"},{from:327,to:322,id:"e322"},{from:326,to:323,id:"e323"},{from:328,to:324,id:"e324"},{from:328,to:325,id:"e325"},{from:327,to:326,id:"e326"},{from:0,to:327,id:"e327"},{from:70,to:328,id:"e328"},{from:327,to:329,id:"e329"},{from:324,to:330,id:"e330"},{from:69,to:332,id:"e331"},{from:346,to:333,id:"e332"},{from:346,to:334,id:"e333"},{from:337,to:335,id:"e334"},{from:106,to:336,id:"e335"},{from:341,to:337,id:"e336"},{from:341,to:338,id:"e337"},{from:346,to:339,id:"e338"},{from:337,to:340,id:"e339"},{from:334,to:341,id:"e340"},{from:334,to:342,id:"e341"},{from:334,to:343,id:"e342"},{from:334,to:344,id:"e343"},{from:84,to:345,id:"e344"},{from:14,to:346,id:"e345"},{from:331,to:347,id:"e346"}]
\ No newline at end of file
diff --git a/lib/vis/examples/network/exampleApplications/lesMiserables.html b/lib/vis/examples/network/exampleApplications/lesMiserables.html
index 3ac0114ec..bf39a4629 100644
--- a/lib/vis/examples/network/exampleApplications/lesMiserables.html
+++ b/lib/vis/examples/network/exampleApplications/lesMiserables.html
@@ -376,7 +376,7 @@
maxVelocity: 146,
solver: 'forceAtlas2Based',
timestep: 0.35,
- stabilization: {iterations:300}
+ stabilization: {iterations: 150}
}
};
var network = new vis.Network(container, data, options);
diff --git a/lib/vis/examples/network/exampleUtil.js b/lib/vis/examples/network/exampleUtil.js
index a5554ced3..1621a9a50 100644
--- a/lib/vis/examples/network/exampleUtil.js
+++ b/lib/vis/examples/network/exampleUtil.js
@@ -66,5 +66,68 @@ function getScaleFreeNetwork(nodeCount) {
}
}
+ return {nodes:nodes, edges:edges};
+}
+
+var randomSeed = 764; // Math.round(Math.random()*1000);
+function seededRandom() {
+ var x = Math.sin(randomSeed++) * 10000;
+ return x - Math.floor(x);
+}
+
+function getScaleFreeNetworkSeeded(nodeCount, seed) {
+ if (seed) {
+ randomSeed = Number(seed);
+ }
+ var nodes = [];
+ var edges = [];
+ var connectionCount = [];
+ var edgesId = 0;
+
+
+ // randomly create some nodes and edges
+ for (var i = 0; i < nodeCount; i++) {
+ nodes.push({
+ id: i,
+ label: String(i)
+ });
+
+ connectionCount[i] = 0;
+
+ // create edges in a scale-free-network way
+ if (i == 1) {
+ var from = i;
+ var to = 0;
+ edges.push({
+ id: edgesId++,
+ from: from,
+ to: to
+ });
+ connectionCount[from]++;
+ connectionCount[to]++;
+ }
+ else if (i > 1) {
+ var conn = edges.length * 2;
+ var rand = Math.floor(seededRandom() * conn);
+ var cum = 0;
+ var j = 0;
+ while (j < connectionCount.length && cum < rand) {
+ cum += connectionCount[j];
+ j++;
+ }
+
+
+ var from = i;
+ var to = j;
+ edges.push({
+ id: edgesId++,
+ from: from,
+ to: to
+ });
+ connectionCount[from]++;
+ connectionCount[to]++;
+ }
+ }
+
return {nodes:nodes, edges:edges};
}
\ No newline at end of file
diff --git a/lib/vis/examples/network/layout/hierarchicalLayout.html b/lib/vis/examples/network/layout/hierarchicalLayout.html
index 4a2539a81..d827814c4 100644
--- a/lib/vis/examples/network/layout/hierarchicalLayout.html
+++ b/lib/vis/examples/network/layout/hierarchicalLayout.html
@@ -57,7 +57,7 @@
}
-
+
diff --git a/lib/vis/examples/network/layout/hierarchicalLayoutMethods.html b/lib/vis/examples/network/layout/hierarchicalLayoutMethods.html
index 93a16cf43..51f552670 100644
--- a/lib/vis/examples/network/layout/hierarchicalLayoutMethods.html
+++ b/lib/vis/examples/network/layout/hierarchicalLayoutMethods.html
@@ -19,7 +19,7 @@
-
+
-
-
+ // randomly create some nodes and edges
+ for (var i = 0; i < 15; i++) {
+ nodes.push({id: i, label: String(i)});
+ }
+ edges.push({from: 0, to: 1});
+ edges.push({from: 0, to: 6});
+ edges.push({from: 0, to: 13});
+ edges.push({from: 0, to: 11});
+ edges.push({from: 1, to: 2});
+ edges.push({from: 2, to: 3});
+ edges.push({from: 2, to: 4});
+ edges.push({from: 3, to: 5});
+ edges.push({from: 1, to: 10});
+ edges.push({from: 1, to: 7});
+ edges.push({from: 2, to: 8});
+ edges.push({from: 2, to: 9});
+ edges.push({from: 3, to: 14});
+ edges.push({from: 1, to: 12});
+ nodes[0]["level"] = 0;
+ nodes[1]["level"] = 1;
+ nodes[2]["level"] = 3;
+ nodes[3]["level"] = 4;
+ nodes[4]["level"] = 4;
+ nodes[5]["level"] = 5;
+ nodes[6]["level"] = 1;
+ nodes[7]["level"] = 2;
+ nodes[8]["level"] = 4;
+ nodes[9]["level"] = 4;
+ nodes[10]["level"] = 2;
+ nodes[11]["level"] = 1;
+ nodes[12]["level"] = 2;
+ nodes[13]["level"] = 1;
+ nodes[14]["level"] = 5;
+
+
+ // create a network
+ var container = document.getElementById('mynetwork');
+ var data = {
+ nodes: nodes,
+ edges: edges
+ };
+
+ var options = {
+ edges: {
+ smooth: {
+ type: 'cubicBezier',
+ forceDirection: (directionInput.value == "UD" || directionInput.value == "DU") ? 'vertical' : 'horizontal',
+ roundness: 0.4
+ }
+ },
+ layout: {
+ hierarchical: {
+ direction: directionInput.value
+ }
+ },
+ physics:false
+ };
+ network = new vis.Network(container, data, options);
+
+ // add event listeners
+ network.on('select', function (params) {
+ document.getElementById('selection').innerHTML = 'Selection: ' + params.nodes;
+ });
+ }
+
+
+
Hierarchical Layout - User-defined
+
- This example shows a user-defined hierarchical layout. If the user defines levels for nodes but does not do so for all nodes, an alert will show up and hierarchical layout will be disabled. Either all or none can be defined.
+ This example shows a user-defined hierarchical layout. If the user defines levels for nodes but does not do so for
+ all nodes, an alert will show up and hierarchical layout will be disabled. Either all or none can be defined.
If the smooth curves appear to be inverted, the direction of the edge is not in the same direction as the network.
-
-
-
-
-
+
+
+
+
+
@@ -123,22 +128,22 @@
+
+
+
+
+
+
Hierarchical Layout without Physics
+The hierarchical layout can now be controlled without the use of physics. This is much quicker. The options for this are:
+
+
+
+
levelSeparation
+
Distance between levels.
+
+
+
nodeSpacing
+
Minimum distance between nodes on the free axis.
+
+
+
treeSpacing
+
Distance between different trees (independent networks).
+
+
+
blockShifting
+
Method for reducing whitespace. Can be used alone or together with edge minimization. Each node will check for whitespace and will shift
+ it's branch along with it for as far as it can, respecting the nodeSpacing on any level.
+
+
+
edgeMinimization
+
Method for reducing whitespace. Can be used alone or together with block shifting. Enabling block shifting will usually speed up the layout process.
+ Each node will try to move along its free axis to reduce the total length of it's edges.
+
+
+
+Play with the settings below the network and see how the layout changes!
+
+
+
+