Browse Source

feat: change styles if element is selected (#2446)

* element characteristic changes
* assume edge color inheritance is correct before choosing
* Adjust nodes’ chosen’s boolean -> bool
* Need to get user-reset size
* make example edges thicker for more noticeable shadow
* preemptive ES6 fix (see #2500/#2501)
* documentation for the feature that was previously overwritten
readme-improvements
David Anderson 8 years ago
committed by Alexander Wunschik
parent
commit
becf18e6eb
32 changed files with 1238 additions and 432 deletions
  1. +97
    -1
      docs/network/edges.html
  2. +85
    -0
      docs/network/nodes.html
  3. +466
    -0
      examples/network/other/chosen.html
  4. +4
    -6
      lib/network/modules/CanvasRenderer.js
  5. +0
    -13
      lib/network/modules/EdgesHandler.js
  6. +166
    -59
      lib/network/modules/components/Edge.js
  7. +67
    -2
      lib/network/modules/components/Node.js
  8. +3
    -3
      lib/network/modules/components/edges/BezierEdgeDynamic.js
  9. +3
    -3
      lib/network/modules/components/edges/BezierEdgeStatic.js
  10. +3
    -3
      lib/network/modules/components/edges/CubicBezierEdge.js
  11. +3
    -3
      lib/network/modules/components/edges/StraightEdge.js
  12. +74
    -101
      lib/network/modules/components/edges/util/EdgeBase.js
  13. +18
    -22
      lib/network/modules/components/nodes/shapes/Box.js
  14. +11
    -11
      lib/network/modules/components/nodes/shapes/Circle.js
  15. +16
    -16
      lib/network/modules/components/nodes/shapes/CircularImage.js
  16. +16
    -18
      lib/network/modules/components/nodes/shapes/Database.js
  17. +5
    -5
      lib/network/modules/components/nodes/shapes/Diamond.js
  18. +5
    -5
      lib/network/modules/components/nodes/shapes/Dot.js
  19. +16
    -18
      lib/network/modules/components/nodes/shapes/Ellipse.js
  20. +11
    -12
      lib/network/modules/components/nodes/shapes/Icon.js
  21. +4
    -4
      lib/network/modules/components/nodes/shapes/Image.js
  22. +3
    -3
      lib/network/modules/components/nodes/shapes/Square.js
  23. +5
    -5
      lib/network/modules/components/nodes/shapes/Star.js
  24. +11
    -11
      lib/network/modules/components/nodes/shapes/Text.js
  25. +3
    -3
      lib/network/modules/components/nodes/shapes/Triangle.js
  26. +3
    -3
      lib/network/modules/components/nodes/shapes/TriangleDown.js
  27. +16
    -18
      lib/network/modules/components/nodes/util/CircleImageBase.js
  28. +15
    -13
      lib/network/modules/components/nodes/util/NodeBase.js
  29. +15
    -17
      lib/network/modules/components/nodes/util/ShapeBase.js
  30. +83
    -53
      lib/network/modules/components/shared/Label.js
  31. +10
    -0
      lib/network/options.js
  32. +1
    -1
      lib/util.js

+ 97
- 1
docs/network/edges.html View File

@ -120,6 +120,7 @@ var options = {
from: {enabled: false, scaleFactor:1, type:'arrow'}
},
arrowStrikethrough: true,
chosen: true,
color: {
color:'#848484',
highlight:'#848484',
@ -298,6 +299,101 @@ network.setOptions(options);
<td><code>true</code></td>
<td>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.</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','chosen', this);">
<td><span parent="chosen" class="right-caret"></span> chosen</td>
<td>Object or Boolean</td>
<td><code>true</code></td>
<td>
When true, selecting or hovering on an edge will change it and its label's characteristics according the default.
When false, no change to the edge or its label will occur when the edge is chosen.
If an object is supplied, finer-grained adjustment of edge and label characteristics is available when an edge is chosen.
</td>
</tr>
<tr parent="chosen" class="hidden">
<td class="indent">chosen.edge</td>
<td>Function or Boolean</td>
<td>undefined</td>
<td>
When true, selecting or hovering on an edge will change its characteristics according the default.
When false, no change to the edge will occur when the edge is chosen.
<p>
If a function is supplied, it is called when the edge is chosen.
<pre class="code">
function(values, id, selected, hovering) {
values.<i>property</i> = <i>chosenValue</i>;
}</pre>
</p>
<p>
Any of the incoming arguments may be used to determine characteristic changes.
If a property is not specifically assigned by the supplied function, it will be left unchanged.
A specific function may be assigned to each particular edge in its options, or to all in the network's <code>edges</code> options.
</p>
<p>
The properties define the characteristics that can be changed as follows:
</p>
<table>
<tr><th>Property</th><th>Edge Reference</th></tr>
<tr><td>dashes</td><td>see dashes</td></tr>
<tr><td>toArrow</td><td>see arrows.to.enabled</td></tr>
<tr><td>toArrowScale</td><td>see arrows.to.scaleFactor</td></tr>
<tr><td>toArrowType</td><td>see arrows.to.type</td></tr>
<tr><td>middleArrow</td><td>see arrows.middle.enabled</td></tr>
<tr><td>middleArrowScale</td><td>see arrows.middle.scaleFactor</td></tr>
<tr><td>middleArrowType</td><td>see arrows.middle.type</td></tr>
<tr><td>fromArrow</td><td>see arrows.from.enabled</td></tr>
<tr><td>fromArrowScale</td><td>see arrows.from.scaleFactor</td></tr>
<tr><td>fromArrowType</td><td>see arrows.from.type</td></tr>
<tr><td>arrowStrikethrough</td><td>see arrowStrikethrough</td></tr>
<tr><td>color</td><td>see color.color</td></tr>
<tr><td>inheritsColor</td><td>see color.inherit</td></tr>
<tr><td>opacity</td><td>see color.opacity</td></tr>
<tr><td>hidden</td><td>see hidden</td></tr>
<tr><td>length</td><td>see length</td></tr>
<tr><td>shadow</td><td>see shadow.enabled</td></tr>
<tr><td>shadowColor</td><td>see shadow.color</td></tr>
<tr><td>shadowSize</td><td>see shadow.size</td></tr>
<tr><td>shadowX</td><td>see shadow.x</td></tr>
<tr><td>shadowY</td><td>see shadow.y</td></tr>
<tr><td>width</td><td>see width</td></tr>
</table>
<br/>
</td>
</tr>
<tr parent="chosen" class="hidden">
<td class="indent">chosen.label</td>
<td>Function or Boolean</td>
<td>undefined</td>
<td>
When true, selecting or hovering on an edge will change its label's characteristics according the default.
When false, no change to the edge's label will occur when the edge is chosen.
<p>
If a function is supplied, it is called when the edge is chosen.
<pre class="code">
function(values, id, selected, hovering) {
values.<i>property</i> = <i>chosenValue</i>;
}</pre>
</p>
<p>
Any of the incoming arguments may be used to determine characteristic changes.
If a property is not specifically assigned by the supplied function, it will be left unchanged.
A specific function may be assigned to each particular edge in its options, or to all in the network's <code>edges</code> options.
</p>
<p>
The properties define the characteristics that can be changed as follows:
</p>
<table>
<tr><th>Property</th><th>Edge Reference</th></tr>
<tr><td>color</td><td>see font.color</td></tr>
<tr><td>size</td><td>see font.size</td></tr>
<tr><td>face</td><td>see font.face</td></tr>
<tr><td>mod</td><td>font modifier ('bold', 'italic', etc.)</td></tr>
<tr><td>vadjust</td><td>see font.vadjust</td></tr>
<tr><td>strokeWidth</td><td>see font.strokeWidth</td></tr>
<tr><td>strokeColor</td><td>see font.strokeColor</td></tr>
</table>
<br/>
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','color', this);">
<td><span parent="color" class="right-caret"></span> color</td>
<td>Object or String</td>
@ -311,7 +407,7 @@ network.setOptions(options);
<td class="indent">color.color</td>
<td>String</td>
<td><code>'#848484'</code></td>
<td>The color of the border of the node when it is not selected or hovered over <i>(assuming hover is
<td>The color of the edge when it is not selected or hovered over <i>(assuming hover is
enabled in the interaction module)</i>.
</td>
</tr>

+ 85
- 0
docs/network/nodes.html View File

@ -110,6 +110,7 @@ var options = {
borderWidth: 1,
borderWidthSelected: 2,
brokenImage:undefined,
chosen: true,
color: {
border: '#2B7CE9',
background: '#97C2FC',
@ -271,6 +272,90 @@ network.setOptions(options);
a backup image in case the URL supplied in the image option cannot be resolved.
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','chosen', this);">
<td><span parent="chosen" class="right-caret"></span> chosen</td>
<td>Object or Boolean</td>
<td><code>true</code></td>
<td>
When true, selecting or hovering on a node will change it and its label's characteristics according the default.
When false, no change to the node or its label will occur when the node is chosen.
If an object is supplied, finer-grained adjustment of node and label characteristics is available when a node is chosen.
</td>
</tr>
<tr parent="chosen" class="hidden">
<td class="indent">chosen.node</td>
<td>Function or Boolean</td>
<td>undefined</td>
<td>
When true, selecting or hovering on a node will change its characteristics according the default.
When false, no change to the node will occur when the node is chosen.
<p>
If a function is supplied, it is called when the node is chosen.
<pre class="code">
function(values, id, selected, hovering) {
values.<i>property</i> = <i>chosenValue</i>;
}</pre>
</p>
<p>
Any of the incoming arguments may be used to determine characteristic changes.
If a property is not specifically assigned by the supplied function, it will be left unchanged.
A specific function may be assigned to each particular node in its options, or to all in the network's <code>nodes</code> options.
</p>
<p>
The properties define the characteristics that can be changed as follows:
</p>
<table>
<tr><th>Property</th><th>Node Reference</th></tr>
<tr><td>color</td><td>see color.background</td></tr>
<tr><td>borderWidth</td><td>see borderWidth</td></tr>
<tr><td>borderColor</td><td>see color.border</td></tr>
<tr><td>size</td><td>see size</td></tr>
<tr><td>borderDashes</td><td>see shapeProperties.borderDashes</td></tr>
<tr><td>borderRadius</td><td>see shapeProperties.borderRadius</td></tr>
<tr><td>shadow</td><td>see shadow.enabled</td></tr>
<tr><td>shadowColor</td><td>see shadow.color</td></tr>
<tr><td>shadowSize</td><td>see shadow.size</td></tr>
<tr><td>shadowX</td><td>see shadow.x</td></tr>
<tr><td>shadowY</td><td>see shadow.y</td></tr>
</table>
<br/>
</td>
</tr>
<tr parent="chosen" class="hidden">
<td class="indent">chosen.label</td>
<td>Function or Boolean</td>
<td>undefined</td>
<td>
When true, selecting or hovering on a node will change its label's characteristics according the default.
When false, no change to the node's label will occur when the node is chosen.
<p>
If a function is supplied, it is called when the node is chosen.
<pre class="code">
function(values, id, selected, hovering) {
values.<i>property</i> = <i>chosenValue</i>;
}</pre>
</p>
<p>
Any of the incoming arguments may be used to determine characteristic changes.
If a property is not specifically assigned by the supplied function, it will be left unchanged.
A specific function may be assigned to each particular node in its options, or to all in the network's <code>nodes</code> options.
</p>
<p>
The properties define the characteristics that can be changed as follows:
</p>
<table>
<tr><th>Property</th><th>Node Reference</th></tr>
<tr><td>color</td><td>see font.color</td></tr>
<tr><td>size</td><td>see font.size</td></tr>
<tr><td>face</td><td>see font.face</td></tr>
<tr><td>mod</td><td>font modifier ('bold', 'italic', etc.)</td></tr>
<tr><td>vadjust</td><td>see font.vadjust</td></tr>
<tr><td>strokeWidth</td><td>see font.strokeWidth</td></tr>
<tr><td>strokeColor</td><td>see font.strokeColor</td></tr>
</table>
<br/>
</td>
</tr>
<tr class='toggle collapsible' onclick="toggleTable('optionTable','color', this);">
<td><span parent="color" class="right-caret"></span> color</td>
<td>Object or String</td>

+ 466
- 0
examples/network/other/chosen.html View File

@ -0,0 +1,466 @@
<!doctype html>
<html>
<head>
<title>Network | Chosen Elements</title>
<script type="text/javascript" src="../../../dist/vis.js"></script>
<link href="../../../dist/vis-network.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#mynetwork {
width: 900px;
height: 600px;
border: 1px solid lightgray;
}
code {
font-size: 14px;
background: #dddddd;
}
p {
max-width: 600px;
}
.indented {
margin-left: 30px;
}
.sep {
height: 1px;
width: 35%;
margin-left: 40px;
background-color: #dddddd;
}
</style>
<script src="../../googleAnalytics.js"></script>
</head>
<body>
<p>When a node or edge is selected or hovered its visible characteristics can be changed.</p>
<div id="mynetwork"></div>
<p>In this network, an element (node, edge or label) will change a characteristic when hovered, and it will be locked in when selected.
This is managed by setting up a 'chosen' function that will be called when the element containing the function is chosen.
These functions may be set on nodes, edges and labels, at the individual or group level.</p>
<p>All states (unselected, hover-over-unselected, selected, and hover-over selected) may be handled as needed by the application using vis, as the select and hover states are passed to the chosen function when called.
Additionally, the id of the element is passed to allow context-specific characteristic adjustment on select or hover as needed.</p>
<p><i>It should be noted that the characteristics which might affect the position of elements have been left out on purpose.
While it might be interesting to make them changeable, this is problematic on hovering.
Consider that the user hovers over an object.
If it changed characteristics that moved it outside of the hover-distance, it would then no longer be hovering.
So it would be moved back to its original prosition, within the hover-distance and then again be hovering over the object.
This hysteresis loop is kept from occurring by leaving out the characteristics that could cause it.
Some seemingly innocuous changes (such as resizing a node's label on hover that would in turn cause the node to resize and move out of hover-distance) may still cause hysteresis, but with care they should be avoidable.</i></p>
<script type="text/javascript">
var changeChosenLabelColor =
function(ctx, values, id) {
values.color = "#ff0000";
}
var changeChosenLabelSize =
function(ctx, values, id) {
values.size += 1;
}
var changeChosenLabelFace =
function(ctx, values, id) {
values.face = "serif";
}
var changeChosenLabelMod =
function(ctx, values, id) {
values.mod = "bold italic";
}
var changeChosenLabelStrokeWidth =
function(ctx, values, id) {
values.strokeWidth = 5;
}
var changeChosenLabelStrokeColor =
function(ctx, values, id) {
values.strokeColor = "#00ff00";
}
var changeChosenNodeColor =
function(values, id, selected, hovering) {
values.color = "#ffdd88";
}
var changeChosenNodeBorderWidth =
function(values, id, selected, hovering) {
values.borderWidth = 3;
}
var changeChosenNodeBorderColor =
function(values, id, selected, hovering) {
values.borderColor = "#ff0000";
}
var changeChosenNodeSize =
function(values, id, selected, hovering) {
values.size = 30;
}
var changeChosenNodeBorderDashes =
function(values, id, selected, hovering) {
values.borderDashes = [ 10, 10 ];
}
var changeChosenNodeBorderRadius =
function(values, id, selected, hovering) {
values.borderRadius = 15;
}
var changeChosenNodeShadow =
function(values, id, selected, hovering) {
values.shadow = true;
}
var changeChosenNodeShadowColor =
function(values, id, selected, hovering) {
values.shadowColor = "#ff0000";
}
var changeChosenNodeShadowSize =
function(values, id, selected, hovering) {
values.shadowSize = 30;
}
var changeChosenNodeShadowX =
function(values, id, selected, hovering) {
values.shadowX = -5;
}
var changeChosenNodeShadowY =
function(values, id, selected, hovering) {
values.shadowY = -5;
}
var changeChosenEdgeToArrow =
function(values, id, selected, hovering) {
values.toArrow = true;
}
var changeChosenEdgeToArrowScale =
function(values, id, selected, hovering) {
values.toArrowScale = 2;
}
var changeChosenEdgeToArrowType =
function(values, id, selected, hovering) {
values.toArrowType = "circle";
}
var changeChosenEdgeMiddleArrow =
function(values, id, selected, hovering) {
values.middleArrow = true;
}
var changeChosenEdgeMiddleArrowScale =
function(values, id, selected, hovering) {
values.middleArrowScale = 2;
}
var changeChosenEdgeMiddleArrowType =
function(values, id, selected, hovering) {
values.middleArrowType = "circle";
}
var changeChosenEdgeFromArrow =
function(values, id, selected, hovering) {
values.fromArrow = true;
}
var changeChosenEdgeFromArrowScale =
function(values, id, selected, hovering) {
values.fromArrowScale = 2;
}
var changeChosenEdgeFromArrowType =
function(values, id, selected, hovering) {
values.fromArrowType = "circle";
}
var changeChosenEdgeArrowStrikethrough =
function(values, id, selected, hovering) {
values.arrowStrikethrough = false;
}
var changeChosenEdgeColor =
function(values, id, selected, hovering) {
values.color = "#00ff00";
}
var changeChosenEdgeInheritsColor =
function(values, id, selected, hovering) {
values.inheritsColor = "both";
}
var changeChosenEdgeOpacity =
function(values, id, selected, hovering) {
values.opacity = 0.25;
}
var changeChosenEdgeHidden =
function(values, id, selected, hovering) {
values.hidden = true;
}
var changeChosenEdgeShadow =
function(values, id, selected, hovering) {
values.shadow = true;
}
var changeChosenEdgeShadowColor =
function(values, id, selected, hovering) {
values.shadowColor = "#00ffff";
}
var changeChosenEdgeShadowSize =
function(values, id, selected, hovering) {
values.shadowSize = 20;
}
var changeChosenEdgeShadowX =
function(values, id, selected, hovering) {
values.shadowX = -5;
}
var changeChosenEdgeShadowY =
function(values, id, selected, hovering) {
values.shadowY = -5;
}
var changeChosenEdgeWidth =
function(values, id, selected, hovering) {
values.width = 5;
}
var changeChosenEdgeDashes =
function(values, id, selected, hovering) {
values.dashes = [10, 10];
}
var nodes = [
{ id: 1000, label: "label does not change",
x: -400, y: -300,
chosen: { label: false, node: false } },
{ id: 1010, label: "label default settings",
x: -400, y: -225,
chosen: { label: true, node: false } },
{ id: 1020, label: "label changes color",
x: -400, y: -150,
chosen: { label: changeChosenLabelColor, node: false } },
{ id: 1030, label: "label changes size",
x: -400, y: -75,
chosen: { label: changeChosenLabelSize, node: false } },
{ id: 1040, label: "label changes face",
x: -400, y: 0,
chosen: { label: changeChosenLabelFace, node: false } },
{ id: 1050, label: "label changes modifier",
x: -400, y: 75,
chosen: { label: changeChosenLabelMod, node: false } },
{ id: 1060, label: "label changes stokeWidth",
x: -400, y: 150,
chosen: { label: changeChosenLabelStrokeWidth, node: false } },
{ id: 1070, label: "label changes stokeColor",
x: -400, y: 225, font: { strokeWidth: 2 },
chosen: { label: changeChosenLabelStrokeColor, node: false } },
{ id: 2000, label: "node does not change",
x: 0, y: -300,
chosen: { label: false, node: false } },
{ id: 2010, label: "node default settings",
x: 0, y: -225,
chosen: { label: false, node: true } },
{ id: 2020, label: "node changes color",
x: 0, y: -150,
chosen: { label: false, node: changeChosenNodeColor } },
{ id: 2030, label: "node changes borderWidth",
x: 0, y: -75,
chosen: { label: false, node: changeChosenNodeBorderWidth } },
{ id: 2040, label: "node changes borderColor",
x: 0, y: 0,
chosen: { label: false, node: changeChosenNodeBorderColor } },
{ id: 2050, label: "shaped nodes change size",
x: 0, y: 70, shape: 'star',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2051, x: -60, y: 70, shape: 'dot',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2052, x: -120, y: 70, shape: 'diamond',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2053, x: 60, y: 70, shape: 'square',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2054, x: 120, y: 70, shape: 'triangle',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2055, x: 165, y: 70, shape: 'triangleDown',
chosen: { label: false, node: changeChosenNodeSize } },
{ id: 2060, label: "node changes borderDashes",
x: 0, y: 150,
chosen: { label: false, node: changeChosenNodeBorderDashes } },
{ id: 2070, label: "node changes borderRadius",
x: 0, y: 225,
chosen: { label: false, node: changeChosenNodeBorderRadius } },
{ id: 2080, label: "node changes shadow",
x: 0, y: 300,
chosen: { label: false, node: changeChosenNodeShadow } },
{ id: 2090, label: "node changes shadowColor",
x: 0, y: 375, shadow: true,
chosen: { label: false, node: changeChosenNodeShadowColor } },
{ id: 2100, label: "node changes shadowSize",
x: 0, y: 450, shadow: true,
chosen: { label: false, node: changeChosenNodeShadowSize } },
{ id: 2110, label: "node changes shadowX",
x: 0, y: 525, shadow: true,
chosen: { label: false, node: changeChosenNodeShadowX } },
{ id: 2120, label: "node changes shadowY",
x: 0, y: 600, shadow: true,
chosen: { label: false, node: changeChosenNodeShadowY } },
{ id: 3000, x: 275, y: -310, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3001, x: 525, y: -210, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3010, x: 275, y: -235, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3011, x: 525, y: -135, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3020, x: 275, y: -160, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3021, x: 525, y: -60, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3030, x: 275, y: -85, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3031, x: 525, y: 15, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3040, x: 275, y: -10, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3041, x: 525, y: 90, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3050, x: 275, y: 65, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3051, x: 525, y: 165, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3060, x: 275, y: 140, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3061, x: 525, y: 240, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3070, x: 275, y: 215, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3071, x: 525, y: 315, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3080, x: 275, y: 290, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0},
{ id: 3081, x: 525, y: 390, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3090, x: 275, y: 365, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3091, x: 525, y: 465, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3100, x: 275, y: 440, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3101, x: 525, y: 540, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3110, x: 275, y: 515, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3111, x: 525, y: 615, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3120, x: 575, y: -310, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3121, x: 825, y: -210, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3130, x: 575, y: -235, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3131, x: 825, y: -135, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3140, x: 575, y: -160, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3141, x: 825, y: -60, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3150, x: 575, y: -85, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3151, x: 825, y: 15, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3160, x: 575, y: -10, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3161, x: 825, y: 90, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3170, x: 575, y: 65, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3171, x: 825, y: 165, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3180, x: 575, y: 140, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3181, x: 825, y: 240, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3190, x: 575, y: 215, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3191, x: 825, y: 315, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3200, x: 575, y: 290, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3201, x: 825, y: 390, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3210, x: 575, y: 365, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3211, x: 825, y: 465, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
{ id: 3220, x: 575, y: 440, chosen: false, shape: "dot", size: 10, color: "#dd6644", borderWidth: 0 },
{ id: 3221, x: 825, y: 540, chosen: false, shape: "dot", size: 10, color: "#6699dd", borderWidth: 0 },
];
var edges = [
{ id: 4000, from: 3000, to: 3001, label: "edge does not change",
chosen: false },
{ id: 4010, from: 3010, to: 3011, label: "edge has default settings",
chosen: { label: false, edge: true } },
{ id: 4020, from: 3020, to: 3021, label: "edge changes toArrow",
chosen: { label: false, edge: changeChosenEdgeToArrow } },
{ id: 4030, from: 3030, to: 3031, label: "edge changes toArrowScale",
arrows: { to: true },
chosen: { label: false, edge: changeChosenEdgeToArrowScale } },
{ id: 4040, from: 3040, to: 3041, label: "edge changes toArrowType",
arrows: { to: true },
chosen: { label: false, edge: changeChosenEdgeToArrowType } },
{ id: 4050, from: 3050, to: 3051, label: "edge changes middleArrow",
chosen: { label: false, edge: changeChosenEdgeMiddleArrow } },
{ id: 4060, from: 3060, to: 3061, label: "edge changes middleArrowScale",
arrows: { middle: true },
chosen: { label: false, edge: changeChosenEdgeMiddleArrowScale } },
{ id: 4070, from: 3070, to: 3071, label: "edge changes middleArrowType",
arrows: { middle: true },
chosen: { label: false, edge: changeChosenEdgeMiddleArrowType } },
{ id: 4080, from: 3080, to: 3081, label: "edge changes fromArrow",
chosen: { label: false, edge: changeChosenEdgeFromArrow } },
{ id: 4090, from: 3090, to: 3091, label: "edge changes fromArrowScale",
arrows: { from: true },
chosen: { label: false, edge: changeChosenEdgeFromArrowScale } },
{ id: 4100, from: 3100, to: 3101, label: "edge changes fromArrowType",
arrows: { from: true },
chosen: { label: false, edge: changeChosenEdgeFromArrowType } },
{ id: 4110, from: 3110, to: 3111, label: "edge changes arrowStrikethrough",
arrows: { to: true, from: true }, width: 7,
chosen: { label: false, edge: changeChosenEdgeArrowStrikethrough } },
{ id: 4120, from: 3120, to: 3121, label: "edge changes color",
chosen: { label: false, edge: changeChosenEdgeColor } },
{ id: 4130, from: 3130, to: 3131, label: "edge inherits color",
chosen: { label: false, edge: changeChosenEdgeInheritsColor } },
{ id: 4140, from: 3140, to: 3141, label: "edge changes opacity",
chosen: { label: false, edge: changeChosenEdgeOpacity } },
{ id: 4150, from: 3150, to: 3151, label: "edge changes hidden",
chosen: { label: false, edge: changeChosenEdgeHidden } },
{ id: 4160, from: 3160, to: 3161, label: "edge changes shadow",
width: 7,
chosen: { label: false, edge: changeChosenEdgeShadow } },
{ id: 4170, from: 3170, to: 3171, label: "edge changes shadowColor",
shadow: true, width: 7,
chosen: { label: false, edge: changeChosenEdgeShadowColor } },
{ id: 4180, from: 3180, to: 3181, label: "edge changes shadowSize",
shadow: true, width: 7,
chosen: { label: false, edge: changeChosenEdgeShadowSize } },
{ id: 4190, from: 3190, to: 3191, label: "edge changes shadowX",
shadow: true, width: 7,
chosen: { label: false, edge: changeChosenEdgeShadowX } },
{ id: 4200, from: 3200, to: 3201, label: "edge changes shadowY",
shadow: true, width: 7,
chosen: { label: false, edge: changeChosenEdgeShadowY } },
{ id: 4210, from: 3210, to: 3211, label: "edge changes width",
chosen: { label: false, edge: changeChosenEdgeWidth } },
{ id: 4220, from: 3220, to: 3221, label: "edge changes dashes",
chosen: { label: false, edge: changeChosenEdgeDashes } },
];
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
edges: {
font: {
size: 16
},
selfReferenceSize: 30
},
nodes: {
shape: 'box',
widthConstraint: 250,
color: "#cccccc",
margin: 10,
font: {
size: 16
}
},
physics: {
enabled: false
},
interaction: {
hover: true
}
};
var network = new vis.Network(container, data, options);
</script>
</body>
</html>

+ 4
- 6
lib/network/modules/CanvasRenderer.js View File

@ -32,11 +32,9 @@ class CanvasRenderer {
}
bindEventListeners() {
this.body.emitter.on("dragStart", () => {
this.dragging = true;
});
this.body.emitter.on("dragEnd", () => this.dragging = false);
this.body.emitter.on("_resizeNodes", () => this._resizeNodes());
this.body.emitter.on("dragStart", () => { this.dragging = true; });
this.body.emitter.on("dragEnd", () => { this.dragging = false; });
this.body.emitter.on("_resizeNodes", () => { this._resizeNodes(); });
this.body.emitter.on("_redraw", () => {
if (this.renderingActive === false) {
this._redraw();
@ -327,4 +325,4 @@ class CanvasRenderer {
}
export default CanvasRenderer;
export default CanvasRenderer;

+ 0
- 13
lib/network/modules/EdgesHandler.js View File

@ -151,7 +151,6 @@ class EdgesHandler {
// this is called when options of EXISTING nodes or edges have changed.
this.body.emitter.on("_dataUpdated", () => {
this.reconnectEdges();
this.markAllEdgesAsDirty();
});
// refresh the edges. Used when reverting from hierarchical layout
@ -177,11 +176,6 @@ class EdgesHandler {
// use the parser from the Edge class to fill in all shorthand notations
Edge.parseOptions(this.options, options);
// handle multiple input cases for color
if (options.color !== undefined) {
this.markAllEdgesAsDirty();
}
// update smooth settings in all edges
let dataChanged = false;
if (options.smooth !== undefined) {
@ -361,13 +355,6 @@ class EdgesHandler {
return new Edge(properties, this.body, this.options, this.defaultOptions, this.edgeOptions)
}
markAllEdgesAsDirty() {
for (var edgeId in this.body.edges) {
this.body.edges[edgeId].edgeType.colorDirty = true;
}
}
/**
* Reconnect all edges
* @private

+ 166
- 59
lib/network/modules/components/Edge.js View File

@ -39,7 +39,6 @@ class Edge {
this.selected = false;
this.hover = false;
this.labelDirty = true;
this.colorDirty = true;
this.baseWidth = this.options.width;
this.baseFontSize = this.options.font.size;
@ -65,16 +64,26 @@ class Edge {
if (!options) {
return;
}
this.colorDirty = true;
Edge.parseOptions(this.options, options, true, this.globalOptions);
if (options.id !== undefined) {this.id = options.id;}
if (options.from !== undefined) {this.fromId = options.from;}
if (options.to !== undefined) {this.toId = options.to;}
if (options.title !== undefined) {this.title = options.title;}
if (options.value !== undefined) {options.value = parseFloat(options.value);}
if (options.id !== undefined) {
this.id = options.id;
}
if (options.from !== undefined) {
this.fromId = options.from;
}
if (options.to !== undefined) {
this.toId = options.to;
}
if (options.title !== undefined) {
this.title = options.title;
}
if (options.value !== undefined) {
options.value = parseFloat(options.value);
}
this.choosify(options);
// update label Module
this.updateLabelModule(options);
@ -197,6 +206,94 @@ class Edge {
}
}
choosify(options) {
this.chooser = true;
let pile = [options, this.options, this.defaultOptions];
let chosen = util.topMost(pile, 'chosen');
if (typeof chosen === 'boolean') {
this.chooser = chosen;
} else if (typeof chosen === 'object') {
let chosenEdge = util.topMost(pile, ['chosen', 'edge']);
if ((typeof chosenEdge === 'boolean') || (typeof chosenEdge === 'function')) {
this.chooser = chosenEdge;
}
}
}
getFormattingValues() {
let toArrow = (this.options.arrows.to === true) || (this.options.arrows.to.enabled === true)
let fromArrow = (this.options.arrows.from === true) || (this.options.arrows.from.enabled === true)
let middleArrow = (this.options.arrows.middle === true) || (this.options.arrows.middle.enabled === true)
let inheritsColor = this.options.color.inherit;
let values = {
toArrow: toArrow,
toArrowScale: this.options.arrows.to.scaleFactor,
toArrowType: this.options.arrows.to.type,
middleArrow: middleArrow,
middleArrowScale: this.options.arrows.middle.scaleFactor,
middleArrowType: this.options.arrows.middle.type,
fromArrow: fromArrow,
fromArrowScale: this.options.arrows.from.scaleFactor,
fromArrowType: this.options.arrows.from.type,
arrowStrikethrough: this.options.arrowStrikethrough,
color: (inheritsColor? undefined : this.options.color.color),
inheritsColor: inheritsColor,
opacity: this.options.color.opacity,
hidden: this.options.hidden,
length: this.options.length,
shadow: this.options.shadow.enabled,
shadowColor: this.options.shadow.color,
shadowSize: this.options.shadow.size,
shadowX: this.options.shadow.x,
shadowY: this.options.shadow.y,
dashes: this.options.dashes,
width: this.options.width
};
if (this.selected || this.hover) {
if (this.chooser === true) {
if (this.selected) {
let selectedWidth = this.options.selectionWidth;
if (typeof selectedWidth === 'function') {
values.width = selectedWidth(values.width);
} else if (typeof selectedWidth === 'number') {
values.width += selectedWidth;
}
values.width = Math.max(values.width, 0.3 / this.body.view.scale);
values.color = this.options.color.highlight;
values.shadow = this.options.shadow.enabled;
} else if (this.hover) {
let hoverWidth = this.options.hoverWidth;
if (typeof hoverWidth === 'function') {
values.width = hoverWidth(values.width);
} else if (typeof hoverWidth === 'number') {
values.width += hoverWidth;
}
values.width = Math.max(values.width, 0.3 / this.body.view.scale);
values.color = this.options.color.hover;
values.shadow = this.options.shadow.enabled;
}
} else if (typeof this.chooser === 'function') {
this.chooser(values, this.options.id, this.selected, this.hover);
if (values.color !== undefined) {
values.inheritsColor = false;
}
if (values.shadow === false) {
if ((values.shadowColor !== this.options.shadow.color) ||
(values.shadowSize !== this.options.shadow.size) ||
(values.shadowX !== this.options.shadow.x) ||
(values.shadowY !== this.options.shadow.y)) {
values.shadow = true;
}
}
}
} else {
values.shadow = this.options.shadow.enabled;
values.width = Math.max(values.width, 0.3 / this.body.view.scale);
}
return values;
}
/**
* update the options in the label module
@ -207,6 +304,7 @@ class Edge {
this.baseFontSize = this.labelModule.baseSize;
}
this.labelModule.constrain(this.edgeOptions, options, this.defaultOptions);
this.labelModule.choosify(this.edgeOptions, options, this.defaultOptions);
}
/**
@ -214,46 +312,47 @@ class Edge {
* @returns {boolean}
*/
updateEdgeType() {
let smooth = this.options.smooth;
let dataChanged = false;
let changeInType = true;
let smooth = this.options.smooth;
if (this.edgeType !== undefined) {
if (this.edgeType instanceof BezierEdgeDynamic && smooth.enabled === true && smooth.type === 'dynamic') {changeInType = false;}
if (this.edgeType instanceof CubicBezierEdge && smooth.enabled === true && smooth.type === 'cubicBezier') {changeInType = false;}
if (this.edgeType instanceof BezierEdgeStatic && smooth.enabled === true && smooth.type !== 'dynamic' && smooth.type !== 'cubicBezier') {changeInType = false;}
if (this.edgeType instanceof StraightEdge && smooth.enabled === false) {changeInType = false;}
if ((((this.edgeType instanceof BezierEdgeDynamic) &&
(smooth.enabled === true) &&
(smooth.type === 'dynamic'))) ||
(((this.edgeType instanceof CubicBezierEdge) &&
(smooth.enabled === true) &&
(smooth.type === 'cubicBezier'))) ||
(((this.edgeType instanceof BezierEdgeStatic) &&
(smooth.enabled === true) &&
(smooth.type !== 'dynamic') &&
(smooth.type !== 'cubicBezier'))) ||
(((this.edgeType instanceof StraightEdge) &&
(smooth.type.enabled === false)))) {
changeInType = false;
}
if (changeInType === true) {
dataChanged = this.cleanup();
}
}
if (changeInType === true) {
if (this.options.smooth.enabled === true) {
if (this.options.smooth.type === 'dynamic') {
if (smooth.enabled === true) {
if (smooth.type === 'dynamic') {
dataChanged = true;
this.edgeType = new BezierEdgeDynamic(this.options, this.body, this.labelModule);
}
else if (this.options.smooth.type === 'cubicBezier') {
} else if (smooth.type === 'cubicBezier') {
this.edgeType = new CubicBezierEdge(this.options, this.body, this.labelModule);
}
else {
} else {
this.edgeType = new BezierEdgeStatic(this.options, this.body, this.labelModule);
}
}
else {
} else {
this.edgeType = new StraightEdge(this.options, this.body, this.labelModule);
}
}
else {
// if nothing changes, we just set the options.
} else { // if nothing changes, we just set the options.
this.edgeType.setOptions(this.options);
}
return dataChanged;
}
/**
* Connect an edge to its nodes
*/
@ -353,21 +452,18 @@ class Edge {
this.updateLabelModule();
}
_setInteractionWidths() {
if (typeof this.options.hoverWidth === 'function') {
this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width);
}
else {
this.edgeType.hoverWidth = this.options.hoverWidth + this.options.width;
}
if (typeof this.options.selectionWidth === 'function') {
this.edgeType.selectionWidth = this.options.selectionWidth(this.options.width);
}
else {
this.edgeType.selectionWidth = this.options.selectionWidth + this.options.width;
}
}
_setInteractionWidths() {
if (typeof this.options.hoverWidth === 'function') {
this.edgeType.hoverWidth = this.options.hoverWidth(this.options.width);
} else {
this.edgeType.hoverWidth = this.options.hoverWidth + this.options.width;
}
if (typeof this.options.selectionWidth === 'function') {
this.edgeType.selectionWidth = this.options.selectionWidth(this.options.width);
} else {
this.edgeType.selectionWidth = this.options.selectionWidth + this.options.width;
}
}
/**
@ -377,6 +473,11 @@ class Edge {
* @param {CanvasRenderingContext2D} ctx
*/
draw(ctx) {
let values = this.getFormattingValues();
if (values.hidden) {
return;
}
// get the via node from the edge type
let viaNode = this.edgeType.getViaNode();
let arrowData = {};
@ -386,33 +487,39 @@ class Edge {
this.edgeType.toPoint = this.edgeType.to;
// from and to arrows give a different end point for edges. we set them here
if (this.options.arrows.from.enabled === true) {
arrowData.from = this.edgeType.getArrowData(ctx,'from', viaNode, this.selected, this.hover);
if (this.options.arrowStrikethrough === false)
if (values.fromArrow) {
arrowData.from = this.edgeType.getArrowData(ctx, 'from', viaNode, this.selected, this.hover, values);
if (values.arrowStrikethrough === false)
this.edgeType.fromPoint = arrowData.from.core;
}
if (this.options.arrows.to.enabled === true) {
arrowData.to = this.edgeType.getArrowData(ctx,'to', viaNode, this.selected, this.hover);
if (this.options.arrowStrikethrough === false)
if (values.toArrow) {
arrowData.to = this.edgeType.getArrowData(ctx, 'to', viaNode, this.selected, this.hover, values);
if (values.arrowStrikethrough === false)
this.edgeType.toPoint = arrowData.to.core;
}
// the middle arrow depends on the line, which can depend on the to and from arrows so we do this one lastly.
if (this.options.arrows.middle.enabled === true) {
arrowData.middle = this.edgeType.getArrowData(ctx,'middle', viaNode, this.selected, this.hover);
if (values.middleArrow) {
arrowData.middle = this.edgeType.getArrowData(ctx,'middle', viaNode, this.selected, this.hover, values);
}
// draw everything
this.edgeType.drawLine(ctx, this.selected, this.hover, viaNode);
this.drawArrows(ctx, arrowData);
this.edgeType.drawLine(ctx, values, this.selected, this.hover, viaNode);
this.drawArrows(ctx, arrowData, values);
this.drawLabel (ctx, viaNode);
}
drawArrows(ctx, arrowData) {
if (this.options.arrows.from.enabled === true) {this.edgeType.drawArrowHead(ctx, this.selected, this.hover, arrowData.from);}
if (this.options.arrows.middle.enabled === true) {this.edgeType.drawArrowHead(ctx, this.selected, this.hover, arrowData.middle);}
if (this.options.arrows.to.enabled === true) {this.edgeType.drawArrowHead(ctx, this.selected, this.hover, arrowData.to);}
drawArrows(ctx, arrowData, values) {
if (values.fromArrow) {
this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.from);
}
if (values.middleArrow) {
this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.middle);
}
if (values.toArrow) {
this.edgeType.drawArrowHead(ctx, values, this.selected, this.hover, arrowData.to);
}
}
@ -429,13 +536,13 @@ class Edge {
// if the label has to be rotated:
if (this.options.font.align !== "horizontal") {
this.labelModule.calculateLabelSize(ctx,selected,point.x,point.y);
this.labelModule.calculateLabelSize(ctx, selected, this.hover, point.x, point.y);
ctx.translate(point.x, this.labelModule.size.yLine);
this._rotateForLabelAlignment(ctx);
}
// draw the label
this.labelModule.draw(ctx, point.x, point.y, selected);
this.labelModule.draw(ctx, point.x, point.y, selected, this.hover);
ctx.restore();
}
else {
@ -452,7 +559,7 @@ class Edge {
y = node1.y - node1.shape.height * 0.5;
}
point = this._pointOnCircle(x, y, radius, 0.125);
this.labelModule.draw(ctx, point.x, point.y, selected);
this.labelModule.draw(ctx, point.x, point.y, selected, this.hover);
}
}
}

+ 67
- 2
lib/network/modules/components/Node.js View File

@ -139,6 +139,8 @@ class Node {
// this transforms all shorthands into fully defined options
Node.parseOptions(this.options, options, true, this.globalOptions);
this.choosify(options);
// load the images
if (this.options.image !== undefined) {
if (this.imagelist) {
@ -219,6 +221,66 @@ class Node {
}
}
choosify(options) {
this.chooser = true;
let pile = [options, this.options, this.defaultOptions];
let chosen = util.topMost(pile, 'chosen');
if (typeof chosen === 'boolean') {
this.chooser = chosen;
} else if (typeof chosen === 'object') {
let chosenNode = util.topMost(pile, ['chosen', 'node']);
if ((typeof chosenNode === 'boolean') || (typeof chosenNode === 'function')) {
this.chooser = chosenNode;
}
}
}
getFormattingValues() {
let values = {
color: this.options.color.background,
borderWidth: this.options.borderWidth,
borderColor: this.options.color.border,
size: this.options.size,
borderDashes: this.options.shapeProperties.borderDashes,
borderRadius: this.options.shapeProperties.borderRadius,
shadow: this.options.shadow.enabled,
shadowColor: this.options.shadow.color,
shadowSize: this.options.shadow.size,
shadowX: this.options.shadow.x,
shadowY: this.options.shadow.y
};
if (this.selected || this.hover) {
if (this.chooser === true) {
if (this.selected) {
values.borderWidth *= 2;
values.color = this.options.color.highlight.background;
values.borderColor = this.options.color.highlight.border;
values.shadow = this.options.shadow.enabled;
} else if (this.hover) {
values.color = this.options.color.hover.background;
values.borderColor = this.options.color.hover.border;
values.shadow = this.options.shadow.enabled;
}
} else if (typeof this.chooser === 'function') {
this.chooser(values, this.options.id, this.selected, this.hover);
if (values.shadow === false) {
if ((values.shadowColor !== this.options.shadow.color) ||
(values.shadowSize !== this.options.shadow.size) ||
(values.shadowX !== this.options.shadow.x) ||
(values.shadowY !== this.options.shadow.y)) {
values.shadow = true;
}
}
}
} else {
values.shadow = this.options.shadow.enabled;
}
return values;
}
updateLabelModule(options) {
if (this.options.label === undefined || this.options.label === null) {
this.options.label = '';
@ -228,6 +290,7 @@ class Node {
this.baseFontSize = this.labelModule.baseSize;
}
this.labelModule.constrain(this.nodeOptions, options, this.defaultOptions);
this.labelModule.choosify(this.nodeOptions, options, this.defaultOptions);
}
updateShape(currentShape) {
@ -396,7 +459,8 @@ class Node {
* @param {CanvasRenderingContext2D} ctx
*/
draw(ctx) {
this.shape.draw(ctx, this.x, this.y, this.selected, this.hover);
let values = this.getFormattingValues();
this.shape.draw(ctx, this.x, this.y, this.selected, this.hover, values);
}
@ -413,7 +477,8 @@ class Node {
* @param {CanvasRenderingContext2D} ctx
*/
resize(ctx) {
this.shape.resize(ctx, this.selected);
let values = this.getFormattingValues();
this.shape.resize(ctx, this.selected, this.hover, values);
}

+ 3
- 3
lib/network/modules/components/edges/BezierEdgeDynamic.js View File

@ -102,7 +102,7 @@ class BezierEdgeDynamic extends BezierEdgeBase {
* @param {CanvasRenderingContext2D} ctx
* @private
*/
_line(ctx, viaNode) {
_line(ctx, values, viaNode) {
// draw a straight line
ctx.beginPath();
ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
@ -114,9 +114,9 @@ class BezierEdgeDynamic extends BezierEdgeBase {
ctx.quadraticCurveTo(viaNode.x, viaNode.y, this.toPoint.x, this.toPoint.y);
}
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
ctx.stroke();
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}
getViaNode() {

+ 3
- 3
lib/network/modules/components/edges/BezierEdgeStatic.js View File

@ -10,7 +10,7 @@ class BezierEdgeStatic extends BezierEdgeBase {
* @param {CanvasRenderingContext2D} ctx
* @private
*/
_line(ctx, viaNode) {
_line(ctx, values, viaNode) {
// draw a straight line
ctx.beginPath();
ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
@ -23,9 +23,9 @@ class BezierEdgeStatic extends BezierEdgeBase {
ctx.quadraticCurveTo(viaNode.x, viaNode.y, this.toPoint.x, this.toPoint.y);
}
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
ctx.stroke();
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}
getViaNode() {

+ 3
- 3
lib/network/modules/components/edges/CubicBezierEdge.js View File

@ -10,7 +10,7 @@ class CubicBezierEdge extends CubicBezierEdgeBase {
* @param {CanvasRenderingContext2D} ctx
* @private
*/
_line(ctx, viaNodes) {
_line(ctx, values, viaNodes) {
// get the coordinates of the support points.
let via1 = viaNodes[0];
let via2 = viaNodes[1];
@ -27,9 +27,9 @@ class CubicBezierEdge extends CubicBezierEdgeBase {
ctx.bezierCurveTo(via1.x, via1.y, via2.x, via2.y, this.toPoint.x, this.toPoint.y);
}
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
ctx.stroke();
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}
_getViaCoordinates() {

+ 3
- 3
lib/network/modules/components/edges/StraightEdge.js View File

@ -10,15 +10,15 @@ class StraightEdge extends EdgeBase {
* @param {CanvasRenderingContext2D} ctx
* @private
*/
_line(ctx) {
_line(ctx, values) {
// draw a straight line
ctx.beginPath();
ctx.moveTo(this.fromPoint.x, this.fromPoint.y);
ctx.lineTo(this.toPoint.x, this.toPoint.y);
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
ctx.stroke();
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}
getViaNode() {

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

@ -18,7 +18,10 @@ class EdgeBase {
this.from = this.body.nodes[this.options.from];
this.to = this.body.nodes[this.options.to];
}
cleanup() {return false}
cleanup() {
return false;
}
setOptions(options) {
this.options = options;
@ -34,36 +37,36 @@ class EdgeBase {
* @param {CanvasRenderingContext2D} ctx
* @private
*/
drawLine(ctx, selected, hover, viaNode) {
drawLine(ctx, values, selected, hover, viaNode) {
// set style
ctx.strokeStyle = this.getColor(ctx, selected, hover);
ctx.lineWidth = this.getLineWidth(selected, hover);
ctx.strokeStyle = this.getColor(ctx, values, selected, hover);
ctx.lineWidth = values.width;
if (this.options.dashes !== false) {
this._drawDashedLine(ctx, viaNode);
if (values.dashes !== false) {
this._drawDashedLine(ctx, values, viaNode);
}
else {
this._drawLine(ctx, viaNode);
this._drawLine(ctx, values, viaNode);
}
}
_drawLine(ctx, viaNode, fromPoint, toPoint) {
_drawLine(ctx, values, viaNode, fromPoint, toPoint) {
if (this.from != this.to) {
// draw line
this._line(ctx, viaNode, fromPoint, toPoint);
this._line(ctx, values, viaNode, fromPoint, toPoint);
}
else {
let [x,y,radius] = this._getCircleData(ctx);
this._circle(ctx, x, y, radius);
let [x,y,radius] = this._getCircleData(ctx, values);
this._circle(ctx, values, x, y, radius);
}
}
_drawDashedLine(ctx, viaNode, fromPoint, toPoint) {
_drawDashedLine(ctx, values, viaNode, fromPoint, toPoint) {
ctx.lineCap = 'round';
let pattern = [5,5];
if (Array.isArray(this.options.dashes) === true) {
pattern = this.options.dashes;
if (Array.isArray(values.dashes) === true) {
pattern = values.dashes;
}
// only firefox and chrome support this method, else we use the legacy one.
@ -77,11 +80,11 @@ class EdgeBase {
// draw the line
if (this.from != this.to) {
// draw line
this._line(ctx, viaNode);
this._line(ctx, values, viaNode);
}
else {
let [x,y,radius] = this._getCircleData(ctx);
this._circle(ctx, x, y, radius);
let [x,y,radius] = this._getCircleData(ctx, values);
this._circle(ctx, values, x, y, radius);
}
// restore the dash settings.
@ -95,16 +98,16 @@ class EdgeBase {
ctx.dashedLine(this.from.x, this.from.y, this.to.x, this.to.y, pattern);
}
else {
let [x,y,radius] = this._getCircleData(ctx);
this._circle(ctx, x, y, radius);
let [x,y,radius] = this._getCircleData(ctx, values);
this._circle(ctx, values, x, y, radius);
}
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
ctx.stroke();
// disable shadows for other elements.
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}
}
@ -252,24 +255,23 @@ class EdgeBase {
}
getColor(ctx, selected, hover) {
let colorOptions = this.options.color;
if (colorOptions.inherit !== false) {
getColor(ctx, values, selected, hover) {
if (values.inheritsColor !== false) {
// when this is a loop edge, just use the 'from' method
if (colorOptions.inherit === 'both' && this.from.id !== this.to.id) {
if ((values.inheritsColor === 'both') && (this.from.id !== this.to.id)) {
let grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y);
let fromColor, toColor;
fromColor = this.from.options.color.highlight.border;
toColor = this.to.options.color.highlight.border;
if (this.from.selected === false && this.to.selected === false) {
fromColor = util.overrideOpacity(this.from.options.color.border, this.options.color.opacity);
toColor = util.overrideOpacity(this.to.options.color.border, this.options.color.opacity);
if ((this.from.selected === false) && (this.to.selected === false)) {
fromColor = util.overrideOpacity(this.from.options.color.border, values.opacity);
toColor = util.overrideOpacity(this.to.options.color.border, values.opacity);
}
else if (this.from.selected === true && this.to.selected === false) {
else if ((this.from.selected === true) && (this.to.selected === false)) {
toColor = this.to.options.color.border;
}
else if (this.from.selected === false && this.to.selected === true) {
else if ((this.from.selected === false) && (this.to.selected === true)) {
fromColor = this.from.options.color.border;
}
grd.addColorStop(0, fromColor);
@ -279,37 +281,13 @@ class EdgeBase {
return grd;
}
if (this.colorDirty === true) {
if (colorOptions.inherit === "to") {
this.color.highlight = this.to.options.color.highlight.border;
this.color.hover = this.to.options.color.hover.border;
this.color.color = util.overrideOpacity(this.to.options.color.border, colorOptions.opacity);
}
else { // (this.options.color.inherit.source === "from") {
this.color.highlight = this.from.options.color.highlight.border;
this.color.hover = this.from.options.color.hover.border;
this.color.color = util.overrideOpacity(this.from.options.color.border, colorOptions.opacity);
}
if (values.inheritsColor === "to") {
return util.overrideOpacity(this.to.options.color.border, values.opacity);
} else { // "from"
return util.overrideOpacity(this.from.options.color.border, values.opacity);
}
}
else if (this.colorDirty === true) {
this.color.highlight = colorOptions.highlight;
this.color.hover = colorOptions.hover;
this.color.color = util.overrideOpacity(colorOptions.color, colorOptions.opacity);
}
// if color inherit is on and gradients are used, the function has already returned by now.
this.colorDirty = false;
if (selected === true) {
return this.color.highlight;
}
else if (hover === true) {
return this.color.hover;
}
else {
return this.color.color;
} else {
return util.overrideOpacity(values.color, values.opacity);
}
}
@ -321,9 +299,9 @@ class EdgeBase {
* @param {Number} radius
* @private
*/
_circle(ctx, x, y, radius) {
_circle(ctx, values, x, y, radius) {
// draw shadow if enabled
this.enableShadow(ctx);
this.enableShadow(ctx, values);
// draw a circle
ctx.beginPath();
@ -331,7 +309,7 @@ class EdgeBase {
ctx.stroke();
// disable shadows for other elements.
this.disableShadow(ctx);
this.disableShadow(ctx, values);
}