123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- var Node = require('./components/Node').default;
- var Edge = require('./components/Edge').default;
- let util = require('../../util');
- class SelectionHandler {
-
- constructor(body, canvas) {
- this.body = body;
- this.canvas = canvas;
- this.selectionObj = {nodes: [], edges: []};
- this.hoverObj = {nodes:{},edges:{}};
- this.options = {};
- this.defaultOptions = {
- multiselect: false,
- selectable: true,
- selectConnectedEdges: true,
- hoverConnectedEdges: true
- };
- util.extend(this.options, this.defaultOptions);
- this.body.emitter.on("_dataChanged", () => {
- this.updateSelection()
- });
- }
-
- setOptions(options) {
- if (options !== undefined) {
- let fields = ['multiselect','hoverConnectedEdges','selectable','selectConnectedEdges'];
- util.selectiveDeepExtend(fields,this.options, options);
- }
- }
-
- selectOnPoint(pointer) {
- let selected = false;
- if (this.options.selectable === true) {
- let obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);
-
- this.unselectAll();
- if (obj !== undefined) {
- selected = this.selectObject(obj);
- }
- this.body.emitter.emit("_requestRedraw");
- }
- return selected;
- }
-
- selectAdditionalOnPoint(pointer) {
- let selectionChanged = false;
- if (this.options.selectable === true) {
- let obj = this.getNodeAt(pointer) || this.getEdgeAt(pointer);
- if (obj !== undefined) {
- selectionChanged = true;
- if (obj.isSelected() === true) {
- this.deselectObject(obj);
- }
- else {
- this.selectObject(obj);
- }
- this.body.emitter.emit("_requestRedraw");
- }
- }
- return selectionChanged;
- }
-
- _initBaseEvent(event, pointer) {
- let properties = {};
- properties['pointer'] = {
- DOM: {x: pointer.x, y: pointer.y},
- canvas: this.canvas.DOMtoCanvas(pointer)
- };
- properties['event'] = event;
- return properties;
- }
-
- _generateClickEvent(eventType, event, pointer, oldSelection, emptySelection = false) {
- let properties = this._initBaseEvent(event, pointer);
- if (emptySelection === true) {
- properties.nodes = [];
- properties.edges = [];
- }
- else {
- let tmp = this.getSelection();
- properties.nodes = tmp.nodes;
- properties.edges = tmp.edges;
- }
- if (oldSelection !== undefined) {
- properties['previousSelection'] = oldSelection;
- }
- if (eventType == 'click') {
-
-
- properties.items = this.getClickedItems(pointer);
- }
- this.body.emitter.emit(eventType, properties);
- }
-
- selectObject(obj, highlightEdges = this.options.selectConnectedEdges) {
- if (obj !== undefined) {
- if (obj instanceof Node) {
- if (highlightEdges === true) {
- this._selectConnectedEdges(obj);
- }
- }
- obj.select();
- this._addToSelection(obj);
- return true;
- }
- return false;
- }
-
- deselectObject(obj) {
- if (obj.isSelected() === true) {
- obj.selected = false;
- this._removeFromSelection(obj);
- }
- }
-
- _getAllNodesOverlappingWith(object) {
- let overlappingNodes = [];
- let nodes = this.body.nodes;
- for (let i = 0; i < this.body.nodeIndices.length; i++) {
- let nodeId = this.body.nodeIndices[i];
- if (nodes[nodeId].isOverlappingWith(object)) {
- overlappingNodes.push(nodeId);
- }
- }
- return overlappingNodes;
- }
-
- _pointerToPositionObject(pointer) {
- let canvasPos = this.canvas.DOMtoCanvas(pointer);
- return {
- left: canvasPos.x - 1,
- top: canvasPos.y + 1,
- right: canvasPos.x + 1,
- bottom: canvasPos.y - 1
- };
- }
-
- getNodeAt(pointer, returnNode = true) {
-
- let positionObject = this._pointerToPositionObject(pointer);
- let overlappingNodes = this._getAllNodesOverlappingWith(positionObject);
-
-
- if (overlappingNodes.length > 0) {
- if (returnNode === true) {
- return this.body.nodes[overlappingNodes[overlappingNodes.length - 1]];
- }
- else {
- return overlappingNodes[overlappingNodes.length - 1];
- }
- }
- else {
- return undefined;
- }
- }
-
- _getEdgesOverlappingWith(object, overlappingEdges) {
- let edges = this.body.edges;
- for (let i = 0; i < this.body.edgeIndices.length; i++) {
- let edgeId = this.body.edgeIndices[i];
- if (edges[edgeId].isOverlappingWith(object)) {
- overlappingEdges.push(edgeId);
- }
- }
- }
-
- _getAllEdgesOverlappingWith(object) {
- let overlappingEdges = [];
- this._getEdgesOverlappingWith(object,overlappingEdges);
- return overlappingEdges;
- }
-
- getEdgeAt(pointer, returnEdge = true) {
-
- var canvasPos = this.canvas.DOMtoCanvas(pointer);
- var mindist = 10;
- var overlappingEdge = null;
- var edges = this.body.edges;
- for (var i = 0; i < this.body.edgeIndices.length; i++) {
- var edgeId = this.body.edgeIndices[i];
- var edge = edges[edgeId];
- if (edge.connected) {
- var xFrom = edge.from.x;
- var yFrom = edge.from.y;
- var xTo = edge.to.x;
- var yTo = edge.to.y;
- var dist = edge.edgeType.getDistanceToEdge(xFrom, yFrom, xTo, yTo, canvasPos.x, canvasPos.y);
- if(dist < mindist){
- overlappingEdge = edgeId;
- mindist = dist;
- }
- }
- }
- if (overlappingEdge !== null) {
- if (returnEdge === true) {
- return this.body.edges[overlappingEdge];
- }
- else {
- return overlappingEdge;
- }
- }
- else {
- return undefined;
- }
- }
-
- _addToSelection(obj) {
- if (obj instanceof Node) {
- this.selectionObj.nodes[obj.id] = obj;
- }
- else {
- this.selectionObj.edges[obj.id] = obj;
- }
- }
-
- _addToHover(obj) {
- if (obj instanceof Node) {
- this.hoverObj.nodes[obj.id] = obj;
- }
- else {
- this.hoverObj.edges[obj.id] = obj;
- }
- }
-
- _removeFromSelection(obj) {
- if (obj instanceof Node) {
- delete this.selectionObj.nodes[obj.id];
- this._unselectConnectedEdges(obj);
- }
- else {
- delete this.selectionObj.edges[obj.id];
- }
- }
-
- unselectAll() {
- for(let nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- this.selectionObj.nodes[nodeId].unselect();
- }
- }
- for(let edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- this.selectionObj.edges[edgeId].unselect();
- }
- }
- this.selectionObj = {nodes:{},edges:{}};
- }
-
- _getSelectedNodeCount() {
- let count = 0;
- for (let nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- count += 1;
- }
- }
- return count;
- }
-
- _getSelectedNode() {
- for (let nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- return this.selectionObj.nodes[nodeId];
- }
- }
- return undefined;
- }
-
- _getSelectedEdge() {
- for (let edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- return this.selectionObj.edges[edgeId];
- }
- }
- return undefined;
- }
-
- _getSelectedEdgeCount() {
- let count = 0;
- for (let edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- count += 1;
- }
- }
- return count;
- }
-
- _getSelectedObjectCount() {
- let count = 0;
- for(let nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- count += 1;
- }
- }
- for(let edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- count += 1;
- }
- }
- return count;
- }
-
- _selectionIsEmpty() {
- for(let nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- return false;
- }
- }
- for(let edgeId in this.selectionObj.edges) {
- if(this.selectionObj.edges.hasOwnProperty(edgeId)) {
- return false;
- }
- }
- return true;
- }
-
- _clusterInSelection() {
- for(let nodeId in this.selectionObj.nodes) {
- if(this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- if (this.selectionObj.nodes[nodeId].clusterSize > 1) {
- return true;
- }
- }
- }
- return false;
- }
-
- _selectConnectedEdges(node) {
- for (let i = 0; i < node.edges.length; i++) {
- let edge = node.edges[i];
- edge.select();
- this._addToSelection(edge);
- }
- }
-
- _hoverConnectedEdges(node) {
- for (let i = 0; i < node.edges.length; i++) {
- let edge = node.edges[i];
- edge.hover = true;
- this._addToHover(edge);
- }
- }
-
- _unselectConnectedEdges(node) {
- for (let i = 0; i < node.edges.length; i++) {
- let edge = node.edges[i];
- edge.unselect();
- this._removeFromSelection(edge);
- }
- }
-
- emitBlurEvent(event, pointer, object) {
- let properties = this._initBaseEvent(event, pointer);
- if (object.hover === true) {
- object.hover = false;
- if (object instanceof Node) {
- properties.node = object.id;
- this.body.emitter.emit("blurNode", properties);
- }
- else {
- properties.edge = object.id;
- this.body.emitter.emit("blurEdge", properties);
- }
- }
- }
-
- emitHoverEvent(event, pointer, object) {
- let properties = this._initBaseEvent(event, pointer);
- let hoverChanged = false;
- if (object.hover === false) {
- object.hover = true;
- this._addToHover(object);
- hoverChanged = true;
- if (object instanceof Node) {
- properties.node = object.id;
- this.body.emitter.emit("hoverNode", properties);
- }
- else {
- properties.edge = object.id;
- this.body.emitter.emit("hoverEdge", properties);
- }
- }
- return hoverChanged;
- }
-
- hoverObject(event, pointer) {
- let object = this.getNodeAt(pointer);
- if (object === undefined) {
- object = this.getEdgeAt(pointer);
- }
- let hoverChanged = false;
-
- for (let nodeId in this.hoverObj.nodes) {
- if (this.hoverObj.nodes.hasOwnProperty(nodeId)) {
- if (object === undefined || (object instanceof Node && object.id != nodeId) || object instanceof Edge) {
- this.emitBlurEvent(event, pointer, this.hoverObj.nodes[nodeId]);
- delete this.hoverObj.nodes[nodeId];
- hoverChanged = true;
- }
- }
- }
-
- for (let edgeId in this.hoverObj.edges) {
- if (this.hoverObj.edges.hasOwnProperty(edgeId)) {
-
-
- if (hoverChanged === true) {
- this.hoverObj.edges[edgeId].hover = false;
- delete this.hoverObj.edges[edgeId];
- }
-
-
- else if (object === undefined || (object instanceof Edge && object.id != edgeId) || (object instanceof Node && !object.hover)) {
- this.emitBlurEvent(event, pointer, this.hoverObj.edges[edgeId]);
- delete this.hoverObj.edges[edgeId];
- hoverChanged = true;
- }
- }
- }
- if (object !== undefined) {
- hoverChanged = hoverChanged || this.emitHoverEvent(event, pointer, object);
- if (object instanceof Node && this.options.hoverConnectedEdges === true) {
- this._hoverConnectedEdges(object);
- }
- }
- if (hoverChanged === true) {
- this.body.emitter.emit('_requestRedraw');
- }
- }
-
- getSelection() {
- let nodeIds = this.getSelectedNodes();
- let edgeIds = this.getSelectedEdges();
- return {nodes:nodeIds, edges:edgeIds};
- }
-
- getSelectedNodes() {
- let idArray = [];
- if (this.options.selectable === true) {
- for (let nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- idArray.push(this.selectionObj.nodes[nodeId].id);
- }
- }
- }
- return idArray;
- }
-
- getSelectedEdges() {
- let idArray = [];
- if (this.options.selectable === true) {
- for (let edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- idArray.push(this.selectionObj.edges[edgeId].id);
- }
- }
- }
- return idArray;
- }
-
- setSelection(selection, options = {}) {
- let i, id;
- if (!selection || (!selection.nodes && !selection.edges))
- throw 'Selection must be an object with nodes and/or edges properties';
-
- if (options.unselectAll || options.unselectAll === undefined) {
- this.unselectAll();
- }
- if (selection.nodes) {
- for (i = 0; i < selection.nodes.length; i++) {
- id = selection.nodes[i];
- let node = this.body.nodes[id];
- if (!node) {
- throw new RangeError('Node with id "' + id + '" not found');
- }
-
- this.selectObject(node, options.highlightEdges);
- }
- }
- if (selection.edges) {
- for (i = 0; i < selection.edges.length; i++) {
- id = selection.edges[i];
- let edge = this.body.edges[id];
- if (!edge) {
- throw new RangeError('Edge with id "' + id + '" not found');
- }
- this.selectObject(edge);
- }
- }
- this.body.emitter.emit('_requestRedraw');
- }
-
- selectNodes(selection, highlightEdges = true) {
- if (!selection || (selection.length === undefined))
- throw 'Selection must be an array with ids';
- this.setSelection({nodes: selection}, {highlightEdges: highlightEdges});
- }
-
- selectEdges(selection) {
- if (!selection || (selection.length === undefined))
- throw 'Selection must be an array with ids';
- this.setSelection({edges: selection});
- }
-
- updateSelection() {
- for (let nodeId in this.selectionObj.nodes) {
- if (this.selectionObj.nodes.hasOwnProperty(nodeId)) {
- if (!this.body.nodes.hasOwnProperty(nodeId)) {
- delete this.selectionObj.nodes[nodeId];
- }
- }
- }
- for (let edgeId in this.selectionObj.edges) {
- if (this.selectionObj.edges.hasOwnProperty(edgeId)) {
- if (!this.body.edges.hasOwnProperty(edgeId)) {
- delete this.selectionObj.edges[edgeId];
- }
- }
- }
- }
-
-
- getClickedItems(pointer) {
- let point = this.canvas.DOMtoCanvas(pointer);
- var items = [];
-
-
- let nodeIndices = this.body.nodeIndices;
- let nodes = this.body.nodes;
- for (let i = nodeIndices.length - 1; i >= 0; i--) {
- let node = nodes[nodeIndices[i]];
- let ret = node.getItemsOnPoint(point);
- items.push.apply(items, ret);
- }
- let edgeIndices = this.body.edgeIndices;
- let edges = this.body.edges;
- for (let i = edgeIndices.length - 1; i >= 0; i--) {
- let edge = edges[edgeIndices[i]];
- let ret = edge.getItemsOnPoint(point);
- items.push.apply(items, ret);
- }
- return items;
- }
- }
- export default SelectionHandler;
|