Skip to content

Commit 5ac8b8a

Browse files
Max Carlsonclaude
andcommitted
docs: add magnet layout example
- Create interactive example with 3 magnet configurations - Demonstrate tag-based filtering - Show multiple magnets and strength scaling - Include sample data with tags and popularity metrics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 76dc7b3 commit 5ac8b8a

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>SpaceCraft Magnet Layout Example</title>
7+
<style>
8+
body { margin: 0; overflow: hidden; font-family: sans-serif; }
9+
#canvas { display: block; }
10+
#controls {
11+
position: absolute;
12+
top: 10px;
13+
left: 10px;
14+
background: rgba(0, 0, 0, 0.8);
15+
color: white;
16+
padding: 15px;
17+
border-radius: 5px;
18+
max-width: 350px;
19+
}
20+
button {
21+
margin: 5px;
22+
padding: 10px 15px;
23+
cursor: pointer;
24+
background: #444;
25+
color: white;
26+
border: 1px solid #666;
27+
border-radius: 3px;
28+
}
29+
button:hover { background: #555; }
30+
h3 { margin-top: 0; }
31+
.info { font-size: 0.9em; opacity: 0.8; }
32+
</style>
33+
</head>
34+
<body>
35+
<canvas id="canvas" width="1200" height="800"></canvas>
36+
<div id="controls">
37+
<h3>Magnet Layout Demo</h3>
38+
<p class="info">Physics-based layouts using metadata filtering</p>
39+
<button onclick="loadTagFiltered()">Tag-Based Clustering</button>
40+
<button onclick="loadPopularityWeighted()">Popularity Weighted</button>
41+
<button onclick="loadMultipleMagnets()">Multiple Magnets</button>
42+
</div>
43+
44+
<script type="module">
45+
import { Viewer } from '../dist/spacecraft-viewer.js'
46+
47+
const canvas = document.getElementById('canvas')
48+
const viewer = new Viewer(canvas)
49+
50+
// Sample data with tags and downloads
51+
const sampleData = [
52+
{ id: 'book1', title: 'Neuromancer', tags: ['cyberpunk', 'ai'], downloads: 1200 },
53+
{ id: 'book2', title: 'Snow Crash', tags: ['cyberpunk', 'vr'], downloads: 900 },
54+
{ id: 'book3', title: 'Lord of the Rings', tags: ['fantasy', 'epic'], downloads: 1500 },
55+
{ id: 'book4', title: 'Foundation', tags: ['sci-fi', 'space'], downloads: 800 },
56+
{ id: 'book5', title: 'Dune', tags: ['sci-fi', 'desert'], downloads: 1400 },
57+
{ id: 'book6', title: 'Hyperion', tags: ['sci-fi', 'space'], downloads: 600 },
58+
{ id: 'book7', title: 'Name of the Wind', tags: ['fantasy', 'magic'], downloads: 1100 },
59+
{ id: 'book8', title: 'Mistborn', tags: ['fantasy', 'magic'], downloads: 950 },
60+
{ id: 'book9', title: 'Altered Carbon', tags: ['cyberpunk', 'noir'], downloads: 750 },
61+
{ id: 'book10', title: 'Ringworld', tags: ['sci-fi', 'exploration'], downloads: 500 }
62+
]
63+
64+
window.loadTagFiltered = async () => {
65+
console.log('Loading tag-based clustering...')
66+
await viewer
67+
.data(sampleData)
68+
.into('scifi-books', {
69+
layout: 'magnet',
70+
magnets: [
71+
{
72+
position: { x: 30, y: 0, z: 0 },
73+
strength: 50,
74+
radius: 100,
75+
type: 'attractor',
76+
filter: {
77+
field: 'tags',
78+
value: 'cyberpunk',
79+
operator: 'contains'
80+
}
81+
}
82+
],
83+
iterations: 100
84+
})
85+
console.log('Tag-based layout applied!')
86+
}
87+
88+
window.loadPopularityWeighted = async () => {
89+
console.log('Loading popularity-weighted layout...')
90+
await viewer
91+
.data(sampleData)
92+
.into('scifi-books', {
93+
layout: 'magnet',
94+
magnets: [{
95+
position: { x: 0, y: 30, z: 0 },
96+
strength: 10,
97+
radius: 100,
98+
type: 'attractor',
99+
strengthField: 'downloads',
100+
strengthScale: 0.05
101+
}],
102+
iterations: 100
103+
})
104+
console.log('Popularity-weighted layout applied!')
105+
}
106+
107+
window.loadMultipleMagnets = async () => {
108+
console.log('Loading multiple magnets...')
109+
await viewer
110+
.data(sampleData)
111+
.into('scifi-books', {
112+
layout: 'magnet',
113+
magnets: [
114+
{
115+
position: { x: 30, y: 20, z: 0 },
116+
strength: 50,
117+
radius: 100,
118+
type: 'attractor',
119+
filter: { field: 'tags', value: 'cyberpunk', operator: 'contains' }
120+
},
121+
{
122+
position: { x: -30, y: 20, z: 0 },
123+
strength: 50,
124+
radius: 100,
125+
type: 'attractor',
126+
filter: { field: 'tags', value: 'fantasy', operator: 'contains' }
127+
},
128+
{
129+
position: { x: 0, y: -20, z: 0 },
130+
strength: 30,
131+
radius: 100,
132+
type: 'repeller',
133+
filter: { field: 'tags', value: 'sci-fi', operator: 'contains' }
134+
}
135+
],
136+
iterations: 150
137+
})
138+
console.log('Multiple magnets layout applied!')
139+
}
140+
141+
// Start with tag-based clustering
142+
loadTagFiltered()
143+
viewer.start()
144+
</script>
145+
</body>
146+
</html>

0 commit comments

Comments
 (0)