<!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>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(.5, .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 < .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(.5, .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(.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>