UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

347 lines 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Vertices = void 0; const x6_geometry_1 = require("@antv/x6-geometry"); const x6_common_1 = require("@antv/x6-common"); const config_1 = require("../../config"); const view_1 = require("../../view/view"); const tool_1 = require("../../view/tool"); class Vertices extends tool_1.ToolsView.ToolItem { constructor() { super(...arguments); this.handles = []; } get vertices() { return this.cellView.cell.getVertices(); } onRender() { this.addClass(this.prefixClassName('edge-tool-vertices')); if (this.options.addable) { this.updatePath(); } this.resetHandles(); this.renderHandles(); return this; } update() { const vertices = this.vertices; if (vertices.length === this.handles.length) { this.updateHandles(); } else { this.resetHandles(); this.renderHandles(); } if (this.options.addable) { this.updatePath(); } return this; } resetHandles() { const handles = this.handles; this.handles = []; if (handles) { handles.forEach((handle) => { this.stopHandleListening(handle); handle.remove(); }); } } renderHandles() { const vertices = this.vertices; for (let i = 0, l = vertices.length; i < l; i += 1) { const vertex = vertices[i]; const createHandle = this.options.createHandle; const processHandle = this.options.processHandle; const handle = createHandle({ index: i, graph: this.graph, guard: (evt) => this.guard(evt), attrs: this.options.attrs || {}, }); if (processHandle) { processHandle(handle); } handle.updatePosition(vertex.x, vertex.y); this.stamp(handle.container); this.container.appendChild(handle.container); this.handles.push(handle); this.startHandleListening(handle); } } updateHandles() { const vertices = this.vertices; for (let i = 0, l = vertices.length; i < l; i += 1) { const vertex = vertices[i]; const handle = this.handles[i]; if (handle) { handle.updatePosition(vertex.x, vertex.y); } } } updatePath() { const connection = this.childNodes.connection; if (connection) { connection.setAttribute('d', this.cellView.getConnectionPathData()); } } startHandleListening(handle) { const edgeView = this.cellView; if (edgeView.can('vertexMovable')) { handle.on('change', this.onHandleChange, this); handle.on('changing', this.onHandleChanging, this); handle.on('changed', this.onHandleChanged, this); } if (edgeView.can('vertexDeletable')) { handle.on('remove', this.onHandleRemove, this); } } stopHandleListening(handle) { const edgeView = this.cellView; if (edgeView.can('vertexMovable')) { handle.off('change', this.onHandleChange, this); handle.off('changing', this.onHandleChanging, this); handle.off('changed', this.onHandleChanged, this); } if (edgeView.can('vertexDeletable')) { handle.off('remove', this.onHandleRemove, this); } } getNeighborPoints(index) { const edgeView = this.cellView; const vertices = this.vertices; const prev = index > 0 ? vertices[index - 1] : edgeView.sourceAnchor; const next = index < vertices.length - 1 ? vertices[index + 1] : edgeView.targetAnchor; return { prev: x6_geometry_1.Point.create(prev), next: x6_geometry_1.Point.create(next), }; } getMouseEventArgs(evt) { const e = this.normalizeEvent(evt); const { x, y } = this.graph.snapToGrid(e.clientX, e.clientY); return { e, x, y }; } onHandleChange({ e }) { this.focus(); const edgeView = this.cellView; edgeView.cell.startBatch('move-vertex', { ui: true, toolId: this.cid }); if (!this.options.stopPropagation) { const { e: evt, x, y } = this.getMouseEventArgs(e); this.eventData(evt, { start: { x, y } }); edgeView.notifyMouseDown(evt, x, y); } } onHandleChanging({ handle, e, }) { const edgeView = this.cellView; const index = handle.options.index; const { e: evt, x, y } = this.getMouseEventArgs(e); const vertex = { x, y }; this.snapVertex(vertex, index); edgeView.cell.setVertexAt(index, vertex, { ui: true, toolId: this.cid }); handle.updatePosition(vertex.x, vertex.y); if (!this.options.stopPropagation) { edgeView.notifyMouseMove(evt, x, y); } } stopBatch(vertexAdded) { this.cell.stopBatch('move-vertex', { ui: true, toolId: this.cid }); if (vertexAdded) { this.cell.stopBatch('add-vertex', { ui: true, toolId: this.cid }); } } onHandleChanged({ e }) { const options = this.options; const edgeView = this.cellView; if (options.addable) { this.updatePath(); } if (!options.removeRedundancies) { this.stopBatch(this.eventData(e).vertexAdded); return; } const verticesRemoved = edgeView.removeRedundantLinearVertices({ ui: true, toolId: this.cid, }); if (verticesRemoved) { this.render(); } this.blur(); this.stopBatch(this.eventData(e).vertexAdded); const { e: evt, x, y } = this.getMouseEventArgs(e); if (!this.options.stopPropagation) { edgeView.notifyMouseUp(evt, x, y); const { start } = this.eventData(evt); if (start) { const { x: startX, y: startY } = start; if (startX === x && startY === y) { edgeView.onClick(evt, x, y); } } } edgeView.checkMouseleave(evt); options.onChanged && options.onChanged({ edge: edgeView.cell, edgeView }); } snapVertex(vertex, index) { const snapRadius = this.options.snapRadius || 0; if (snapRadius > 0) { const neighbors = this.getNeighborPoints(index); const prev = neighbors.prev; const next = neighbors.next; if (Math.abs(vertex.x - prev.x) < snapRadius) { vertex.x = prev.x; } else if (Math.abs(vertex.x - next.x) < snapRadius) { vertex.x = next.x; } if (Math.abs(vertex.y - prev.y) < snapRadius) { vertex.y = neighbors.prev.y; } else if (Math.abs(vertex.y - next.y) < snapRadius) { vertex.y = next.y; } } } onHandleRemove({ handle, e }) { if (this.options.removable) { const index = handle.options.index; const edgeView = this.cellView; edgeView.cell.removeVertexAt(index, { ui: true }); if (this.options.addable) { this.updatePath(); } edgeView.checkMouseleave(this.normalizeEvent(e)); } } allowAddVertex(e) { const guard = this.guard(e); const addable = this.options.addable && this.cellView.can('vertexAddable'); const matchModifiers = this.options.modifiers ? x6_common_1.ModifierKey.isMatch(e, this.options.modifiers) : true; return !guard && addable && matchModifiers; } onPathMouseDown(evt) { const edgeView = this.cellView; if (!this.allowAddVertex(evt)) { return; } evt.stopPropagation(); evt.preventDefault(); const e = this.normalizeEvent(evt); const vertex = this.graph.snapToGrid(e.clientX, e.clientY).toJSON(); edgeView.cell.startBatch('add-vertex', { ui: true, toolId: this.cid }); const index = edgeView.getVertexIndex(vertex.x, vertex.y); this.snapVertex(vertex, index); edgeView.cell.insertVertex(vertex, index, { ui: true, toolId: this.cid, }); this.render(); const handle = this.handles[index]; this.eventData(e, { vertexAdded: true }); handle.onMouseDown(e); } onRemove() { this.resetHandles(); } } exports.Vertices = Vertices; (function (Vertices) { class Handle extends view_1.View { get graph() { return this.options.graph; } constructor(options) { super(); this.options = options; this.render(); this.delegateEvents({ mousedown: 'onMouseDown', touchstart: 'onMouseDown', dblclick: 'onDoubleClick', }); } render() { this.container = view_1.View.createElement('circle', true); const attrs = this.options.attrs; if (typeof attrs === 'function') { const defaults = Vertices.getDefaults(); this.setAttrs(Object.assign(Object.assign({}, defaults.attrs), attrs(this))); } else { this.setAttrs(attrs); } this.addClass(this.prefixClassName('edge-tool-vertex')); } updatePosition(x, y) { this.setAttrs({ cx: x, cy: y }); } onMouseDown(evt) { if (this.options.guard(evt)) { return; } evt.stopPropagation(); evt.preventDefault(); this.graph.view.undelegateEvents(); this.delegateDocumentEvents({ mousemove: 'onMouseMove', touchmove: 'onMouseMove', mouseup: 'onMouseUp', touchend: 'onMouseUp', touchcancel: 'onMouseUp', }, evt.data); this.emit('change', { e: evt, handle: this }); } onMouseMove(evt) { this.emit('changing', { e: evt, handle: this }); } onMouseUp(evt) { this.emit('changed', { e: evt, handle: this }); this.undelegateDocumentEvents(); this.graph.view.delegateEvents(); } onDoubleClick(evt) { this.emit('remove', { e: evt, handle: this }); } } Vertices.Handle = Handle; })(Vertices = exports.Vertices || (exports.Vertices = {})); (function (Vertices) { const pathClassName = config_1.Config.prefix('edge-tool-vertex-path'); Vertices.config({ name: 'vertices', snapRadius: 20, addable: true, removable: true, removeRedundancies: true, stopPropagation: true, attrs: { r: 6, fill: '#333', stroke: '#fff', cursor: 'move', 'stroke-width': 2, }, createHandle: (options) => new Vertices.Handle(options), markup: [ { tagName: 'path', selector: 'connection', className: pathClassName, attrs: { fill: 'none', stroke: 'transparent', 'stroke-width': 10, cursor: 'pointer', }, }, ], events: { [`mousedown .${pathClassName}`]: 'onPathMouseDown', [`touchstart .${pathClassName}`]: 'onPathMouseDown', }, }); })(Vertices = exports.Vertices || (exports.Vertices = {})); //# sourceMappingURL=vertices.js.map