<label id="message">message</label>
<div id="canvas" data-filter="all"></div>
<button id="addCell">Add Node</button>
body {
  font-family: sans-serif;
  font-size: 20px;
}

#message {
  opacity: 0;
  transition: opacity 5s linear;
  
  &.visible {
    opacity: 1;
    transition: opacity 0.1s linear;
  }
}

#canvas {
  border: 1px solid;
  width: 100%;
  height: 35vh;
  min-height: 300px;
  
}
.element-node {
  fill: #f1207d;
  
  text {
      fill: #FFFFFF;
    }
  
  &:hover .port {
      opacity: 1;
    }
}

.port {
  width: 10px;
  height: 10px;
  transform: translate(70px, 40px);
  fill: #000;
  opacity: 0.5;
}

button {
  color: #FFFFFF;
  background-color: #f1207d;
  border-radius: 3px;
  border: 0;
  padding: 10px 20px;
  margin: 5px 0;
  cursor: pointer;
}
View Compiled
joint.shapes.devs.Model = joint.shapes.devs.Model.extend({
markup: '<g class="element-node">'+
             '<rect class="body" stroke-width="0" rx="5px" ry="5px"></rect>'+
            '<text class="label" y="0.8em" xml:space="preserve" font-size="14" text-anchor="middle" font-family="Arial, helvetica, sans-serif">'+
              '<tspan id="v-18" dy="0em" x="0" class="v-line"></tspan>'+
            '</text>'+
          '<g class="inPorts"/>' +
          '<g class="outPorts"/>' +
        '</g>',
portMarkup: '<g class="port port<%= id %>"><circle class="port-body"/></g>'
});
  
var canvas = $('#canvas');
var cells = [];
var message = $('#message');
var graph = new joint.dia.Graph();

var paper = new joint.dia.Paper({
  el: canvas,
  width: canvas.outerWidth(),
  height: canvas.outerHeight(),
  model: graph,
  gridSize: 20,
  defaultRouter: { name: 'metro' },
  clickThreshold: 1
});

cells[0] = new joint.shapes.devs.Model({
  type: 'devs.Model',
  position: {x: 20, y: 20},
  attrs: {
    '.body': {
      width: '140',
      height: '60'
    },
    '.label': {
      text: 'blok 1',
    },
    '.element-node' : {
      'data-color': 'pink'
    }
  },
  inPorts: ['center']
});
cells[0].translate(140, 100);
cells[1] = cells[0].clone();
cells[1].translate(300, 60);
cells[1].attr('.label/text', 'blok 2');
graph.addCells(cells);

var link = new joint.dia.Link({
  source: {
    id: cells[0].id,
    port: 'center'
  },
  target: {
    id: cells[1].id,
    port: 'center'
  }
});
graph.addCells([link]);

function addCell(){
  var number = cells.length;
  cells[number] = cells[0].clone();
  cells[number].translate(-140, -100);
  cells[number].attr('.label/text', 'blok '+cells.length);
  graph.addCells(cells);
}

$('#addCell').on('click', addCell);

(function(){
  paper.on('cell:pointerclick', function(e){
    message.addClass('visible');
    message.html(e.el.textContent+' clicked');
  setTimeout(function(){  message.removeClass('visible');
                       }, 1000);
  });
})();
Run Pen

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.9/joint.core.css

External JavaScript

  1. https://ariutta.github.io/svg-pan-zoom/dist/svg-pan-zoom.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js
  4. https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js
  5. https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.7/joint.js