vis-rails 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -1
- data/README.md +2 -0
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/javascripts/module/exports-only-timeline.js +55 -0
- data/vendor/assets/javascripts/vis-only-timeline.js +23 -0
- data/vendor/assets/javascripts/vis.js +3 -3
- data/vendor/assets/stylesheets/vis-only-timeline.css +3 -0
- data/vendor/assets/vis/DataSet.js +106 -130
- data/vendor/assets/vis/DataView.js +35 -37
- data/vendor/assets/vis/graph/Edge.js +225 -45
- data/vendor/assets/vis/graph/Graph.js +120 -24
- data/vendor/assets/vis/graph/Node.js +16 -16
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +1 -1
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +143 -0
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +81 -3
- data/vendor/assets/vis/graph3d/Graph3d.js +3306 -0
- data/vendor/assets/vis/module/exports.js +2 -3
- data/vendor/assets/vis/timeline/Range.js +93 -80
- data/vendor/assets/vis/timeline/Timeline.js +525 -428
- data/vendor/assets/vis/timeline/component/Component.js +19 -53
- data/vendor/assets/vis/timeline/component/CurrentTime.js +57 -25
- data/vendor/assets/vis/timeline/component/CustomTime.js +55 -19
- data/vendor/assets/vis/timeline/component/Group.js +47 -50
- data/vendor/assets/vis/timeline/component/ItemSet.js +402 -206
- data/vendor/assets/vis/timeline/component/TimeAxis.js +112 -169
- data/vendor/assets/vis/timeline/component/css/animation.css +33 -0
- data/vendor/assets/vis/timeline/component/css/currenttime.css +1 -1
- data/vendor/assets/vis/timeline/component/css/customtime.css +1 -1
- data/vendor/assets/vis/timeline/component/css/item.css +1 -11
- data/vendor/assets/vis/timeline/component/css/itemset.css +13 -18
- data/vendor/assets/vis/timeline/component/css/labelset.css +8 -6
- data/vendor/assets/vis/timeline/component/css/panel.css +56 -13
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +15 -8
- data/vendor/assets/vis/timeline/component/item/Item.js +16 -15
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +30 -30
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +20 -21
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +23 -24
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +10 -10
- data/vendor/assets/vis/timeline/stack.js +5 -5
- data/vendor/assets/vis/util.js +81 -35
- metadata +7 -4
- data/vendor/assets/vis/timeline/component/Panel.js +0 -170
- data/vendor/assets/vis/timeline/component/RootPanel.js +0 -176
| @@ -23,14 +23,14 @@ function Graph (container, data, options) { | |
| 23 23 | 
             
              this.renderTimestep = 1000 / this.renderRefreshRate; // ms -- saves calculation later on
         | 
| 24 24 | 
             
              this.renderTime = 0.5 * this.renderTimestep;         // measured time it takes to render a frame
         | 
| 25 25 | 
             
              this.maxPhysicsTicksPerRender = 3;                   // max amount of physics ticks per render step.
         | 
| 26 | 
            -
              this.physicsDiscreteStepsize = 0. | 
| 26 | 
            +
              this.physicsDiscreteStepsize = 0.50;                 // discrete stepsize of the simulation
         | 
| 27 27 |  | 
| 28 28 | 
             
              this.stabilize = true;  // stabilize before displaying the graph
         | 
| 29 29 | 
             
              this.selectable = true;
         | 
| 30 30 | 
             
              this.initializing = true;
         | 
| 31 31 |  | 
| 32 32 | 
             
              // these functions are triggered when the dataset is edited
         | 
| 33 | 
            -
              this.triggerFunctions = {add:null,edit:null,connect:null,del:null};
         | 
| 33 | 
            +
              this.triggerFunctions = {add:null,edit:null,editEdge:null,connect:null,del:null};
         | 
| 34 34 |  | 
| 35 35 | 
             
              // set constant values
         | 
| 36 36 | 
             
              this.constants = {
         | 
| @@ -53,6 +53,10 @@ function Graph (container, data, options) { | |
| 53 53 | 
             
                    highlight: {
         | 
| 54 54 | 
             
                      border: '#2B7CE9',
         | 
| 55 55 | 
             
                      background: '#D2E5FF'
         | 
| 56 | 
            +
                    },
         | 
| 57 | 
            +
                    hover: {
         | 
| 58 | 
            +
                      border: '#2B7CE9',
         | 
| 59 | 
            +
                      background: '#D2E5FF'
         | 
| 56 60 | 
             
                    }
         | 
| 57 61 | 
             
                  },
         | 
| 58 62 | 
             
                  borderColor: '#2B7CE9',
         | 
| @@ -64,10 +68,12 @@ function Graph (container, data, options) { | |
| 64 68 | 
             
                  widthMin: 1,
         | 
| 65 69 | 
             
                  widthMax: 15,
         | 
| 66 70 | 
             
                  width: 1,
         | 
| 71 | 
            +
                  hoverWidth: 1.5,
         | 
| 67 72 | 
             
                  style: 'line',
         | 
| 68 73 | 
             
                  color: {
         | 
| 69 74 | 
             
                    color:'#848484',
         | 
| 70 | 
            -
                    highlight:'#848484'
         | 
| 75 | 
            +
                    highlight:'#848484',
         | 
| 76 | 
            +
                    hover: '#848484'
         | 
| 71 77 | 
             
                  },
         | 
| 72 78 | 
             
                  fontColor: '#343434',
         | 
| 73 79 | 
             
                  fontSize: 14, // px
         | 
| @@ -160,9 +166,11 @@ function Graph (container, data, options) { | |
| 160 166 | 
             
                  link:"Add Link",
         | 
| 161 167 | 
             
                  del:"Delete selected",
         | 
| 162 168 | 
             
                  editNode:"Edit Node",
         | 
| 169 | 
            +
                  editEdge:"Edit Edge",
         | 
| 163 170 | 
             
                  back:"Back",
         | 
| 164 171 | 
             
                  addDescription:"Click in an empty space to place a new node.",
         | 
| 165 172 | 
             
                  linkDescription:"Click on a node and drag the edge to another node to connect them.",
         | 
| 173 | 
            +
                  editEdgeDescription:"Click on the control points and drag them to a node to connect to it.",
         | 
| 166 174 | 
             
                  addError:"The function for add does not support two arguments (data,callback).",
         | 
| 167 175 | 
             
                  linkError:"The function for connect does not support two arguments (data,callback).",
         | 
| 168 176 | 
             
                  editError:"The function for edit does not support two arguments (data, callback).",
         | 
| @@ -180,10 +188,13 @@ function Graph (container, data, options) { | |
| 180 188 | 
             
                    background: '#FFFFC6'
         | 
| 181 189 | 
             
                  }
         | 
| 182 190 | 
             
                },
         | 
| 183 | 
            -
                 | 
| 184 | 
            -
                 | 
| 191 | 
            +
                dragGraph: true,
         | 
| 192 | 
            +
                dragNodes: true,
         | 
| 193 | 
            +
                zoomable: true,
         | 
| 194 | 
            +
                hover: false
         | 
| 185 195 | 
             
              };
         | 
| 186 | 
            -
              this. | 
| 196 | 
            +
              this.hoverObj = {nodes:{},edges:{}};
         | 
| 197 | 
            +
             | 
| 187 198 |  | 
| 188 199 | 
             
              // Node variables
         | 
| 189 200 | 
             
              var graph = this;
         | 
| @@ -217,7 +228,6 @@ function Graph (container, data, options) { | |
| 217 228 | 
             
              this._setScale(1);
         | 
| 218 229 | 
             
              this.setOptions(options);
         | 
| 219 230 |  | 
| 220 | 
            -
             | 
| 221 231 | 
             
              // other vars
         | 
| 222 232 | 
             
              this.freezeSimulation = false;// freeze the simulation
         | 
| 223 233 | 
             
              this.cachedFunctions = {};
         | 
| @@ -521,9 +531,10 @@ Graph.prototype.setOptions = function (options) { | |
| 521 531 | 
             
                if (options.freezeForStabilization !== undefined)    {this.constants.freezeForStabilization = options.freezeForStabilization;}
         | 
| 522 532 | 
             
                if (options.configurePhysics !== undefined){this.constants.configurePhysics = options.configurePhysics;}
         | 
| 523 533 | 
             
                if (options.stabilizationIterations !== undefined)   {this.constants.stabilizationIterations = options.stabilizationIterations;}
         | 
| 524 | 
            -
                if (options. | 
| 525 | 
            -
                if (options. | 
| 526 | 
            -
             | 
| 534 | 
            +
                if (options.dragGraph !== undefined)       {this.constants.dragGraph = options.dragGraph;}
         | 
| 535 | 
            +
                if (options.dragNodes !== undefined)       {this.constants.dragNodes = options.dragNodes;}
         | 
| 536 | 
            +
                if (options.zoomable !== undefined)        {this.constants.zoomable = options.zoomable;}
         | 
| 537 | 
            +
                if (options.hover !== undefined)           {this.constants.hover = options.hover;}
         | 
| 527 538 |  | 
| 528 539 | 
             
                if (options.labels !== undefined)  {
         | 
| 529 540 | 
             
                  for (prop in options.labels) {
         | 
| @@ -541,6 +552,10 @@ Graph.prototype.setOptions = function (options) { | |
| 541 552 | 
             
                  this.triggerFunctions.edit = options.onEdit;
         | 
| 542 553 | 
             
                }
         | 
| 543 554 |  | 
| 555 | 
            +
                if (options.onEditEdge) {
         | 
| 556 | 
            +
                  this.triggerFunctions.editEdge = options.onEditEdge;
         | 
| 557 | 
            +
                }
         | 
| 558 | 
            +
             | 
| 544 559 | 
             
                if (options.onConnect) {
         | 
| 545 560 | 
             
                  this.triggerFunctions.connect = options.onConnect;
         | 
| 546 561 | 
             
                }
         | 
| @@ -635,6 +650,7 @@ Graph.prototype.setOptions = function (options) { | |
| 635 650 | 
             
                      this.constants.dataManipulation[prop] = options.dataManipulation[prop];
         | 
| 636 651 | 
             
                    }
         | 
| 637 652 | 
             
                  }
         | 
| 653 | 
            +
                  this.editMode = this.constants.dataManipulation.initiallyVisible;
         | 
| 638 654 | 
             
                }
         | 
| 639 655 | 
             
                else if (options.dataManipulation !== undefined)  {
         | 
| 640 656 | 
             
                  this.constants.dataManipulation.enabled = false;
         | 
| @@ -656,10 +672,12 @@ Graph.prototype.setOptions = function (options) { | |
| 656 672 | 
             
                      this.constants.edges.color = {};
         | 
| 657 673 | 
             
                      this.constants.edges.color.color = options.edges.color;
         | 
| 658 674 | 
             
                      this.constants.edges.color.highlight = options.edges.color;
         | 
| 675 | 
            +
                      this.constants.edges.color.hover = options.edges.color;
         | 
| 659 676 | 
             
                    }
         | 
| 660 677 | 
             
                    else {
         | 
| 661 678 | 
             
                      if (options.edges.color.color !== undefined)     {this.constants.edges.color.color = options.edges.color.color;}
         | 
| 662 679 | 
             
                      if (options.edges.color.highlight !== undefined) {this.constants.edges.color.highlight = options.edges.color.highlight;}
         | 
| 680 | 
            +
                      if (options.edges.color.hover !== undefined)     {this.constants.edges.color.hover = options.edges.color.hover;}
         | 
| 663 681 | 
             
                    }
         | 
| 664 682 | 
             
                  }
         | 
| 665 683 |  | 
| @@ -946,7 +964,7 @@ Graph.prototype._handleOnDrag = function(event) { | |
| 946 964 | 
             
              var me = this,
         | 
| 947 965 | 
             
                drag = this.drag,
         | 
| 948 966 | 
             
                selection = drag.selection;
         | 
| 949 | 
            -
              if (selection && selection.length) {
         | 
| 967 | 
            +
              if (selection && selection.length && this.constants.dragNodes == true) {
         | 
| 950 968 | 
             
                // calculate delta's and new location
         | 
| 951 969 | 
             
                var deltaX = pointer.x - drag.pointer.x,
         | 
| 952 970 | 
             
                  deltaY = pointer.y - drag.pointer.y;
         | 
| @@ -971,7 +989,7 @@ Graph.prototype._handleOnDrag = function(event) { | |
| 971 989 | 
             
                }
         | 
| 972 990 | 
             
              }
         | 
| 973 991 | 
             
              else {
         | 
| 974 | 
            -
                if (this.constants. | 
| 992 | 
            +
                if (this.constants.dragGraph == true) {
         | 
| 975 993 | 
             
                  // move the graph
         | 
| 976 994 | 
             
                  var diffX = pointer.x - this.drag.pointer.x;
         | 
| 977 995 | 
             
                  var diffY = pointer.y - this.drag.pointer.y;
         | 
| @@ -1159,7 +1177,7 @@ Graph.prototype._onMouseMoveTitle = function (event) { | |
| 1159 1177 | 
             
              var pointer = this._getPointer(gesture.center);
         | 
| 1160 1178 |  | 
| 1161 1179 | 
             
              // check if the previously selected node is still selected
         | 
| 1162 | 
            -
              if (this. | 
| 1180 | 
            +
              if (this.popupObj) {
         | 
| 1163 1181 | 
             
                this._checkHidePopup(pointer);
         | 
| 1164 1182 | 
             
              }
         | 
| 1165 1183 |  | 
| @@ -1175,6 +1193,40 @@ Graph.prototype._onMouseMoveTitle = function (event) { | |
| 1175 1193 | 
             
              if (!this.drag.dragging) {
         | 
| 1176 1194 | 
             
                this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay);
         | 
| 1177 1195 | 
             
              }
         | 
| 1196 | 
            +
             | 
| 1197 | 
            +
             | 
| 1198 | 
            +
              /**
         | 
| 1199 | 
            +
               * Adding hover highlights
         | 
| 1200 | 
            +
               */
         | 
| 1201 | 
            +
              if (this.constants.hover == true) {
         | 
| 1202 | 
            +
                // removing all hover highlights
         | 
| 1203 | 
            +
                for (var edgeId in this.hoverObj.edges) {
         | 
| 1204 | 
            +
                  if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
         | 
| 1205 | 
            +
                    this.hoverObj.edges[edgeId].hover = false;
         | 
| 1206 | 
            +
                    delete this.hoverObj.edges[edgeId];
         | 
| 1207 | 
            +
                  }
         | 
| 1208 | 
            +
                }
         | 
| 1209 | 
            +
             | 
| 1210 | 
            +
                // adding hover highlights
         | 
| 1211 | 
            +
                var obj = this._getNodeAt(pointer);
         | 
| 1212 | 
            +
                if (obj == null) {
         | 
| 1213 | 
            +
                  obj = this._getEdgeAt(pointer);
         | 
| 1214 | 
            +
                }
         | 
| 1215 | 
            +
                if (obj != null) {
         | 
| 1216 | 
            +
                  this._hoverObject(obj);
         | 
| 1217 | 
            +
                }
         | 
| 1218 | 
            +
             | 
| 1219 | 
            +
                // removing all node hover highlights except for the selected one.
         | 
| 1220 | 
            +
                for (var nodeId in this.hoverObj.nodes) {
         | 
| 1221 | 
            +
                  if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
         | 
| 1222 | 
            +
                    if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) {
         | 
| 1223 | 
            +
                      this._blurObject(this.hoverObj.nodes[nodeId]);
         | 
| 1224 | 
            +
                      delete this.hoverObj.nodes[nodeId];
         | 
| 1225 | 
            +
                    }
         | 
| 1226 | 
            +
                  }
         | 
| 1227 | 
            +
                }
         | 
| 1228 | 
            +
                this.redraw();
         | 
| 1229 | 
            +
              }
         | 
| 1178 1230 | 
             
            };
         | 
| 1179 1231 |  | 
| 1180 1232 | 
             
            /**
         | 
| @@ -1194,23 +1246,23 @@ Graph.prototype._checkShowPopup = function (pointer) { | |
| 1194 1246 | 
             
              };
         | 
| 1195 1247 |  | 
| 1196 1248 | 
             
              var id;
         | 
| 1197 | 
            -
              var lastPopupNode = this. | 
| 1249 | 
            +
              var lastPopupNode = this.popupObj;
         | 
| 1198 1250 |  | 
| 1199 | 
            -
              if (this. | 
| 1251 | 
            +
              if (this.popupObj == undefined) {
         | 
| 1200 1252 | 
             
                // search the nodes for overlap, select the top one in case of multiple nodes
         | 
| 1201 1253 | 
             
                var nodes = this.nodes;
         | 
| 1202 1254 | 
             
                for (id in nodes) {
         | 
| 1203 1255 | 
             
                  if (nodes.hasOwnProperty(id)) {
         | 
| 1204 1256 | 
             
                    var node = nodes[id];
         | 
| 1205 1257 | 
             
                    if (node.getTitle() !== undefined && node.isOverlappingWith(obj)) {
         | 
| 1206 | 
            -
                      this. | 
| 1258 | 
            +
                      this.popupObj = node;
         | 
| 1207 1259 | 
             
                      break;
         | 
| 1208 1260 | 
             
                    }
         | 
| 1209 1261 | 
             
                  }
         | 
| 1210 1262 | 
             
                }
         | 
| 1211 1263 | 
             
              }
         | 
| 1212 1264 |  | 
| 1213 | 
            -
              if (this. | 
| 1265 | 
            +
              if (this.popupObj === undefined) {
         | 
| 1214 1266 | 
             
                // search the edges for overlap
         | 
| 1215 1267 | 
             
                var edges = this.edges;
         | 
| 1216 1268 | 
             
                for (id in edges) {
         | 
| @@ -1218,16 +1270,16 @@ Graph.prototype._checkShowPopup = function (pointer) { | |
| 1218 1270 | 
             
                    var edge = edges[id];
         | 
| 1219 1271 | 
             
                    if (edge.connected && (edge.getTitle() !== undefined) &&
         | 
| 1220 1272 | 
             
                        edge.isOverlappingWith(obj)) {
         | 
| 1221 | 
            -
                      this. | 
| 1273 | 
            +
                      this.popupObj = edge;
         | 
| 1222 1274 | 
             
                      break;
         | 
| 1223 1275 | 
             
                    }
         | 
| 1224 1276 | 
             
                  }
         | 
| 1225 1277 | 
             
                }
         | 
| 1226 1278 | 
             
              }
         | 
| 1227 1279 |  | 
| 1228 | 
            -
              if (this. | 
| 1280 | 
            +
              if (this.popupObj) {
         | 
| 1229 1281 | 
             
                // show popup message window
         | 
| 1230 | 
            -
                if (this. | 
| 1282 | 
            +
                if (this.popupObj != lastPopupNode) {
         | 
| 1231 1283 | 
             
                  var me = this;
         | 
| 1232 1284 | 
             
                  if (!me.popup) {
         | 
| 1233 1285 | 
             
                    me.popup = new Popup(me.frame, me.constants.tooltip);
         | 
| @@ -1237,7 +1289,7 @@ Graph.prototype._checkShowPopup = function (pointer) { | |
| 1237 1289 | 
             
                  // bottom left location of the popup, and you can easily move over the
         | 
| 1238 1290 | 
             
                  // popup area
         | 
| 1239 1291 | 
             
                  me.popup.setPosition(pointer.x - 3, pointer.y - 3);
         | 
| 1240 | 
            -
                  me.popup.setText(me. | 
| 1292 | 
            +
                  me.popup.setText(me.popupObj.getTitle());
         | 
| 1241 1293 | 
             
                  me.popup.show();
         | 
| 1242 1294 | 
             
                }
         | 
| 1243 1295 | 
             
              }
         | 
| @@ -1256,8 +1308,8 @@ Graph.prototype._checkShowPopup = function (pointer) { | |
| 1256 1308 | 
             
             * @private
         | 
| 1257 1309 | 
             
             */
         | 
| 1258 1310 | 
             
            Graph.prototype._checkHidePopup = function (pointer) {
         | 
| 1259 | 
            -
              if (!this. | 
| 1260 | 
            -
                this. | 
| 1311 | 
            +
              if (!this.popupObj || !this._getNodeAt(pointer) ) {
         | 
| 1312 | 
            +
                this.popupObj = undefined;
         | 
| 1261 1313 | 
             
                if (this.popup) {
         | 
| 1262 1314 | 
             
                  this.popup.hide();
         | 
| 1263 1315 | 
             
                }
         | 
| @@ -1633,7 +1685,6 @@ Graph.prototype._updateValueRange = function(obj) { | |
| 1633 1685 | 
             
             */
         | 
| 1634 1686 | 
             
            Graph.prototype.redraw = function() {
         | 
| 1635 1687 | 
             
              this.setSize(this.width, this.height);
         | 
| 1636 | 
            -
             | 
| 1637 1688 | 
             
              this._redraw();
         | 
| 1638 1689 | 
             
            };
         | 
| 1639 1690 |  | 
| @@ -1665,6 +1716,7 @@ Graph.prototype._redraw = function() { | |
| 1665 1716 | 
             
              this._doInAllSectors("_drawAllSectorNodes",ctx);
         | 
| 1666 1717 | 
             
              this._doInAllSectors("_drawEdges",ctx);
         | 
| 1667 1718 | 
             
              this._doInAllSectors("_drawNodes",ctx,false);
         | 
| 1719 | 
            +
              this._doInAllSectors("_drawControlNodes",ctx);
         | 
| 1668 1720 |  | 
| 1669 1721 | 
             
            //  this._doInSupportSector("_drawNodes",ctx,true);
         | 
| 1670 1722 | 
             
            //  this._drawTree(ctx,"#F00F0F");
         | 
| @@ -1849,6 +1901,21 @@ Graph.prototype._drawEdges = function(ctx) { | |
| 1849 1901 | 
             
              }
         | 
| 1850 1902 | 
             
            };
         | 
| 1851 1903 |  | 
| 1904 | 
            +
            /**
         | 
| 1905 | 
            +
             * Redraw all edges
         | 
| 1906 | 
            +
             * The 2d context of a HTML canvas can be retrieved by canvas.getContext('2d');
         | 
| 1907 | 
            +
             * @param {CanvasRenderingContext2D}   ctx
         | 
| 1908 | 
            +
             * @private
         | 
| 1909 | 
            +
             */
         | 
| 1910 | 
            +
            Graph.prototype._drawControlNodes = function(ctx) {
         | 
| 1911 | 
            +
              var edges = this.edges;
         | 
| 1912 | 
            +
              for (var id in edges) {
         | 
| 1913 | 
            +
                if (edges.hasOwnProperty(id)) {
         | 
| 1914 | 
            +
                  edges[id]._drawControlNodes(ctx);
         | 
| 1915 | 
            +
                }
         | 
| 1916 | 
            +
              }
         | 
| 1917 | 
            +
            };
         | 
| 1918 | 
            +
             | 
| 1852 1919 | 
             
            /**
         | 
| 1853 1920 | 
             
             * Find a stable position for all nodes
         | 
| 1854 1921 | 
             
             * @private
         | 
| @@ -2183,7 +2250,36 @@ Graph.prototype.storePosition = function() { | |
| 2183 2250 | 
             
            };
         | 
| 2184 2251 |  | 
| 2185 2252 |  | 
| 2253 | 
            +
            /**
         | 
| 2254 | 
            +
             * Center a node in view.
         | 
| 2255 | 
            +
             *
         | 
| 2256 | 
            +
             * @param {Number} nodeId
         | 
| 2257 | 
            +
             * @param {Number} [zoomLevel]
         | 
| 2258 | 
            +
             */
         | 
| 2259 | 
            +
            Graph.prototype.focusOnNode = function (nodeId, zoomLevel) {
         | 
| 2260 | 
            +
              if (this.nodes.hasOwnProperty(nodeId)) {
         | 
| 2261 | 
            +
                if (zoomLevel === undefined) {
         | 
| 2262 | 
            +
                  zoomLevel = this._getScale();
         | 
| 2263 | 
            +
                }
         | 
| 2264 | 
            +
                var nodePosition= {x: this.nodes[nodeId].x, y: this.nodes[nodeId].y};
         | 
| 2265 | 
            +
             | 
| 2266 | 
            +
                var requiredScale = zoomLevel;
         | 
| 2267 | 
            +
                this._setScale(requiredScale);
         | 
| 2268 | 
            +
             | 
| 2269 | 
            +
                var canvasCenter = this.DOMtoCanvas({x:0.5 * this.frame.canvas.width,y:0.5 * this.frame.canvas.height});
         | 
| 2270 | 
            +
                var translation = this._getTranslation();
         | 
| 2186 2271 |  | 
| 2272 | 
            +
                var distanceFromCenter = {x:canvasCenter.x - nodePosition.x,
         | 
| 2273 | 
            +
                                          y:canvasCenter.y - nodePosition.y};
         | 
| 2274 | 
            +
             | 
| 2275 | 
            +
                this._setTranslation(translation.x + requiredScale * distanceFromCenter.x,
         | 
| 2276 | 
            +
                                     translation.y + requiredScale * distanceFromCenter.y);
         | 
| 2277 | 
            +
                this.redraw();
         | 
| 2278 | 
            +
              }
         | 
| 2279 | 
            +
              else {
         | 
| 2280 | 
            +
                console.log("This nodeId cannot be found.")
         | 
| 2281 | 
            +
              }
         | 
| 2282 | 
            +
            };
         | 
| 2187 2283 |  | 
| 2188 2284 |  | 
| 2189 2285 |  | 
| @@ -25,13 +25,14 @@ | |
| 25 25 | 
             
             */
         | 
| 26 26 | 
             
            function Node(properties, imagelist, grouplist, constants) {
         | 
| 27 27 | 
             
              this.selected = false;
         | 
| 28 | 
            +
              this.hover = false;
         | 
| 28 29 |  | 
| 29 30 | 
             
              this.edges = []; // all edges connected to this node
         | 
| 30 31 | 
             
              this.dynamicEdges = [];
         | 
| 31 32 | 
             
              this.reroutedEdges = {};
         | 
| 32 | 
            -
              this.group = constants.nodes.group;
         | 
| 33 33 |  | 
| 34 | 
            -
              this. | 
| 34 | 
            +
              this.group = constants.nodes.group;
         | 
| 35 | 
            +
              this.fontSize = Number(constants.nodes.fontSize);
         | 
| 35 36 | 
             
              this.fontFace = constants.nodes.fontFace;
         | 
| 36 37 | 
             
              this.fontColor = constants.nodes.fontColor;
         | 
| 37 38 | 
             
              this.fontDrawThreshold = 3;
         | 
| @@ -569,7 +570,7 @@ Node.prototype._drawBox = function (ctx) { | |
| 569 570 | 
             
              var clusterLineWidth = 2.5;
         | 
| 570 571 | 
             
              var selectionLineWidth = 2;
         | 
| 571 572 |  | 
| 572 | 
            -
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.color.border;
         | 
| 573 | 
            +
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
         | 
| 573 574 |  | 
| 574 575 | 
             
              // draw the outer border
         | 
| 575 576 | 
             
              if (this.clusterSize > 1) {
         | 
| @@ -618,7 +619,7 @@ Node.prototype._drawDatabase = function (ctx) { | |
| 618 619 | 
             
              var clusterLineWidth = 2.5;
         | 
| 619 620 | 
             
              var selectionLineWidth = 2;
         | 
| 620 621 |  | 
| 621 | 
            -
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.color.border;
         | 
| 622 | 
            +
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
         | 
| 622 623 |  | 
| 623 624 | 
             
              // draw the outer border
         | 
| 624 625 | 
             
              if (this.clusterSize > 1) {
         | 
| @@ -633,7 +634,7 @@ Node.prototype._drawDatabase = function (ctx) { | |
| 633 634 | 
             
              ctx.lineWidth *= this.graphScaleInv;
         | 
| 634 635 | 
             
              ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
         | 
| 635 636 |  | 
| 636 | 
            -
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
         | 
| 637 | 
            +
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
         | 
| 637 638 | 
             
              ctx.database(this.x - this.width/2, this.y - this.height*0.5, this.width, this.height);
         | 
| 638 639 | 
             
              ctx.fill();
         | 
| 639 640 | 
             
              ctx.stroke();
         | 
| @@ -668,7 +669,7 @@ Node.prototype._drawCircle = function (ctx) { | |
| 668 669 | 
             
              var clusterLineWidth = 2.5;
         | 
| 669 670 | 
             
              var selectionLineWidth = 2;
         | 
| 670 671 |  | 
| 671 | 
            -
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.color.border;
         | 
| 672 | 
            +
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
         | 
| 672 673 |  | 
| 673 674 | 
             
              // draw the outer border
         | 
| 674 675 | 
             
              if (this.clusterSize > 1) {
         | 
| @@ -683,7 +684,7 @@ Node.prototype._drawCircle = function (ctx) { | |
| 683 684 | 
             
              ctx.lineWidth *= this.graphScaleInv;
         | 
| 684 685 | 
             
              ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
         | 
| 685 686 |  | 
| 686 | 
            -
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
         | 
| 687 | 
            +
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
         | 
| 687 688 | 
             
              ctx.circle(this.x, this.y, this.radius);
         | 
| 688 689 | 
             
              ctx.fill();
         | 
| 689 690 | 
             
              ctx.stroke();
         | 
| @@ -718,7 +719,7 @@ Node.prototype._drawEllipse = function (ctx) { | |
| 718 719 | 
             
              var clusterLineWidth = 2.5;
         | 
| 719 720 | 
             
              var selectionLineWidth = 2;
         | 
| 720 721 |  | 
| 721 | 
            -
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.color.border;
         | 
| 722 | 
            +
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
         | 
| 722 723 |  | 
| 723 724 | 
             
              // draw the outer border
         | 
| 724 725 | 
             
              if (this.clusterSize > 1) {
         | 
| @@ -733,7 +734,7 @@ Node.prototype._drawEllipse = function (ctx) { | |
| 733 734 | 
             
              ctx.lineWidth *= this.graphScaleInv;
         | 
| 734 735 | 
             
              ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
         | 
| 735 736 |  | 
| 736 | 
            -
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
         | 
| 737 | 
            +
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
         | 
| 737 738 |  | 
| 738 739 | 
             
              ctx.ellipse(this.left, this.top, this.width, this.height);
         | 
| 739 740 | 
             
              ctx.fill();
         | 
| @@ -795,7 +796,7 @@ Node.prototype._drawShape = function (ctx, shape) { | |
| 795 796 | 
             
                case 'star':          radiusMultiplier = 4; break;
         | 
| 796 797 | 
             
              }
         | 
| 797 798 |  | 
| 798 | 
            -
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.color.border;
         | 
| 799 | 
            +
              ctx.strokeStyle = this.selected ? this.color.highlight.border : this.hover ? this.color.hover.border : this.color.border;
         | 
| 799 800 |  | 
| 800 801 | 
             
              // draw the outer border
         | 
| 801 802 | 
             
              if (this.clusterSize > 1) {
         | 
| @@ -810,8 +811,7 @@ Node.prototype._drawShape = function (ctx, shape) { | |
| 810 811 | 
             
              ctx.lineWidth *= this.graphScaleInv;
         | 
| 811 812 | 
             
              ctx.lineWidth = Math.min(0.1 * this.width,ctx.lineWidth);
         | 
| 812 813 |  | 
| 813 | 
            -
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.color.background;
         | 
| 814 | 
            -
             | 
| 814 | 
            +
              ctx.fillStyle = this.selected ? this.color.highlight.background : this.hover ? this.color.hover.background : this.color.background;
         | 
| 815 815 | 
             
              ctx[shape](this.x, this.y, this.radius);
         | 
| 816 816 | 
             
              ctx.fill();
         | 
| 817 817 | 
             
              ctx.stroke();
         | 
| @@ -892,10 +892,10 @@ Node.prototype.getTextSize = function(ctx) { | |
| 892 892 | 
             
             */
         | 
| 893 893 | 
             
            Node.prototype.inArea = function() {
         | 
| 894 894 | 
             
              if (this.width !== undefined) {
         | 
| 895 | 
            -
              return (this.x + this.width*this.graphScaleInv  >= this.canvasTopLeft.x | 
| 896 | 
            -
                      this.x - this.width*this.graphScaleInv  <  this.canvasBottomRight.x &&
         | 
| 897 | 
            -
                      this.y + this.height*this.graphScaleInv | 
| 898 | 
            -
                      this.y - this.height*this.graphScaleInv | 
| 895 | 
            +
              return (this.x + this.width *this.graphScaleInv  >= this.canvasTopLeft.x     &&
         | 
| 896 | 
            +
                      this.x - this.width *this.graphScaleInv  <  this.canvasBottomRight.x &&
         | 
| 897 | 
            +
                      this.y + this.height*this.graphScaleInv  >= this.canvasTopLeft.y     &&
         | 
| 898 | 
            +
                      this.y - this.height*this.graphScaleInv  <  this.canvasBottomRight.y);
         | 
| 899 899 | 
             
              }
         | 
| 900 900 | 
             
              else {
         | 
| 901 901 | 
             
                return true;
         | 
| @@ -20,7 +20,7 @@ var HierarchicalLayoutMixin = { | |
| 20 20 | 
             
               * @private
         | 
| 21 21 | 
             
               */
         | 
| 22 22 | 
             
              _setupHierarchicalLayout : function() {
         | 
| 23 | 
            -
                if (this.constants.hierarchicalLayout.enabled == true) {
         | 
| 23 | 
            +
                if (this.constants.hierarchicalLayout.enabled == true && this.nodeIndices.length > 0) {
         | 
| 24 24 | 
             
                  if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "DU") {
         | 
| 25 25 | 
             
                    this.constants.hierarchicalLayout.levelSeparation *= -1;
         | 
| 26 26 | 
             
                  }
         | 
| @@ -65,6 +65,11 @@ var manipulationMixin = { | |
| 65 65 | 
             
                if (this.boundFunction) {
         | 
| 66 66 | 
             
                  this.off('select', this.boundFunction);
         | 
| 67 67 | 
             
                }
         | 
| 68 | 
            +
                if (this.edgeBeingEdited !== undefined) {
         | 
| 69 | 
            +
                  this.edgeBeingEdited._disableControlNodes();
         | 
| 70 | 
            +
                  this.edgeBeingEdited = undefined;
         | 
| 71 | 
            +
                  this.selectedControlNode = null;
         | 
| 72 | 
            +
                }
         | 
| 68 73 |  | 
| 69 74 | 
             
                // restore overloaded functions
         | 
| 70 75 | 
             
                this._restoreOverloadedFunctions();
         | 
| @@ -93,6 +98,12 @@ var manipulationMixin = { | |
| 93 98 | 
             
                      "<span class='graph-manipulationUI edit' id='graph-manipulate-editNode'>" +
         | 
| 94 99 | 
             
                        "<span class='graph-manipulationLabel'>"+this.constants.labels['editNode'] +"</span></span>";
         | 
| 95 100 | 
             
                  }
         | 
| 101 | 
            +
                  else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
         | 
| 102 | 
            +
                    this.manipulationDiv.innerHTML += "" +
         | 
| 103 | 
            +
                      "<div class='graph-seperatorLine'></div>" +
         | 
| 104 | 
            +
                      "<span class='graph-manipulationUI edit' id='graph-manipulate-editEdge'>" +
         | 
| 105 | 
            +
                      "<span class='graph-manipulationLabel'>"+this.constants.labels['editEdge'] +"</span></span>";
         | 
| 106 | 
            +
                  }
         | 
| 96 107 | 
             
                  if (this._selectionIsEmpty() == false) {
         | 
| 97 108 | 
             
                    this.manipulationDiv.innerHTML += "" +
         | 
| 98 109 | 
             
                      "<div class='graph-seperatorLine'></div>" +
         | 
| @@ -110,6 +121,10 @@ var manipulationMixin = { | |
| 110 121 | 
             
                    var editButton = document.getElementById("graph-manipulate-editNode");
         | 
| 111 122 | 
             
                    editButton.onclick = this._editNode.bind(this);
         | 
| 112 123 | 
             
                  }
         | 
| 124 | 
            +
                  else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
         | 
| 125 | 
            +
                    var editButton = document.getElementById("graph-manipulate-editEdge");
         | 
| 126 | 
            +
                    editButton.onclick = this._createEditEdgeToolbar.bind(this);
         | 
| 127 | 
            +
                  }
         | 
| 113 128 | 
             
                  if (this._selectionIsEmpty() == false) {
         | 
| 114 129 | 
             
                    var deleteButton = document.getElementById("graph-manipulate-delete");
         | 
| 115 130 | 
             
                    deleteButton.onclick = this._deleteSelected.bind(this);
         | 
| @@ -203,10 +218,106 @@ var manipulationMixin = { | |
| 203 218 |  | 
| 204 219 | 
             
                // redraw to show the unselect
         | 
| 205 220 | 
             
                this._redraw();
         | 
| 221 | 
            +
              },
         | 
| 206 222 |  | 
| 223 | 
            +
              /**
         | 
| 224 | 
            +
               * create the toolbar to edit edges
         | 
| 225 | 
            +
               *
         | 
| 226 | 
            +
               * @private
         | 
| 227 | 
            +
               */
         | 
| 228 | 
            +
              _createEditEdgeToolbar : function() {
         | 
| 229 | 
            +
                // clear the toolbar
         | 
| 230 | 
            +
                this._clearManipulatorBar();
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                if (this.boundFunction) {
         | 
| 233 | 
            +
                  this.off('select', this.boundFunction);
         | 
| 234 | 
            +
                }
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                this.edgeBeingEdited = this._getSelectedEdge();
         | 
| 237 | 
            +
                this.edgeBeingEdited._enableControlNodes();
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                this.manipulationDiv.innerHTML = "" +
         | 
| 240 | 
            +
                  "<span class='graph-manipulationUI back' id='graph-manipulate-back'>" +
         | 
| 241 | 
            +
                  "<span class='graph-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
         | 
| 242 | 
            +
                  "<div class='graph-seperatorLine'></div>" +
         | 
| 243 | 
            +
                  "<span class='graph-manipulationUI none' id='graph-manipulate-back'>" +
         | 
| 244 | 
            +
                  "<span id='graph-manipulatorLabel' class='graph-manipulationLabel'>" + this.constants.labels['editEdgeDescription'] + "</span></span>";
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                // bind the icon
         | 
| 247 | 
            +
                var backButton = document.getElementById("graph-manipulate-back");
         | 
| 248 | 
            +
                backButton.onclick = this._createManipulatorBar.bind(this);
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                // temporarily overload functions
         | 
| 251 | 
            +
                this.cachedFunctions["_handleTouch"]      = this._handleTouch;
         | 
| 252 | 
            +
                this.cachedFunctions["_handleOnRelease"]  = this._handleOnRelease;
         | 
| 253 | 
            +
                this.cachedFunctions["_handleTap"]        = this._handleTap;
         | 
| 254 | 
            +
                this.cachedFunctions["_handleDragStart"]  = this._handleDragStart;
         | 
| 255 | 
            +
                this.cachedFunctions["_handleOnDrag"]     = this._handleOnDrag;
         | 
| 256 | 
            +
                this._handleTouch     = this._selectControlNode;
         | 
| 257 | 
            +
                this._handleTap       = function () {};
         | 
| 258 | 
            +
                this._handleOnDrag    = this._controlNodeDrag;
         | 
| 259 | 
            +
                this._handleDragStart = function () {}
         | 
| 260 | 
            +
                this._handleOnRelease = this._releaseControlNode;
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                // redraw to show the unselect
         | 
| 263 | 
            +
                this._redraw();
         | 
| 207 264 | 
             
              },
         | 
| 208 265 |  | 
| 209 266 |  | 
| 267 | 
            +
             | 
| 268 | 
            +
             | 
| 269 | 
            +
             | 
| 270 | 
            +
              /**
         | 
| 271 | 
            +
               * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
         | 
| 272 | 
            +
               * to walk the user through the process.
         | 
| 273 | 
            +
               *
         | 
| 274 | 
            +
               * @private
         | 
| 275 | 
            +
               */
         | 
| 276 | 
            +
              _selectControlNode : function(pointer) {
         | 
| 277 | 
            +
                this.edgeBeingEdited.controlNodes.from.unselect();
         | 
| 278 | 
            +
                this.edgeBeingEdited.controlNodes.to.unselect();
         | 
| 279 | 
            +
                this.selectedControlNode = this.edgeBeingEdited._getSelectedControlNode(this._XconvertDOMtoCanvas(pointer.x),this._YconvertDOMtoCanvas(pointer.y));
         | 
| 280 | 
            +
                if (this.selectedControlNode !== null) {
         | 
| 281 | 
            +
                  this.selectedControlNode.select();
         | 
| 282 | 
            +
                  this.freezeSimulation = true;
         | 
| 283 | 
            +
                }
         | 
| 284 | 
            +
                this._redraw();
         | 
| 285 | 
            +
              },
         | 
| 286 | 
            +
             | 
| 287 | 
            +
              /**
         | 
| 288 | 
            +
               * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
         | 
| 289 | 
            +
               * to walk the user through the process.
         | 
| 290 | 
            +
               *
         | 
| 291 | 
            +
               * @private
         | 
| 292 | 
            +
               */
         | 
| 293 | 
            +
              _controlNodeDrag : function(event) {
         | 
| 294 | 
            +
                var pointer = this._getPointer(event.gesture.center);
         | 
| 295 | 
            +
                if (this.selectedControlNode !== null && this.selectedControlNode !== undefined) {
         | 
| 296 | 
            +
                  this.selectedControlNode.x = this._XconvertDOMtoCanvas(pointer.x);
         | 
| 297 | 
            +
                  this.selectedControlNode.y = this._YconvertDOMtoCanvas(pointer.y);
         | 
| 298 | 
            +
                }
         | 
| 299 | 
            +
                this._redraw();
         | 
| 300 | 
            +
              },
         | 
| 301 | 
            +
             | 
| 302 | 
            +
              _releaseControlNode : function(pointer) {
         | 
| 303 | 
            +
                var newNode = this._getNodeAt(pointer);
         | 
| 304 | 
            +
                if (newNode != null) {
         | 
| 305 | 
            +
                  if (this.edgeBeingEdited.controlNodes.from.selected == true) {
         | 
| 306 | 
            +
                    this._editEdge(newNode.id, this.edgeBeingEdited.to.id);
         | 
| 307 | 
            +
                    this.edgeBeingEdited.controlNodes.from.unselect();
         | 
| 308 | 
            +
                  }
         | 
| 309 | 
            +
                  if (this.edgeBeingEdited.controlNodes.to.selected == true) {
         | 
| 310 | 
            +
                    this._editEdge(this.edgeBeingEdited.from.id, newNode.id);
         | 
| 311 | 
            +
                    this.edgeBeingEdited.controlNodes.to.unselect();
         | 
| 312 | 
            +
                  }
         | 
| 313 | 
            +
                }
         | 
| 314 | 
            +
                else {
         | 
| 315 | 
            +
                  this.edgeBeingEdited._restoreControlNodes();
         | 
| 316 | 
            +
                }
         | 
| 317 | 
            +
                this.freezeSimulation = false;
         | 
| 318 | 
            +
                this._redraw();
         | 
| 319 | 
            +
              },
         | 
| 320 | 
            +
             | 
| 210 321 | 
             
              /**
         | 
| 211 322 | 
             
               * the function bound to the selection event. It checks if you want to connect a cluster and changes the description
         | 
| 212 323 | 
             
               * to walk the user through the process.
         | 
| @@ -351,6 +462,36 @@ var manipulationMixin = { | |
| 351 462 | 
             
                }
         | 
| 352 463 | 
             
              },
         | 
| 353 464 |  | 
| 465 | 
            +
              /**
         | 
| 466 | 
            +
               * connect two nodes with a new edge.
         | 
| 467 | 
            +
               *
         | 
| 468 | 
            +
               * @private
         | 
| 469 | 
            +
               */
         | 
| 470 | 
            +
              _editEdge : function(sourceNodeId,targetNodeId) {
         | 
| 471 | 
            +
                if (this.editMode == true) {
         | 
| 472 | 
            +
                  var defaultData = {id: this.edgeBeingEdited.id, from:sourceNodeId, to:targetNodeId};
         | 
| 473 | 
            +
                  if (this.triggerFunctions.editEdge) {
         | 
| 474 | 
            +
                    if (this.triggerFunctions.editEdge.length == 2) {
         | 
| 475 | 
            +
                      var me = this;
         | 
| 476 | 
            +
                      this.triggerFunctions.editEdge(defaultData, function(finalizedData) {
         | 
| 477 | 
            +
                        me.edgesData.update(finalizedData);
         | 
| 478 | 
            +
                        me.moving = true;
         | 
| 479 | 
            +
                        me.start();
         | 
| 480 | 
            +
                      });
         | 
| 481 | 
            +
                    }
         | 
| 482 | 
            +
                    else {
         | 
| 483 | 
            +
                      alert(this.constants.labels["linkError"]);
         | 
| 484 | 
            +
                      this.moving = true;
         | 
| 485 | 
            +
                      this.start();
         | 
| 486 | 
            +
                    }
         | 
| 487 | 
            +
                  }
         | 
| 488 | 
            +
                  else {
         | 
| 489 | 
            +
                    this.edgesData.update(defaultData);
         | 
| 490 | 
            +
                    this.moving = true;
         | 
| 491 | 
            +
                    this.start();
         | 
| 492 | 
            +
                  }
         | 
| 493 | 
            +
                }
         | 
| 494 | 
            +
              },
         | 
| 354 495 |  | 
| 355 496 | 
             
              /**
         | 
| 356 497 | 
             
               * Create the toolbar to edit the selected node. The label and the color can be changed. Other colors are derived from the chosen color.
         | 
| @@ -391,6 +532,8 @@ var manipulationMixin = { | |
| 391 532 | 
             
              },
         | 
| 392 533 |  | 
| 393 534 |  | 
| 535 | 
            +
             | 
| 536 | 
            +
             | 
| 394 537 | 
             
              /**
         | 
| 395 538 | 
             
               * delete everything in the selection
         | 
| 396 539 | 
             
               *
         |