Browse Source

added moving pop-up, optimized the check to hide popup

v3_develop
Alex de Mulder 9 years ago
parent
commit
8a1286aaac
7 changed files with 2438 additions and 2343 deletions
  1. +5
    -0
      HISTORY.md
  2. +2217
    -2171
      dist/vis.js
  3. +142
    -144
      examples/network/38_node_as_icon.html
  4. +23
    -6
      lib/network/Edge.js
  5. +43
    -16
      lib/network/Network.js
  6. +4
    -5
      lib/network/Node.js
  7. +4
    -1
      lib/network/Popup.js

+ 5
- 0
HISTORY.md View File

@ -4,6 +4,11 @@ http://visjs.org
## not yet released, version 3.10.1-SNAPSHOT ## not yet released, version 3.10.1-SNAPSHOT
### Network
- (added gradient coloring for lines, but set for release in 4.0 due to required refactoring of options)
- Fixed bug where a network that has frozen physics would resume redrawing after setData, setOptions etc.
### Timeline ### Timeline
- Fixed not property initializing with a DataView for groups. - Fixed not property initializing with a DataView for groups.

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


+ 142
- 144
examples/network/38_node_as_icon.html View File

@ -5,15 +5,155 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Network | node as icon</title> <title>Network | node as icon</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="../../dist/vis.js"></script> <script type="text/javascript" src="../../dist/vis.js"></script>
<link href="../../dist/vis.css" rel="stylesheet" type="text/css" /> <link href="../../dist/vis.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<script language="JavaScript">
function draw() {
/*
* Example for FontAwesome
*/
var optionsFA = {
height: '300px',
groups: {
usergroups: {
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf0c0',
iconSize: 50,
iconColor: '#57169a'
},
users: {
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf007',
iconSize: 50,
iconColor: '#aa00ff'
}
}
};
// create an array with nodes
var nodesFA = [{
id: 1,
label: 'User 1',
group: 'users'
}, {
id: 2,
label: 'User 2',
group: 'users'
}, {
id: 3,
label: 'Usergroup 1',
group: 'usergroups'
}, {
id: 4,
label: 'Usergroup 2',
group: 'usergroups'
}, {
id: 5,
label: 'Organisation 1',
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf1ad',
iconSize: 50,
iconColor: '#f0a30a'
}];
// create an array with edges
var edges = [{
from: 1,
to: 3
}, {
from: 1,
to: 4
}, {
from: 2,
to: 4
}, {
from: 3,
to: 5
}, {
from: 4,
to: 5
}];
// create a network
var containerFA = document.getElementById('mynetworkFA');
var dataFA = {
nodes: nodesFA,
edges: edges
};
var networkFA = new vis.Network(containerFA, dataFA, optionsFA);
/*
* Example for Ionicons
*/
var optionsIO = {
height: '300px',
groups: {
usergroups: {
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf47c',
iconSize: 50,
iconColor: '#57169a'
},
users: {
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf47e',
iconSize: 50,
iconColor: '#aa00ff'
}
}
};
// create an array with nodes
var nodesIO = [{
id: 1,
label: 'User 1',
group: 'users'
}, {
id: 2,
label: 'User 2',
group: 'users'
}, {
id: 3,
label: 'Usergroup 1',
group: 'usergroups'
}, {
id: 4,
label: 'Usergroup 2',
group: 'usergroups'
}, {
id: 5,
label: 'Organisation 1',
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf276',
iconSize: 50,
iconColor: '#f0a30a'
}];
// create a network
var containerIO = document.getElementById('mynetworkIO');
var dataIO = {
nodes: nodesIO,
edges: edges
};
var networkIO = new vis.Network(containerIO, dataIO, optionsIO);
}
</script>
</head> </head>
<body>
<body onload="draw()">
<h2> <h2>
<i class="fa fa-flag"></i> Use FontAwesome-icons for node</h2> <i class="fa fa-flag"></i> Use FontAwesome-icons for node</h2>
<div id="mynetworkFA"></div> <div id="mynetworkFA"></div>
@ -21,148 +161,6 @@
<i class="ion ion-ionic"></i> Use Ionicons-icons for node</h2> <i class="ion ion-ionic"></i> Use Ionicons-icons for node</h2>
<div id="mynetworkIO"></div> <div id="mynetworkIO"></div>
<script type="text/javascript">
$(function() {
/*
* Example for FontAwesome
*/
var optionsFA = {
height: '300px',
groups: {
usergroups: {
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf0c0',
iconSize: 50,
iconColor: '#57169a'
},
users: {
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf007',
iconSize: 50,
iconColor: '#aa00ff'
},
},
};
// create an array with nodes
var nodesFA = [{
id: 1,
label: 'User 1',
group: 'users'
}, {
id: 2,
label: 'User 2',
group: 'users'
}, {
id: 3,
label: 'Usergroup 1',
group: 'usergroups'
}, {
id: 4,
label: 'Usergroup 2',
group: 'usergroups'
}, {
id: 5,
label: 'Organisation 1',
shape: 'icon',
iconFontFace: 'FontAwesome',
icon: '\uf1ad',
iconSize: 50,
iconColor: '#f0a30a'
}];
// create an array with edges
var edges = [{
from: 1,
to: 3
}, {
from: 1,
to: 4
}, {
from: 2,
to: 4
}, {
from: 3,
to: 5
}, {
from: 4,
to: 5
}];
// create a network
var containerFA = document.getElementById('mynetworkFA');
var dataFA = {
nodes: nodesFA,
edges: edges
};
var networkFA = new vis.Network(containerFA, dataFA, optionsFA);
/*
* Example for Ionicons
*/
var optionsIO = {
height: '300px',
groups: {
usergroups: {
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf47c',
iconSize: 50,
iconColor: '#57169a'
},
users: {
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf47e',
iconSize: 50,
iconColor: '#aa00ff'
},
},
};
// create an array with nodes
var nodesIO = [{
id: 1,
label: 'User 1',
group: 'users'
}, {
id: 2,
label: 'User 2',
group: 'users'
}, {
id: 3,
label: 'Usergroup 1',
group: 'usergroups'
}, {
id: 4,
label: 'Usergroup 2',
group: 'usergroups'
}, {
id: 5,
label: 'Organisation 1',
shape: 'icon',
iconFontFace: 'Ionicons',
icon: '\uf276',
iconSize: 50,
iconColor: '#f0a30a'
}];
// create a network
var containerIO = document.getElementById('mynetworkIO');
var dataIO = {
nodes: nodesIO,
edges: edges
};
var networkIO = new vis.Network(containerIO, dataIO, optionsIO);
})
</script>
</body> </body>
</html> </html>

