JointJS + Patched Handsontable Example

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" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable/dist/handsontable.full.min.css" />
  </head>

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

    <!-- dependencies -->

    <script type="text/javascript" src="https://assets.codepen.io/7589991/handsontable-patched.js"></script>
    <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.7.5/joint.js"></script>

  </body>

</html>

CSS

.joint-highlighted {
  stroke: #0075f2;
  stroke-width: 3;
}

JavaScript

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

const HotModel = dia.Element.define('HotModel', {
  size: {
    width: 300,
    height: 0
  },
  z: 1,
  data: null,
  ports: {
    groups: {
      top: {
        z: 0,
        position: {
          name: 'line',
          args: {
            start: {
              x: 50,
              y: -15
            },
            end: {
              x: 'calc(w)',
              y: -15
            }
          }
        },
        markup: util.svg `
                    <line @selector="portLine" x1="0" y1="0" x2="0" y2="30" stroke="black" />
                    <rect @selector="portBody" magnet="true" x="-5" y="-5" width="10" height="10" stroke="black" fill="white" />
                `
      }
    }
  }
});

const HotFlags = {
  // RenderView is used to render the adaptive card inside the foreign object
  RenderView: '@render-view',
  // UpdateView is used to update the size of the foreign object
  // and the color of border
  UpdateView: '@update-view',
  // TransformView is used to position and rotate the view
  TransformView: '@transform-view',
  // MeasureView is used to measure the view and update
  // the size of the model
  MeasureView: '@measure-view'
};

const HotModelView = dia.ElementView.extend({

  // The root of the element view is the <g> element by default.
  tagName: 'g',

  // Whenever the model attributes change (the map key is the attribute name),
  // the update() method will be called, which will contain all the flags that were reported.
  presentationAttributes: {
    size: [HotFlags.UpdateView],
    position: [HotFlags.TransformView],
    angle: [HotFlags.TransformView],
    template: [HotFlags.RenderView],
    border: [HotFlags.UpdateView],
  },

  // The initFlag property is a list of flags that will be reported to the paper
  // when the element view is initialized.
  initFlag: [HotFlags.RenderView, HotFlags.UpdateView, HotFlags.TransformView, HotFlags.MeasureView],

  confirmUpdate:...