JSFiddle - React, Tailwind, and code Playground
by Roman Bruckner
HTML
<!DOCTYPE html>
<html>
<head>
<meta name=viewport content="width=device-width,initial-scale=1">
<meta name=description content="JointJS Chatbot Design">
<link rel="icon" href="/favicon.ico">
<link rel="stylesheet" href="style.css">
<title>JointJS Chatbot Design</title>
</head>
<body>
<noscript>
<strong>This application doesn't work without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div class="row">
<div class="column middle" id="diagram" onLoad = "svgLoaded();"></div>
<div class="column right" id="element">
<h2>Element</h2>
<form>
<label for="elem-label">Label</label>
<input id="elem-label" type="text" size="20"><br />
<label for="elem-id">ID</label>
<input id="elem-id" type="text" size="40"><br />
<label id="link-from-label" for="link-from-field">From</label>
<input id="link-from-field" type="text" size="20"><br />
<label id="link-to-label" for="link-to-field">To</label>
<input id="link-to-field" type="text" size="20"><br />
</form>
</div>
</div>
<!-- dependencies -->
<script src="https://unpkg.com/@joint/[email protected]/dist/joint.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/graphlib.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/dagre.min.js"></script>
<script src="https://unpkg.com/@joint/[email protected]/dist/DirectedGraph.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/svg-pan-zoom.min.js"></script>
<!-- code -->
<script src="diagram_fiddle.js"></script>
</body>
</html>
CSS
* {
box-sizing: border-box;
}
.column {
float: left;
padding: 10px;
}
.left, .right {
width: 10%;
}
.row:after {
content: "";
display: table;
clear: both;
}
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -60px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip .tooltiptext::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent transparent;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
JavaScript
var namespace = joint.shapes;
var defaults = {
router: 'normal',
connector: 'straight',
corner: { cornerType: 'cubic', precision: 0, cornerRadius: 20 },
body: { fill: 'white', stroke: 'black', highlight: 'orange' },
line: { fill: 'black', stroke: 'black', highlight: 'orange' },
label: { fill: 'black' }
};
var graph = new joint.dia.Graph({}, { cellNamespace: namespace });
var paper = new joint.dia.Paper({
el: document.getElementById('diagram'),
model: graph,
width: screen.width/4,
height: screen.height/2,
cellViewNamespace: namespace,
gridSize: 10,
drawGrid: true,
background: { color: 'rgba(240, 240, 240, 0.3)' },
defaultLink: () => {
let new_link = new joint.shapes.standard.Link({ attrs: { wrapper: { cursor: 'default' } } });
new_link.router(defaults.router);
new_link.connector(defaults.connector, defaults.corner);
return new_link;
},
linkPinning: false,
defaultConnectionPoint: { name: 'boundary' },
validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
// Prevent linking to anything that isn't a box
if (cellViewT.model.attributes.type !== 'standard.Rectangle')
return false;
// Prevent linking to output ports
if (magnetT && magnetT.getAttribute('port-group') === 'out')
return false;
return true;
}
});
function bindInteractionEvents(graph, paper)
{
paper.on('blank:pointerdown', function() {
panZoom?.enablePan();
});
paper.on('blank:pointerup', function() {
panZoom?.disablePan();
});
}
function constructElements(graph)
{
var rect = new joint.shapes.standard.Rectangle();
rect.position(100, 30);
rect.resize(100, 40);
rect.attr({
body: {
fill: 'blue'
},
label: {
text: 'Hello',
fill: 'white'
}
});
...