How to give JointJS elements a remove tool?

前端 未结 4 1714
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 06:53

In JointJS, links come with a handy responsive tool for removing links (when you hover over the link, an \"x\" appears, and clicking it removes the link). Elements, on the

相关标签:
4条回答
  • 2020-12-09 07:45

    A more native approach could be using the provided elementTools:

    const view = element.findView(paper);
    const removeButton = new joint.elementTools.Remove({
        focusOpacity: 0.5,
        rotate: true,
        x: '50%',
        y: '0%',
        offset: { x: 10, y: 10 }
    });
    
    const toolsView = new joint.dia.ToolsView({
        name: 'basic-tools',
        tools: [removeButton]
    });
    
    view.addTools(toolsView);
    
    0 讨论(0)
  • 2020-12-09 07:48

    Have a look at the HTML example on the JointJS website.

    As you can see the elements have a close button there, so there's no need to complicate things by creating your own. Simply create a view for your element that contains the HTML code for the button, as well as the event handling. It's all in the source code of the example.

    Note that the example doesn't provide you the CSS file for the HTML elements, but you also need it: http://resources.jointjs.com/tutorials/joint/tutorials/css/html-elements.css

    0 讨论(0)
  • 2020-12-09 07:51
    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);
    }
    

    }));

    0 讨论(0)
  • 2020-12-09 07:52

    In my project I define a custom shape - toolElement - that encapsulates this behaviour and then extend this with other custom shapes as required.

    Full disclosure: This technique leans heavily on the jointjs code for links - I just adapted it :o)

    Here is a jsfiddle showing it working:

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

    The toolElement is defined like this:

    joint.shapes.tm.toolElement = joint.shapes.basic.Generic.extend({
    
        toolMarkup: ['<g class="element-tools">',
            '<g class="element-tool-remove"><circle fill="red" r="11"/>',
            '<path transform="scale(.8) translate(-16, -16)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',
            '<title>Remove this element from the model</title>',
            '</g>',
            '</g>'].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)
    
    });
    

    You can add more markup if you need other tools as well as the remove button.

    The remove behaviour is encapsulated in a custom view:

    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);
        },
    });
    

    You can then extend these to make your custom shapes. In my project, I am doing data flow diagrams and here is the definition of the Process shape:

    joint.shapes.tm.Process = joint.shapes.tm.toolElement.extend({
    
        markup: '<g class="rotatable"><g class="scalable"><circle class="element-process"/><title class="tooltip"/></g><text/></g>',
    
        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)
    });
    

    and view:

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

    I show and hide the tool markup, depending whether the element is highlighted using CSS. You could do the same when hovering (like the links do) if you like:

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

    When rendered, it looks like this (note: in my case, I have another button in the tools, not just the remove - that is what the green chevron button is. I removed this from the code samples above to make them simpler):

    When the element is not highlighted:

    element tool unhighlighted render

    When it is highlighted:

    rendering of the tool element

    I can then define other shapes really easily by extending toolElement. Here are the data flow diagram shapes for data stores:

    enter image description here

    and external actors:

    enter image description here

    0 讨论(0)
提交回复
热议问题