Skip to main content

Hello World

JsPlumb would not be a real piece of software without a Hello World example. Here we present a basic Hello World application written in various JsPlumb flavours, demonstrating:

  • Usage of a view to map node types to templates and events
  • Usage of render params to configure a surface
  • How to specify an edge label (in shorthand) and color
  • How to specify an edge overlay

This app is available on Github at https://github.com/jsplumb-demonstrations/hello-world

Code

Vanilla JS
React
Angular
Vue
Svelte

Our vanilla JS Hello World is written in ES6. We use this simple HTML file:

<html>
<head>
<script src="node_modules/@jsplumbtoolkit/browser-ui/js/jsplumbtoolkit.browser-ui.umd.js"></script>
<link rel="stylesheet" href="node_modules/@jsplumbtoolkit/browser-ui/css/jsplumbtoolkit.css">
<link rel="stylesheet" href="app.css">
</head>
<body>

<div id="container" style="width:600px;height:600px;outline:1px solid;"></div>

<script type="module" src="app.js"></script>

</body>

</html>

To visualise the contents of a JsPlumb instance, it needs to be rendered. To do that, JsPlumb needs 3 pieces of information:

  • container Which DOM element should JsPlumb render into?
  • view How should JsPlumb map nodes/groups/edges to their visual representations?
  • renderParams What configuration should JsPlumb apply to the surface that is rendering your content?

import { ready, newInstance, AbsoluteLayout, BlankEndpoint,
AnchorLocations, ArrowOverlay, DEFAULT } from "@jsplumbtoolkit/browser-ui"

ready(() => {

// Get a new Toolkit instance
const toolkit = newInstance()

// Get the DOM element to render into
const container = document.getElementById("container")

// Render to a Surface.
const surface = toolkit.render(container, {
layout:{
// there are several layouts that ship with JsPlumb.
type:AbsoluteLayout.type,
options:{
//... if your chosen layout is configurable, options go here
}
},
// Allows us to specify edge color (and line width) in each edge's backing data
simpleEdgeStyles:true,
// Use a Continuous anchor and a blank endpoint by default.
defaults:{
anchor:AnchorLocations.Continuous,
endpoint:BlankEndpoint.type
},
// map node types and edge types to appearance and behaviour
view:{
nodes:{
// abstract parent node definition - declares a tap listener
clickable:{
events:{
tap:(p) => alert(`You clicked on node ${p.obj.id}`)
}
},
// definition for 'hello' nodes. Extends 'clickable' to get the tap listener.
hello:{
parent:"clickable",
template:'<div class="hello-node">{{label}}</div>'
},
// definition for 'world' nodes. Extends 'clickable' to get the tap listener.
world:{
parent:"clickable",
template:'<div class="world-node">{{label}}</div>'
}
},
edges:{
// a default edge definition. Declares an arrow overlay at its tip and extracts 'label' from
// edge data and displays it as a label overlay (by default at location 0.5)
[DEFAULT]:{
overlays:[
{
type:ArrowOverlay.type,
options:{
location: 1
}
}
],
label:"{{label}}"
}
}
}
})
})

CSS

Our CSS for this demo is straightforward. Keep in mind that we also included the jsplumbtoolkit.css stylesheet, which contains sane defaults for the basic styles JsPlumb uses. At first you'll want to keep this stylesheet in your cascade, but over time you may find you arrive at a place where you no longer need it.


.jtk-node {
outline:1px solid;
padding:3px;
display:flex;
align-items:center;
justify-content:center;
}

.hello-node {
width:100px;
height:80px;
background-color:white;
}

.world-node {
width:80px;
height:80px;
border-radius:50%;
background-color:purple;
color:white;
font-weight:bold;
}