GitHub Discussion #2301

https://github.com/clientIO/joint/discussions/2301

by Roman Bruckner

HTML

<html>

  <head>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.6.3/joint.css" />
  </head>

  <body>
    <!-- content -->
    <div id="paper"></div>

    <!-- dependencies -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.4.0/backbone.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.6.3/joint.js"></script>

  </body>

</html>

JavaScript

const { dia, util, elementTools, shapes } = joint;

const graph = new dia.Graph({}, {
  cellNamespace: shapes
});

const paper = new dia.Paper({
  el: document.getElementById('paper'),
  width: 800,
  height: 900,
  model: graph,
  cellViewNamespace: shapes,
  gridSize: 10,
  async: true,
  sorting: dia.Paper.sorting.APPROX,
  defaultLink: () => new shapes.standard.Link()
});

// Example

const el1 = new shapes.standard.Rectangle({
  position: {
    x: 10,
    y: 10
  },
  size: {
    width: 100,
    height: 150
  }
});


const Connect = elementTools.Button.extend({
    name: 'connect',
    documentEvents: {
        mousemove: 'drag',
        touchmove: 'drag',
        mouseup: 'dragend',
        touchend: 'dragend',
        touchcancel: 'dragend',
        contextmenu: 'addVertex'
    },
    children: [{
        tagName: 'circle',
        selector: 'button',
        attributes: {
            'r': 7,
            'fill': '#333333',
            'cursor': 'pointer'
        }
    }, {
        tagName: 'path',
        selector: 'icon',
        attributes: {
            'd': 'M -4 -1 L 0 -1 L 0 -4 L 4 0 L 0 4 0 1 -4 1 z',
            'fill': '#FFFFFF',
            'stroke': 'none',
            'stroke-width': 2,
            'pointer-events': 'none'
        }
    }],
    options: {
        distance: 80,
        offset: 0,
        magnet: (view) => view.el,
        action: (evt, _view, tool) => tool.dragstart(evt),
    },
    getMagnetNode: function() {
        const { options, relatedView } = this;
        const { magnet } = options;
        let magnetNode;
        switch (typeof magnet) {
            case 'function': {
                magnetNode = magnet.call(this, relatedView, this);
                break;
            }
            case 'string': {
                [magnetNode] = relatedView.findBySelector(magnet);
                break;
            }
            default: {
                magnetNode = magnet;
                break;
            }
        }
        if...