+ 23
- 6
lib/network/Edge.js View File

@ -236,6 +236,28 @@ Edge.prototype.isOverlappingWith = function(obj) {
Edge.prototype._getColor = function(ctx) { Edge.prototype._getColor = function(ctx) {
var colorObj = this.options.color; var colorObj = this.options.color;
if (this.options.useGradients == true) {
var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y);
var 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.opacity);
toColor = util.overrideOpacity(this.to.options.color.border, this.options.opacity);
}
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) {
fromColor = this.from.options.color.border;
}
grd.addColorStop(0, fromColor);
grd.addColorStop(1, toColor);
return grd;
}
if (this.colorDirty === true) { if (this.colorDirty === true) {
if (this.options.inheritColor == "to") { if (this.options.inheritColor == "to") {
colorObj = { colorObj = {
@ -255,12 +277,7 @@ Edge.prototype._getColor = function(ctx) {
this.colorDirty = false; this.colorDirty = false;
} }
if (this.options.useGradients == true) {
var grd = ctx.createLinearGradient(this.from.x, this.from.y, this.to.x, this.to.y);
grd.addColorStop(0, this.from.selected ? this.from.options.color.highlight.border : this.from.options.color.border);
grd.addColorStop(1, this.to.selected ? this.to.options.color.highlight.border : this.to.options.color.border);
return grd;
}
if (this.selected == true) {return colorObj.highlight;} if (this.selected == true) {return colorObj.highlight;}
else if (this.hover == true) {return colorObj.hover;} else if (this.hover == true) {return colorObj.hover;}

+ 43
- 16
lib/network/Network.js View File

@ -130,7 +130,7 @@ function Network (container, data, options) {
altLength: undefined altLength: undefined
}, },
inheritColor: "from", // to, from, false, true (== from) inheritColor: "from", // to, from, false, true (== from)
useGradients: false
useGradients: false // release in 4.0
}, },
configurePhysics:false, configurePhysics:false,
physics: { physics: {
@ -1356,9 +1356,18 @@ Network.prototype._onMouseMoveTitle = function (event) {
var gesture = hammerUtil.fakeGesture(this, event); var gesture = hammerUtil.fakeGesture(this, event);
var pointer = this._getPointer(gesture.center); var pointer = this._getPointer(gesture.center);
// check if the previously selected node is still selected // check if the previously selected node is still selected
if (this.popupObj) {
this._checkHidePopup(pointer);
if (this.popup !== undefined) {
if (this.popup.hidden === false) {
this._checkHidePopup(pointer);
}
// if the popup was not hidden above
if (this.popup.hidden === false) {
this.popup.setPosition(pointer.x + 3,pointer.y - 3)
this.popup.show();
}
} }
// if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over // if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over
@ -1431,8 +1440,9 @@ Network.prototype._checkShowPopup = function (pointer) {
}; };
var id; var id;
var lastPopupNode = this.popupObj;
var previousPopupObjId = this.popupObj === undefined ? "" : this.popupObj.id;
var nodeUnderCursor = false; var nodeUnderCursor = false;
var popupType = "node";
if (this.popupObj == undefined) { if (this.popupObj == undefined) {
// search the nodes for overlap, select the top one in case of multiple nodes // search the nodes for overlap, select the top one in case of multiple nodes
@ -1474,23 +1484,26 @@ Network.prototype._checkShowPopup = function (pointer) {
if (overlappingEdges.length > 0) { if (overlappingEdges.length > 0) {
this.popupObj = this.edges[overlappingEdges[overlappingEdges.length - 1]]; this.popupObj = this.edges[overlappingEdges[overlappingEdges.length - 1]];
popupType = "edge";
} }
} }
if (this.popupObj) { if (this.popupObj) {
// show popup message window // show popup message window
if (this.popupObj != lastPopupNode) {
var me = this;
if (!me.popup) {
me.popup = new Popup(me.frame, me.constants.tooltip);
if (this.popupObj.id != previousPopupObjId) {
if (this.popup === undefined) {
this.popup = new Popup(this.frame, this.constants.tooltip);
} }
this.popup.popupTargetType = popupType;
this.popup.popupTargetId = this.popupObj.id;
// adjust a small offset such that the mouse cursor is located in the // adjust a small offset such that the mouse cursor is located in the
// bottom left location of the popup, and you can easily move over the // bottom left location of the popup, and you can easily move over the
// popup area // popup area
me.popup.setPosition(pointer.x - 3, pointer.y - 3);
me.popup.setText(me.popupObj.getTitle());
me.popup.show();
this.popup.setPosition(pointer.x + 3, pointer.y - 3);
this.popup.setText(this.popupObj.getTitle());
this.popup.show();
} }
} }
else { else {
@ -1502,17 +1515,31 @@ Network.prototype._checkShowPopup = function (pointer) {
/** /**
* Check if the popup must be hided, which is the case when the mouse is no
* Check if the popup must be hidden, which is the case when the mouse is no
* longer hovering on the object * longer hovering on the object
* @param {{x:Number, y:Number}} pointer * @param {{x:Number, y:Number}} pointer
* @private * @private
*/ */
Network.prototype._checkHidePopup = function (pointer) { Network.prototype._checkHidePopup = function (pointer) {
if (!this.popupObj || !this._getNodeAt(pointer) ) {
var pointerObj = {
left: this._XconvertDOMtoCanvas(pointer.x),
top: this._YconvertDOMtoCanvas(pointer.y),
right: this._XconvertDOMtoCanvas(pointer.x),
bottom: this._YconvertDOMtoCanvas(pointer.y)
};
var stillOnObj = false;
if (this.popup.popupTargetType == 'node') {
stillOnObj = this.nodes[this.popup.popupTargetId].isOverlappingWith(pointerObj)
}
else {
stillOnObj = this.edges[this.popup.popupTargetId].isOverlappingWith(pointerObj)
}
if (stillOnObj === false) {
this.popupObj = undefined; this.popupObj = undefined;
if (this.popup) {
this.popup.hide();
}
this.popup.hide();
} }
}; };

+ 4
- 5
lib/network/Node.js View File

@ -1034,12 +1034,11 @@ Node.prototype._resizeIcon = function (ctx) {
Node.prototype._drawIcon = function (ctx) { Node.prototype._drawIcon = function (ctx) {
this._resizeIcon(ctx); this._resizeIcon(ctx);
this.options.iconSize = this.options.iconSize || 50;
this.options.iconSize = this.options.iconSize || 50; this.options.iconSize = this.options.iconSize || 50;
this.left = this.x - this.width / 2; this.left = this.x - this.width / 2;
this.top = this.y - this.height / 2; this.top = this.y - this.height / 2;
this._icon(ctx, this.options.icon, this.x, this.y);
this._icon(ctx);
this.boundingBox.top = this.y - this.options.iconSize/2; this.boundingBox.top = this.y - this.options.iconSize/2;
@ -1056,10 +1055,10 @@ Node.prototype._drawIcon = function (ctx) {
} }
}; };
Node.prototype._icon = function (ctx, icon, x, y) {
Node.prototype._icon = function (ctx) {
var relativeIconSize = Number(this.options.iconSize) * this.networkScale; var relativeIconSize = Number(this.options.iconSize) * this.networkScale;
if (icon && relativeIconSize > this.options.fontDrawThreshold - 1) {
if (this.options.icon && relativeIconSize > this.options.fontDrawThreshold - 1) {
var iconSize = Number(this.options.iconSize); var iconSize = Number(this.options.iconSize);
@ -1069,7 +1068,7 @@ Node.prototype._icon = function (ctx, icon, x, y) {
ctx.fillStyle = this.options.iconColor || "black"; ctx.fillStyle = this.options.iconColor || "black";
ctx.textAlign = "center"; ctx.textAlign = "center";
ctx.textBaseline = "middle"; ctx.textBaseline = "middle";
ctx.fillText(icon, x, y);
ctx.fillText(this.options.icon, this.x, this.y);
} }
}; };

+ 4
- 1
lib/network/Popup.js View File

@ -40,8 +40,9 @@ function Popup(container, x, y, text, style) {
this.x = 0; this.x = 0;
this.y = 0; this.y = 0;
this.padding = 5; this.padding = 5;
this.hidden = false;
if (x !== undefined && y !== undefined ) {
if (x !== undefined && y !== undefined) {
this.setPosition(x, y); this.setPosition(x, y);
} }
if (text !== undefined) { if (text !== undefined) {
@ -116,6 +117,7 @@ Popup.prototype.show = function (show) {
this.frame.style.left = left + "px"; this.frame.style.left = left + "px";
this.frame.style.top = top + "px"; this.frame.style.top = top + "px";
this.frame.style.visibility = "visible"; this.frame.style.visibility = "visible";
this.hidden = false;
} }
else { else {
this.hide(); this.hide();
@ -126,6 +128,7 @@ Popup.prototype.show = function (show) {
* Hide the popup window * Hide the popup window
*/ */
Popup.prototype.hide = function () { Popup.prototype.hide = function () {
this.hidden = true;
this.frame.style.visibility = "hidden"; this.frame.style.visibility = "hidden";
}; };

Loading…
Cancel
Save