JSFiddle - React, Tailwind, and code Playground
by Yuki Moriyama
HTML
<script src="http://jointjs.com/js/vendor/jquery/jquery.min.js"></script>
<script src="http://jointjs.com/js/vendor/lodash/lodash.min.js"></script>
<script src="http://jointjs.com/js/vendor/backbone/backbone-min.js"></script>
<script src="http://jointjs.com/downloads/joint.min.js"></script>
<link rel="stylesheet" href="http://jointjs.com/downloads/joint.min.css">
<body>
<div id="paper"></div>
</body>
CSS
#paper {
position: relative;
border: 1px solid gray;
display: inline-block;
background: transparent;
overflow: hidden;
}
#paper svg {
background: transparent;
}
#paper svg .link {
z-index: 2;
}
.html-element {
position: absolute;
background: #3498DB;
/* Make sure events are propagated to the JointJS element so, e.g. dragging works.*/
pointer-events: none;
-webkit-user-select: none;
border-radius: 4px;
border: 2px solid #2980B9;
box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
padding: 5px;
box-sizing: border-box;
z-index: 2;
}
.html-element select,
.html-element input,
.html-element button {
/* Enable interacting with inputs only. */
pointer-events: auto;
}
.html-element button.delete {
color: white;
border: none;
background-color: #C0392B;
border-radius: 20px;
width: 15px;
height: 15px;
line-height: 15px;
text-align: middle;
position: absolute;
top: -15px;
left: -15px;
padding: 0;
margin: 0;
font-weight: bold;
cursor: pointer;
}
.html-element button.delete:hover {
width: 20px;
height: 20px;
line-height: 20px;
}
.html-element select {
position: absolute;
right: 2px;
bottom: 28px;
}
.html-element input {
position: absolute;
bottom: 0;
left: 0;
right: 0;
border: none;
color: #333;
padding: 5px;
height: 16px;
}
.html-element label {
color: #333;
text-shadow: 1px 0 0 lightgray;
font-weight: bold;
}
.html-element span {
position: absolute;
top: 2px;
right: 9px;
color: white;
font-size: 10px;
}
JavaScript
$(function() {
graph = new joint.dia.Graph;
paper = new joint.dia.Paper({
el: $('#paper'),
width: 800,
height: 800,
gridSize: 100,
model: graph
});
// 初期から出ているbox
var el1 = new joint.shapes.html.Element({
position: { x: 80, y: 80 },
size: { width: 170, height: 80 },
divName: 'Atrae',
isCompany: true
});
graph.addCells([el1]);
paper.on('cell:pointerup', function(cellView, evt, x, y) {
var elementBelow = graph.get('cells').find(function(cell) {
if (cell instanceof joint.dia.Link) return false;
if (cell.id === cellView.model.id) return false;
if (cell.getBBox().containsPoint(g.point(x, y))) return true;
return false;
});
if (elementBelow && !_.contains(graph.getNeighbors(elementBelow), cellView.model)) {
graph.addCell(new joint.shapes.org.Arrow({
source: { id: cellView.model.id },
target: { id: elementBelow.id }
}));
cellView.model.translate(-200, 0);
}
});
});
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'html.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
});
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element">',
'<button class="delete">x</button>',
'<input type="text" value=""/>',
'<button class="js-divName"></button>',
'<button class="add">+</button>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
this.$box.find('input').on('mousedown click', function(evt) { evt.stopPropagation();...