trassel
Version:
Graph computing in JavaScript
114 lines (110 loc) • 6.36 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Graph Example</title>
<script src="./trassel.iife.js"></script>
<style>
html,
body {
margin: 0;
width: 100%;
height: 100%;
}
.graph {
width: 100%;
height: 100%;
}
</style>
<script>
window.onload = () => {
/**
* A simple example of how the library can be utilized with a renderer to compute interactive graphs
*/
const nodes = [
{ id: "n0", radius: 30, mass: 1000 },
{ id: "n1", radius: 50, mass: 1000, renderer: { label: "Helloooooooooooooooooooooooooooooooo World", icon: "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 16 16'><path fill='%237c7c7c' fill-rule='evenodd' d='M6.5 0a6.5 6.5 0 0 1 5.25 10.334l3.957 3.959a1 1 0 0 1-1.414 1.414l-3.96-3.957A6.5 6.5 0 1 1 6.5 0zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z'/></svg>" } },
{ id: "n2", radius: 30, mass: 1000, renderer: { label: "Hello World", backgroundColor: 0x00AE8D, textColor: 0xFFFFFF } },
{ id: "n3", radius: 30, mass: 1000, renderer: { label: "Hello World", icon: "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 16 16'><path fill='%237c7c7c' fill-rule='evenodd' d='M6.5 0a6.5 6.5 0 0 1 5.25 10.334l3.957 3.959a1 1 0 0 1-1.414 1.414l-3.96-3.957A6.5 6.5 0 1 1 6.5 0zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z'/></svg>" } },
{ id: "n4", radius: 30, mass: 1000, renderer: { label: "Hello World" } },
{ id: "n5", radius: 30, mass: 1000, renderer: { label: "Hello World" } },
{ id: "n6", radius: 30, mass: 1000, renderer: { label: "Hello World" } },
{ id: "n7", radius: 30, mass: 1000 },
{ id: "n8", width: 200, height: 70, mass: 1000, renderer: { label: "Helloooooooooooooooooooooooooooooooooooooooooooo", shape: "rectangle", icon: "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 16 16'><path fill='%237c7c7c' fill-rule='evenodd' d='M6.5 0a6.5 6.5 0 0 1 5.25 10.334l3.957 3.959a1 1 0 0 1-1.414 1.414l-3.96-3.957A6.5 6.5 0 1 1 6.5 0zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z'/></svg>" } },
]
const edges = [
{ sourceNode: "n0", targetNode: "n1", visibleDistance: 100, renderer: { color: 0x00594E, label: "Hello World!!!!" } },
{ sourceNode: "n0", targetNode: "n2", visibleDistance: 100 },
{ sourceNode: "n1", targetNode: "n3", visibleDistance: 100 },
{ sourceNode: "n1", targetNode: "n4", visibleDistance: 100 },
{ sourceNode: "n2", targetNode: "n5", visibleDistance: 100 },
{ sourceNode: "n2", targetNode: "n6", visibleDistance: 100 },
{ sourceNode: "n6", targetNode: "n7", visibleDistance: 100 },
{ sourceNode: "n6", targetNode: "n7", visibleDistance: 100 },
{ sourceNode: "n7", targetNode: "n7", visibleDistance: 100, renderer: { isInteractive: true, color: 0x00594E, label: "Hello World!!!!" } },
{ sourceNode: "n7", targetNode: "n7", visibleDistance: 100, renderer: { color: 0x00594E, label: "Hello World!!!!" } },
{ sourceNode: "n0", targetNode: "n8", visibleDistance: 100, renderer: { isInteractive: true, color: 0x00594E, label: "Hello World!!!!" } },
]
const graph = new Trassel.Trassel(nodes, edges, { layout: { updateCap: Infinity } })
const renderer = new Trassel.Renderer(document.querySelector(".graph"), nodes, edges)
let shiftKey = false
let ctrlKey = false
let altKey = false
const keyListener = event => {
shiftKey = !!event.shiftKey
ctrlKey = !!event.ctrlKey
altKey = !!event.altKey
if (altKey) {
renderer.toggleLasso(true)
}
else {
renderer.toggleLasso(false)
}
}
window.addEventListener("keydown", keyListener)
window.addEventListener("keyup", keyListener)
renderer.on("entitydragstart", event => {
event.node.fx = event.node.x
event.node.fy = event.node.y
graph.setLayoutAlphaTarget(0.1)
graph.setLayoutAlpha(0.1)
graph.startLayoutLoop()
})
renderer.on("entitydragmove", event => {
event.node.fx = event.position.x
event.node.fy = event.position.y
})
renderer.on("entitydragend", event => {
delete event.node.fx
delete event.node.fy
graph.setLayoutAlphaTarget(0)
})
renderer.on("entityclick", event => {
if (!shiftKey) renderer.clearAllNodeSelections()
renderer.toggleSelectNode(event.node)
})
renderer.on("backdropclick", () => {
renderer.clearAllNodeSelections()
})
renderer.on("lassoupdate", event => {
[...event.added, ...event.removed].forEach(node => renderer.toggleSelectNode(node))
})
graph.addLayoutComponent("collide", new Trassel.LayoutComponents.Collision())
graph.addLayoutComponent("nbody", new Trassel.LayoutComponents.NBody())
graph.addLayoutComponent("x", new Trassel.LayoutComponents.Attraction(true))
graph.addLayoutComponent("y", new Trassel.LayoutComponents.Attraction(false))
graph.addLayoutComponent("link", new Trassel.LayoutComponents.Link())
graph.on("layoutupdate", () => {
renderer.render()
})
graph.startLayoutLoop()
document.querySelector(".graph").addEventListener("contextmenu", event => event.preventDefault())
}
</script>
</head>
<body>
<div class="graph"></div>
</body>
</html>