JointJS Link Markers

Rendering the link markers via SVGMarkers

HTML

<script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.7/joint.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.7/joint.css">
<!-- JointJS Fiddle -->
<div id="paper-container">
  <div id="paper"></div>
</div>

CSS

body {
  background: white;
  color: #3c4260;
}

#paper-container {
  overflow: scroll;
  width: 600px;
  height: 500px;
  border: 2px solid #3c4260;
}

JavaScript

// A special link view for IE to avoid marker-end bug
// https://connect.microsoft.com/IE/feedback/details/801938/dynamically-updated-svg-path-with-a-marker-end-does-not-update
var IELinkView = joint.dia.LinkView.extend({
  update: function() {
    joint.dia.LinkView.prototype.update.apply(this, arguments);
    var connectionNode = this._V.connection.node;
    connectionNode.parentNode.insertBefore(connectionNode, connectionNode);
  }
});

var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
  el: $('#paper'),
  width: 600,
  height: 500,
  model: graph,
  linkView: window.navigator.userAgent.indexOf('MSIE ') ? IELinkView : null
});


var el = new joint.shapes.basic.Generic({
  markup: '<rect/><text/>',
  size: {
    width: 100,
    height: 50
  },
  attrs: {
    rect: {
      'ref-width': '100%',
      'ref-height': '100%',
      'stroke': 'red',
      'stroke-width': 2,
      'fill': 'lightgray'
    },
    text: {
      'text': 'test',
      'fill': 'black',
      'ref-x': '50%',
      'ref-y': '50%',
      'text-anchor': 'middle',
      'y': '.3em'
    }
  },
  z: 2
});

var arrowMarkerStart = V('marker', {
  refX: -5, // distance from the element
  orient: 'auto',
  overflow: 'visible'
}, [
  V('path', {
    'd': 'M 0 -5 L 0 5',
    'stroke': 'black',
    'fill': 'none',
    'stroke-width': 1
  })
]);

var arrowMarkerEnd = V('marker', {
  refX: 5, // distance from the element
  orient: 'auto',
  overflow: 'visible'
}, [
  V('path', {
    'd': 'M 0 -5 L 0 5 M 3 -5 L 3 5',
    'stroke': 'black',
    'fill': 'none',
    'stroke-width': 1
  })
]);

V(paper.defs).append([
  arrowMarkerStart,
  arrowMarkerEnd
]);

var l = new joint.dia.Link({
  markup: '<path class="connection"/>',
  z: 1,
  attrs: {
    '.connection': {
      'stroke': 'black',
      'stroke-width': 3,
      'marker-start': 'url(#' + arrowMarkerStart.attr('id') + ')',
      'marker-end': 'url(#' + arrowMarkerEnd.attr('id') + ')'
    }
  }
});

//l.set('vertices', [{ x: 150, y: 250...