JointJS Link Performance Tip

Fast JointJS view for links

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"></div>

CSS

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

#paper {
  display: inline-block;
  border: 2px solid #3c4260;
}

JavaScript

// Super fast (non-interactive) view for JointJS links
joint.dia.LightLinkView = joint.dia.CellView.extend({

  node: V('<path class="connection" fill="none" />'),

  init: function() {
    this.vel.attr({
      'class': 'link',
      'model-id': this.model.id
    });
  },

  render: function() {

    var model = this.model;
    this._sourceModel = model.getSourceElement();
    this._targetModel = model.getTargetElement();

    this._sourceModel.on('change:position', this.update, this);
    this._targetModel.on('change:position', this.update, this);

    this.listenTo(model, 'change:vertices change:color change:thickness', this.update);

    var node = this._pathNode = this.node.clone();
    V(this.el).append(node);

    this.update();
  },

  update: function() {

    var sourcePosition = this._sourceModel.get('position');
    var targetPosition = this._targetModel.get('position');
    var node = this._pathNode;
    var model = this.model;

    if (sourcePosition && targetPosition) {

      var sourceSize = this._sourceModel.get('size');
      var targetSize = this._targetModel.get('size');

      sourcePosition = {
        x: sourcePosition.x + sourceSize.width / 2,
        y: sourcePosition.y + sourceSize.height / 2
      };
      targetPosition = {
        x: targetPosition.x + targetSize.width / 2,
        y: targetPosition.y + targetSize.height / 2
      };

      var connector = (model.get('smooth')) ? 'smooth' : 'normal';

      node.attr('d', joint.connectors[connector](
        sourcePosition,
        targetPosition,
        model.get('vertices') || []
      ));
    }

    node.attr({
      'stroke': model.get('color') || 'black',
      'stroke-width': model.get('thickness') || 1
    });
  }
});



var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
  el: $('#paper'),
  width: 600,
  height: 500,
  gridSize: 20,
  model: graph,
  // tell paper to use our custom link view for all links
  linkView: joint.dia.LightLinkView
});

var model =...