如何为JointJS元素提供删除工具?

在JointJS中,链接带有一个方便的响应工具,用于删除链接(当您将鼠标hover在链接上时,会出现“x”,然后单击它会删除链接)。 另一方面,元素在API中有一个remove()方法,但是没有UI“x”来向用户公开该方法。

是否有一种直接的方法可以让用户删除UI中的元素?

在我的项目中,我定义了一个自定义形状 – toolElement – 它封装了这种行为,然后根据需要将其与其他自定义形状一起扩展。

完全披露:这种技术在很大程度上依赖于jointjs链接代码 – 我只是改编了它:o)

这是一个显示它工作的jsfiddle:

http://jsfiddle.net/kj4bqczd/3/

toolElement的定义如下:

 joint.shapes.tm.toolElement = joint.shapes.basic.Generic.extend({ toolMarkup: ['', '', '', 'Remove this element from the model', '', ''].join(''), defaults: joint.util.deepSupplement({ attrs: { text: { 'font-weight': 400, 'font-size': 'small', fill: 'black', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle' }, }, }, joint.shapes.basic.Generic.prototype.defaults) }); 

如果您需要其他工具以及删除按钮,可以添加更多标记。

删除行为封装在自定义视图中:

 joint.shapes.tm.ToolElementView = joint.dia.ElementView.extend({ initialize: function() { joint.dia.ElementView.prototype.initialize.apply(this, arguments); }, render: function () { joint.dia.ElementView.prototype.render.apply(this, arguments); this.renderTools(); this.update(); return this; }, renderTools: function () { var toolMarkup = this.model.toolMarkup || this.model.get('toolMarkup'); if (toolMarkup) { var nodes = V(toolMarkup); V(this.el).append(nodes); } return this; }, pointerclick: function (evt, x, y) { this._dx = x; this._dy = y; this._action = ''; var className = evt.target.parentNode.getAttribute('class'); switch (className) { case 'element-tool-remove': this.model.remove(); return; break; default: } joint.dia.CellView.prototype.pointerclick.apply(this, arguments); }, }); 

然后,您可以扩展它们以制作自定义形状。 在我的项目中,我正在做数据流图,这里是Process形状的定义:

 joint.shapes.tm.Process = joint.shapes.tm.toolElement.extend({ markup: '', defaults: joint.util.deepSupplement({ type: 'tm.Process', attrs: { '.element-process': { 'stroke-width': 1, r: 30, stroke: 'black', transform: 'translate(30, 30)' }, text: { ref: '.element-process'} }, size: { width: 100, height: 100 } }, joint.shapes.tm.toolElement.prototype.defaults) }); 

并查看:

 joint.shapes.tm.ProcessView = joint.shapes.tm.ToolElementView; 

我显示并隐藏工具标记,具体取决于元素是否使用CSS突出显示。 如果您愿意,您可以在hover时(如链接一样)执行相同的操作:

 .element .element-tools { display: none; cursor: pointer } .element.highlighted .element-tools { display: inline; } 

渲染时,它看起来像这样(注意:在我的情况下,我在工具中有另一个按钮,而不仅仅是删除 – 这是绿色的V形按钮。我从上面的代码示例中删除了它,使它们更简单):

当元素未突出显示时:

元素工具unhighlighted渲染

突出显示时:

渲染工具元素

然后我可以通过扩展toolElement来轻松定义其他形状。 以下是数据存储的数据流图形状:

在此处输入图像描述

和外部参与者:

在此处输入图像描述

看一下JointJS网站上的HTML示例 。

正如您所看到的那样,元素在那里有一个关闭按钮,所以不需要通过创建自己的元素来复杂化。 只需为元素创建一个视图,其中包含按钮的HTML代码以及事件处理。 这些都在示例的源代码中。

请注意,该示例不提供HTML元素的CSS文件,但您还需要它: http : //resources.jointjs.com/tutorials/joint/tutorials/css/html-elements.css

 joint.shapes.devs.ModelView = joint.dia.ElementView.extend(_.extend({},joint.shapes.basic.PortsViewInterface,{ initialize:function(){ joint.dia.ElementView.prototype.initialize.apply(this,arguments); }, render:function(){ joint.dia.ElementView.prototype.render.apply(this,arguments); this.renderTools(); this.update(); return this; }, renderTools:function(){ var toolMarkup = this.model.toolMarkup || this.model.get('toolMarkup'); if (toolMarkup) { var nodes = V(toolMarkup); V(this.el).append(nodes); } return this; }, pointerclick: function (evt, x, y) { var className = evt.target.parentNode.getAttribute('class'); switch (className) { case 'element-tool-remove': this.model.remove(); return; break; default: } joint.dia.CellView.prototype.pointerclick.apply(this, arguments); } 

}));