<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>PIXI ForceLayout</title> <link rel="stylesheet" href="../3rdparty/highlight/styles/default.css" /> <link rel="stylesheet" href="../../css/doctest.css" /> <script src="../3rdparty/highlight/highlight.pack.js"></script> <script src="../../dist/iwmlib.3rdparty.js"></script> <script src="../../dist/iwmlib.js"></script> <script src="../../dist/iwmlib.pixi.js"></script> <script src="./lib/graphology.min.js"></script> <script src="./lib/graphology-layout-forceatlas2.js"></script> </head> <body onload="Doctest.run()"> <h1><a href="../index.html">lib.</a><a href="index.html">pixi.</a>ForceLayout</h1> <p> Comparison of a <a href="https://github.com/d3/d3-force/blob/master/README.md">D3 ForceLayout</a> with a <a href="https://github.com/graphology/graphology-layout-forceatlas2">ForceAtlas 2</a> forcelayout. </p> <h2>Let's look at the D3 ForceLayout:</h2> <br /> <canvas id="canvas" class="interactive"></canvas> <script class="doctest"> const app = new PIXIApp({ view: canvas, width: 900, height: 420, transparent: false }) .setup() .run() app.loadTextures( ['./assets/circle.png'], (textures) => { // add sprites //-------------------- const sprites = [] for (let i = 0; i < 100; i++) { const sprite = new PIXI.Sprite(textures.get('./assets/circle.png')) sprite.x = randomInt(0, app.size.width) sprite.y = randomInt(0, app.size.height) sprite.width = sprite.height = 2 sprite.anchor.set(0.5, 0.5) sprite.__random = Math.random() sprites.push(sprite) } app.scene.addChild(...sprites) // force simulation //-------------------- const forceCollide = d3.forceCollide().radius((d) => d.width / 2 + 1) const simulation = d3 .forceSimulation(sprites) .on('tick', () => { //forceCollide.radius(d => d.radius) }) .force('collide', forceCollide) .force('x', d3.forceX(app.center.x)) .force('y', d3.forceY(app.center.y)) .stop() .force( 'radial', d3.forceRadial( (d) => { return d.__random < 0.5 ? 60 : 160 }, app.center.x, app.center.y ) ) d3.timeout(() => { simulation.restart() }, 500) }, { resolutionDependent: false } ) </script> <h2>D3 ForceLayout with links:</h2> <br /> <canvas id="canvas2" class="interactive"></canvas> <script class="doctest"> const app2 = new PIXIApp({ view: canvas2, width: 900, height: 420, transparent: false }) .setup() .run() app2.loadTextures( ['./assets/circle2.png'], (textures) => { // add sprites //-------------------- const sprites = [] for (let i = 0; i < 100; i++) { const sprite = new PIXI.Sprite(textures.get('./assets/circle2.png')) sprite.id = i sprite.x = randomInt(0, app2.size.width) sprite.y = randomInt(0, app2.size.height) sprite.width = sprite.height = 16 sprite.anchor.set(0.5, 0.5) sprites.push(sprite) } app2.scene.addChild(...sprites) const links = new PIXI.Graphics() app2.scene.addChildAt(links, 0) // force simulation //-------------------- const forceCollide = d3.forceCollide().radius((d) => d.width / 2 + 4) const forceLink = d3 .forceLink([ { source: 88, target: 8 }, { source: 47, target: 55 }, { source: 70, target: 1 }, { source: 12, target: 12 }, { source: 26, target: 33 }, { source: 48, target: 53 }, { source: 10, target: 70 }, { source: 68, target: 61 }, { source: 28, target: 65 }, { source: 12, target: 34 }, { source: 6, target: 55 }, { source: 9, target: 16 }, { source: 87, target: 96 }, { source: 64, target: 24 }, { source: 98, target: 14 }, { source: 18, target: 23 }, { source: 53, target: 62 }, { source: 11, target: 53 }, { source: 43, target: 23 }, { source: 80, target: 9 }, { source: 72, target: 88 }, { source: 62, target: 3 }, { source: 72, target: 15 }, { source: 84, target: 25 }, { source: 57, target: 58 }, { source: 87, target: 19 } ]) .id((d) => d.id) .strength(0.05) const simulation = d3 .forceSimulation(sprites) .on('tick', () => { links.clear() links.lineStyle(1, 0xfdc02f) for (let link of forceLink.links()) { links.moveTo(link.source.x, link.source.y) links.lineTo(link.target.x, link.target.y) } }) .force('collide', forceCollide) .force('link', forceLink) .stop() d3.timeout(() => { simulation.restart() }, 1000) }, { resolutionDependent: false } ) </script> </body> </html>