Link Anchors

by Roman Bruckner

HTML

<html>
<head>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.6.2/joint.css" />
</head>
<body>
      <!-- content -->
      <div id="paper"></div>

      <!-- dependencies -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.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.2/joint.js"></script>
    
    </body>
</html>

JavaScript

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

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

class LinkElement extends joint.dia.Element {

  defaults() {
    return {
      ...super.defaults,
      type: 'LinkElement',
      size: {
        width: 100,
        height: 50
      },
      attrs: {
        body: {
          width: 'calc(w)',
          height: 'calc(h)',
          stroke: '#333333',
          fill: '#ffffff',
        },
        title: {
          x: 'calc(w/2)',
          y: 'calc(h/2)',
          textAnchor: 'middle',
          textVerticalAnchor: 'middle',
          text: 'Google',
          fontFamily: 'sans-serif',
          fontSize: 14,
          textDecoration: 'underline',
          fill: 'blue'
        },
        anchor: {
          xlinkHref: "https://www.google.com"
        }
      }
    }
  }

  preinitialize() {
    this.markup = joint.util.svg /* xml */ `
                <rect @selector="body" />
                    <a @selector="anchor"
                        xmlns:xlink="http://www.w3.org/1999/xlink"
                        xlink:show="new"
                    >
                    <text @selector="title"></text>
                </a>
            `
  }
}

joint.shapes.LinkElement = LinkElement;

joint.shapes.LinkElementView = joint.dia.ElementView.extend({
  events: {
    'click a': 'onAnchorClick',
    'touchstart a': 'onAnchorTouchStart'
  },
  onAnchorClick: function(evt) {
    if (!evt.currentTarget.getAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
      // there is no href attribute, so the link is not valid
      // prevent the same page to be opened in a new tab
      evt.preventDefault();
    }
  },

  onAnchorTouchStart: function(evt) {
    evt.stopPropagation();
  }
});

const link1 = new LinkElement({
position: { x: 10,...