Joint JS Plus demo with custom HTML and Navigator
by Roman Bruckner
HTML
<link rel="stylesheet" href="https://resources.jointjs.com/docs/rappid/v3.6/css/lib/rappid.min.css">
<script src="https://resources.jointjs.com/docs/rappid/v3.6/js/lib/lodash.min.js"></script>
<script src="https://resources.jointjs.com/docs/rappid/v3.6/js/lib/backbone.min.js"></script>
<script src="https://resources.jointjs.com/docs/rappid/v3.6/js/lib/lodash.min.js"></script>
<script src="https://resources.jointjs.com/docs/rappid/v3.6/js/lib/rappid.min.js"></script>
<div id="paper"></div>
<div class="toolbar">
<span id="zoom-out" class="toolbar-button">Zoom Out</span>
<span id="zoom-in" class="toolbar-button">Zoom In</span>
<span id="reset" class="toolbar-button">Reset</span>
</div>
<div id="navigator"></div>
CSS
html, body {
margin: 0;
padding: 0;
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
overflow-y: hidden;
}
#paper {
border: 1px solid #E2E2E2;
background-color: #F3F7F6;
position: absolute;
inset: 0;
}
#navigator {
right: 0;
position: absolute;
}
/* JointJS HTML Element */
.html-element {
box-sizing: border-box;
font-family: sans-serif;
box-shadow: 4px 4px 4px -1px rgba(0,0,0,0.18);
padding: 8px 16px;
background-color: #FCFCFC;
}
.html-element:after {
content: ' ';
background: #6C6C6C;
height: 8px;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.html-element:before {
content: ' ';
position: absolute;
top: 24px;
right: 16px;
width: 20px;
height: 20px;
background-position: 50% 50%;
background-repeat: no-repeat;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMTEuOTkgMkM2LjQ3IDIgMiA2LjQ4IDIgMTJzNC40NyAxMCA5Ljk5IDEwQzE3LjUyIDIyIDIyIDE3LjUyIDIyIDEyUzE3LjUyIDIgMTEuOTkgMnpNMTIgMjBjLTQuNDIgMC04LTMuNTgtOC04czMuNTgtOCA4LTggOCAzLjU4IDggOC0zLjU4IDgtOCA4em0uNS0xM0gxMXY2bDUuMjUgMy4xNS43NS0xLjIzLTQuNS0yLjY3eiIvPjwvc3ZnPg==);
}
.html-element[data-state="done"]:after {
background:#4666E5;
}
.html-element[data-state="done"]:before {
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMTIgMkM2LjQ4IDIgMiA2LjQ4IDIgMTJzNC40OCAxMCAxMCAxMCAxMC00LjQ4IDEwLTEwUzE3LjUyIDIgMTIgMnptMCAxOGMtNC40MSAwLTgtMy41OS04LThzMy41OS04IDgtOCA4IDMuNTkgOCA4LTMuNTkgOC04IDh6bTQuNTktMTIuNDJMMTAgMTQuMTdsLTIuNTktMi41OEw2IDEzbDQgNCA4LTh6Ii8+PC9zdmc+);
}
.html-element[data-state="at-risk"]:after...
JavaScript
(function(joint, util, V) {
var Element = joint.dia.Element;
var ElementView = joint.dia.ElementView;
Element.define('html.Element', {
size: {
width: 250,
height: 228
},
ports: { // added ports
groups: {
inPorts: {
position: {
name: 'top'
},
attrs: {
text: {
fill: '#000000'
},
circle: {
fill: '#00ff00',
stroke: '#000000',
magnet: true
}
},
z: 0
},
outPorts: {
attrs: {
text: {
fill: '#000000'
},
circle: {
fill: '#ff0000',
stroke: '#000000',
magnet: true
}
},
position: 'bottom',
label: {
position: 'outside'
},
z: 0
}
},
items: [{
id: 'in',
group: 'inPorts',
//attrs: { text: { text: 'in1' }}
},
{
id: 'out',
group: 'outPorts',
//attrs: { text: { text: 'out' }}
}
]
},
fields: {
header: 'Task',
name: '',
resource: '',
state: ''
},
attrs: {
placeholder: {
width: 'calc(w)',
height: 'calc(h)',
fill: 'transparent',
stroke: '#D4D4D4'
}
}
...