iwmlib/lib/pixi/forcelayout.html

181 lines
7.2 KiB
HTML

<!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>