sigma
Version:
A JavaScript library dedicated to graph drawing.
1 lines • 84.1 kB
JSON
{"pageProps":{"examples":[{"name":"animations","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport circularLayout from \"graphology-layout/circular\";\nimport { scaleLinear } from \"d3-scale\";\nimport { extent } from \"simple-statistics\";\n\nimport Sigma from \"sigma\";\nimport { animateNodes } from \"sigma/utils/animate\";\n\nimport miserables from \"./resources/les-miserables.json\";\nimport { globalize } from \"./utils\";\n\nconst graph = new UndirectedGraph();\n\n// Prepare data:\nconst nodeSizeExtent = extent(miserables.nodes.map((n) => n.size));\nconst xExtent = extent(miserables.nodes.map((n) => n.x));\nconst yExtent = extent(miserables.nodes.map((n) => n.y));\n\nconst nodeSizeScale = scaleLinear().domain(nodeSizeExtent).range([3, 15]);\nconst xScale = scaleLinear().domain(xExtent).range([0, 1]);\nconst yScale = scaleLinear().domain(yExtent).range([0, 1]);\n\nmiserables.nodes.forEach((node: { x: number; y: number; size: number }) => {\n node.size = nodeSizeScale(node.size) as number;\n node.x = xScale(node.x) as number;\n node.y = yScale(node.y) as number;\n});\n\nmiserables.nodes.forEach((node, i) => {\n graph.addNode(i, node);\n});\n\nmiserables.edges.forEach((edge) => {\n graph.addEdge(+edge.source, +edge.target, { color: \"#ccc\" });\n});\n\nconst container = document.getElementById(\"container\");\n\nconst renderer = new Sigma(graph, container);\n\nconst initial: Record<string, { x: number; y: number }> = {};\n\nmiserables.nodes.forEach((node: { size: number; x: number; y: number }, i) => {\n initial[i] = {\n x: node.x,\n y: node.y,\n };\n});\n\nconst circle = circularLayout(graph);\n\nlet state = false;\n\nfunction loop() {\n const l = state ? initial : circle;\n\n animateNodes(graph, l, { duration: 2000 }, () => {\n state = !state;\n loop();\n });\n}\n\nloop();\n\nglobalize({ graph, renderer });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> circularLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/circular"</span>;\n<span class=\"hljs-keyword\">import</span> { scaleLinear } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"d3-scale"</span>;\n<span class=\"hljs-keyword\">import</span> { extent } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"simple-statistics"</span>;\n\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"sigma"</span>;\n<span class=\"hljs-keyword\">import</span> { animateNodes } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"sigma/utils/animate"</span>;\n\n<span class=\"hljs-keyword\">import</span> miserables <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./resources/les-miserables.json"</span>;\n<span class=\"hljs-keyword\">import</span> { globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n\n<span class=\"hljs-keyword\">const</span> graph = <span class=\"hljs-keyword\">new</span> UndirectedGraph();\n\n<span class=\"hljs-comment\">// Prepare data:</span>\n<span class=\"hljs-keyword\">const</span> nodeSizeExtent = extent(miserables.nodes.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">n</span>) =></span> n.size));\n<span class=\"hljs-keyword\">const</span> xExtent = extent(miserables.nodes.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">n</span>) =></span> n.x));\n<span class=\"hljs-keyword\">const</span> yExtent = extent(miserables.nodes.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">n</span>) =></span> n.y));\n\n<span class=\"hljs-keyword\">const</span> nodeSizeScale = scaleLinear().domain(nodeSizeExtent).range([<span class=\"hljs-number\">3</span>, <span class=\"hljs-number\">15</span>]);\n<span class=\"hljs-keyword\">const</span> xScale = scaleLinear().domain(xExtent).range([<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">1</span>]);\n<span class=\"hljs-keyword\">const</span> yScale = scaleLinear().domain(yExtent).range([<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">1</span>]);\n\nmiserables.nodes.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node: { x: <span class=\"hljs-built_in\">number</span>; y: <span class=\"hljs-built_in\">number</span>; size: <span class=\"hljs-built_in\">number</span> }</span>) =></span> {\n node.size = nodeSizeScale(node.size) <span class=\"hljs-keyword\">as</span> <span class=\"hljs-built_in\">number</span>;\n node.x = xScale(node.x) <span class=\"hljs-keyword\">as</span> <span class=\"hljs-built_in\">number</span>;\n node.y = yScale(node.y) <span class=\"hljs-keyword\">as</span> <span class=\"hljs-built_in\">number</span>;\n});\n\nmiserables.nodes.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node, i</span>) =></span> {\n graph.addNode(i, node);\n});\n\nmiserables.edges.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">edge</span>) =></span> {\n graph.addEdge(+edge.source, +edge.target, { <span class=\"hljs-attr\">color</span>: <span class=\"hljs-string\">"#ccc"</span> });\n});\n\n<span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\n<span class=\"hljs-keyword\">const</span> renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\n<span class=\"hljs-keyword\">const</span> initial: Record<<span class=\"hljs-built_in\">string</span>, { <span class=\"hljs-attr\">x</span>: <span class=\"hljs-built_in\">number</span>; y: <span class=\"hljs-built_in\">number</span> }> = {};\n\nmiserables.nodes.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node: { size: <span class=\"hljs-built_in\">number</span>; x: <span class=\"hljs-built_in\">number</span>; y: <span class=\"hljs-built_in\">number</span> }, i</span>) =></span> {\n initial[i] = {\n <span class=\"hljs-attr\">x</span>: node.x,\n <span class=\"hljs-attr\">y</span>: node.y,\n };\n});\n\n<span class=\"hljs-keyword\">const</span> circle = circularLayout(graph);\n\n<span class=\"hljs-keyword\">let</span> state = <span class=\"hljs-literal\">false</span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">loop</span>(<span class=\"hljs-params\"></span>) </span>{\n <span class=\"hljs-keyword\">const</span> l = state ? initial : circle;\n\n animateNodes(graph, l, { <span class=\"hljs-attr\">duration</span>: <span class=\"hljs-number\">2000</span> }, <span class=\"hljs-function\">() =></span> {\n state = !state;\n loop();\n });\n}\n\nloop();\n\nglobalize({ graph, renderer });\n","codePath":"/home/alexis/code/sigma/examples/animations.ts","htmlPath":"/home/alexis/code/sigma/examples/animations.ts","iframePath":"/demos/animations.html"},{"name":"basic","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport erdosRenyi from \"graphology-generators/random/erdos-renyi\";\nimport randomLayout from \"graphology-layout/random\";\nimport chroma from \"chroma-js\";\n\nimport { getRandomName, globalize } from \"./utils\";\nimport Sigma from \"../src/sigma\";\n\nconst container = document.getElementById(\"container\");\n\nconst graph = erdosRenyi(UndirectedGraph, { order: 100, probability: 0.2 });\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach((node) => {\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: Math.max(4, Math.random() * 10),\n color: chroma.random().hex(),\n });\n});\n\nconst renderer = new Sigma(graph, container);\n\nglobalize({ graph, renderer });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> erdosRenyi <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-generators/random/erdos-renyi"</span>;\n<span class=\"hljs-keyword\">import</span> randomLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/random"</span>;\n<span class=\"hljs-keyword\">import</span> chroma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"chroma-js"</span>;\n\n<span class=\"hljs-keyword\">import</span> { getRandomName, globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n\n<span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\n<span class=\"hljs-keyword\">const</span> graph = erdosRenyi(UndirectedGraph, { <span class=\"hljs-attr\">order</span>: <span class=\"hljs-number\">100</span>, <span class=\"hljs-attr\">probability</span>: <span class=\"hljs-number\">0.2</span> });\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node</span>) =></span> {\n graph.mergeNodeAttributes(node, {\n <span class=\"hljs-attr\">label</span>: getRandomName(),\n <span class=\"hljs-attr\">size</span>: <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">4</span>, <span class=\"hljs-built_in\">Math</span>.random() * <span class=\"hljs-number\">10</span>),\n <span class=\"hljs-attr\">color</span>: chroma.random().hex(),\n });\n});\n\n<span class=\"hljs-keyword\">const</span> renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\nglobalize({ graph, renderer });\n","codePath":"/home/alexis/code/sigma/examples/basic.ts","htmlPath":"/home/alexis/code/sigma/examples/basic.ts","iframePath":"/demos/basic.html"},{"name":"components","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport randomLayout from \"graphology-layout/random\";\nimport forceAtlas2 from \"graphology-layout-forceatlas2\";\nimport louvain from \"graphology-communities-louvain\";\nimport { connectedComponents } from \"graphology-components\";\n\nimport Sigma from \"../src/sigma\";\n\nimport data from \"./resources/toflit.json\";\n\nconst scale = (d: number) => Math.max(2, Math.log2(d) * 1.7);\n\ndocument.body.innerHTML += `\n <style>\n .subcontainer {\n position: absolute;\n height: 300px;\n border-right: 1px solid black;\n border-bottom: 1px solid black;\n }\n .subcontainer:nth-child(1),\n .subcontainer:nth-child(2),\n .subcontainer:nth-child(3) {\n border-top: 1px solid black;\n }\n </style>\n`;\n\nconst mainContainer = document.getElementById(\"container\") as HTMLElement;\n\nconst graph = new UndirectedGraph();\n\ndata.forEach(({ source, target }) => {\n graph.mergeEdge(source, target);\n});\n\ngraph.nodes().forEach((node) => {\n graph.setNodeAttribute(node, \"label\", node);\n graph.setNodeAttribute(node, \"size\", scale(graph.degree(node)));\n});\n\nconst components = connectedComponents(graph);\n\ncomponents.forEach((component) => {\n if (component.length < 10) component.forEach((node) => graph.dropNode(node));\n});\n\nconst map: { [key: string]: number } = louvain(graph);\nconst communities: { [key: string]: UndirectedGraph } = {};\n\nfor (const node in map) {\n const c = map[node];\n\n if (!(c in communities)) communities[c] = new UndirectedGraph();\n\n const h = communities[c];\n\n h.mergeNode(node, graph.getNodeAttributes(node));\n\n graph.edges(node).forEach((edge) => {\n const target = graph.opposite(node, edge);\n\n if (node < target || map[target] !== c) return;\n\n h.mergeEdge(node, target);\n });\n}\n\nconst biggerCommunities: Array<UndirectedGraph> = Object.values(communities)\n .sort((a, b) => b.order - a.order)\n .slice(0, 6);\n\nconst width = mainContainer.offsetWidth;\n\nconst cellWidth = (width / 3) | 0;\n\nconst containers = biggerCommunities.map((_, i) => {\n const container = document.createElement(\"div\");\n container.style.width = `${cellWidth}px`;\n container.style.left = `${(i % 3) * cellWidth}px`;\n container.style.top = `${Math.floor(i / 3) * 300}px`;\n container.className = \"subcontainer\";\n mainContainer.appendChild(container);\n return container;\n});\n\nbiggerCommunities.forEach((h, i) => {\n randomLayout.assign(h);\n forceAtlas2.assign(h, {\n iterations: 100,\n settings: forceAtlas2.inferSettings(h),\n });\n\n const container = containers[i];\n\n new Sigma(h, container);\n});\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> randomLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/random"</span>;\n<span class=\"hljs-keyword\">import</span> forceAtlas2 <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout-forceatlas2"</span>;\n<span class=\"hljs-keyword\">import</span> louvain <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-communities-louvain"</span>;\n<span class=\"hljs-keyword\">import</span> { connectedComponents } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-components"</span>;\n\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n\n<span class=\"hljs-keyword\">import</span> data <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./resources/toflit.json"</span>;\n\n<span class=\"hljs-keyword\">const</span> scale = <span class=\"hljs-function\">(<span class=\"hljs-params\">d: <span class=\"hljs-built_in\">number</span></span>) =></span> <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">2</span>, <span class=\"hljs-built_in\">Math</span>.log2(d) * <span class=\"hljs-number\">1.7</span>);\n\n<span class=\"hljs-built_in\">document</span>.body.innerHTML += <span class=\"hljs-string\">`\n <style>\n .subcontainer {\n position: absolute;\n height: 300px;\n border-right: 1px solid black;\n border-bottom: 1px solid black;\n }\n .subcontainer:nth-child(1),\n .subcontainer:nth-child(2),\n .subcontainer:nth-child(3) {\n border-top: 1px solid black;\n }\n </style>\n`</span>;\n\n<span class=\"hljs-keyword\">const</span> mainContainer = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>) <span class=\"hljs-keyword\">as</span> HTMLElement;\n\n<span class=\"hljs-keyword\">const</span> graph = <span class=\"hljs-keyword\">new</span> UndirectedGraph();\n\ndata.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ source, target }</span>) =></span> {\n graph.mergeEdge(source, target);\n});\n\ngraph.nodes().forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node</span>) =></span> {\n graph.setNodeAttribute(node, <span class=\"hljs-string\">"label"</span>, node);\n graph.setNodeAttribute(node, <span class=\"hljs-string\">"size"</span>, scale(graph.degree(node)));\n});\n\n<span class=\"hljs-keyword\">const</span> components = connectedComponents(graph);\n\ncomponents.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">component</span>) =></span> {\n <span class=\"hljs-keyword\">if</span> (component.length < <span class=\"hljs-number\">10</span>) component.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node</span>) =></span> graph.dropNode(node));\n});\n\n<span class=\"hljs-keyword\">const</span> map: { [key: <span class=\"hljs-built_in\">string</span>]: <span class=\"hljs-built_in\">number</span> } = louvain(graph);\n<span class=\"hljs-keyword\">const</span> communities: { [key: <span class=\"hljs-built_in\">string</span>]: UndirectedGraph } = {};\n\n<span class=\"hljs-keyword\">for</span> (<span class=\"hljs-keyword\">const</span> node <span class=\"hljs-keyword\">in</span> map) {\n <span class=\"hljs-keyword\">const</span> c = map[node];\n\n <span class=\"hljs-keyword\">if</span> (!(c <span class=\"hljs-keyword\">in</span> communities)) communities[c] = <span class=\"hljs-keyword\">new</span> UndirectedGraph();\n\n <span class=\"hljs-keyword\">const</span> h = communities[c];\n\n h.mergeNode(node, graph.getNodeAttributes(node));\n\n graph.edges(node).forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">edge</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> target = graph.opposite(node, edge);\n\n <span class=\"hljs-keyword\">if</span> (node < target || map[target] !== c) <span class=\"hljs-keyword\">return</span>;\n\n h.mergeEdge(node, target);\n });\n}\n\n<span class=\"hljs-keyword\">const</span> biggerCommunities: <span class=\"hljs-built_in\">Array</span><UndirectedGraph> = <span class=\"hljs-built_in\">Object</span>.values(communities)\n .sort(<span class=\"hljs-function\">(<span class=\"hljs-params\">a, b</span>) =></span> b.order - a.order)\n .slice(<span class=\"hljs-number\">0</span>, <span class=\"hljs-number\">6</span>);\n\n<span class=\"hljs-keyword\">const</span> width = mainContainer.offsetWidth;\n\n<span class=\"hljs-keyword\">const</span> cellWidth = (width / <span class=\"hljs-number\">3</span>) | <span class=\"hljs-number\">0</span>;\n\n<span class=\"hljs-keyword\">const</span> containers = biggerCommunities.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">_, i</span>) =></span> {\n <span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.createElement(<span class=\"hljs-string\">"div"</span>);\n container.style.width = <span class=\"hljs-string\">`<span class=\"hljs-subst\">${cellWidth}</span>px`</span>;\n container.style.left = <span class=\"hljs-string\">`<span class=\"hljs-subst\">${(i % <span class=\"hljs-number\">3</span>) * cellWidth}</span>px`</span>;\n container.style.top = <span class=\"hljs-string\">`<span class=\"hljs-subst\">${<span class=\"hljs-built_in\">Math</span>.floor(i / <span class=\"hljs-number\">3</span>) * <span class=\"hljs-number\">300</span>}</span>px`</span>;\n container.className = <span class=\"hljs-string\">"subcontainer"</span>;\n mainContainer.appendChild(container);\n <span class=\"hljs-keyword\">return</span> container;\n});\n\nbiggerCommunities.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">h, i</span>) =></span> {\n randomLayout.assign(h);\n forceAtlas2.assign(h, {\n <span class=\"hljs-attr\">iterations</span>: <span class=\"hljs-number\">100</span>,\n <span class=\"hljs-attr\">settings</span>: forceAtlas2.inferSettings(h),\n });\n\n <span class=\"hljs-keyword\">const</span> container = containers[i];\n\n <span class=\"hljs-keyword\">new</span> Sigma(h, container);\n});\n","codePath":"/home/alexis/code/sigma/examples/components.ts","htmlPath":"/home/alexis/code/sigma/examples/components.ts","iframePath":"/demos/components.html"},{"name":"drag","codeRaw":"import Graph from \"graphology\";\nimport gexf from \"graphology-gexf/browser\";\nimport { NodeKey } from \"graphology-types\";\n\nimport Sigma from \"../src/sigma\";\nimport { globalize } from \"./utils\";\n\nimport arctic from \"./resources/arctic.gexf\";\n\nconst container = document.getElementById(\"container\");\n\nconst graph = gexf.parse(Graph, arctic);\n\ngraph.edges().forEach((edge) => {\n graph.setEdgeAttribute(edge, \"color\", \"#ccc\");\n});\n\nconst renderer = new Sigma(graph, container);\n\nconst camera = renderer.getCamera();\n\nconst captor = renderer.getMouseCaptor();\n\n// State\nlet draggedNode: NodeKey | null = null,\n dragging = false;\n\nrenderer.on(\"downNode\", (e) => {\n dragging = true;\n draggedNode = e.node;\n camera.disable();\n});\n\ncaptor.on(\"mouseup\", () => {\n dragging = false;\n draggedNode = null;\n camera.enable();\n});\n\ncaptor.on(\"mousemove\", (e) => {\n if (!dragging || !draggedNode) return;\n\n // Get new position of node\n const pos = renderer.viewportToGraph(e);\n\n graph.setNodeAttribute(draggedNode, \"x\", pos.x);\n graph.setNodeAttribute(draggedNode, \"y\", pos.y);\n});\n\nglobalize({ graph, renderer });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> Graph <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> gexf <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-gexf/browser"</span>;\n<span class=\"hljs-keyword\">import</span> { NodeKey } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-types"</span>;\n\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n<span class=\"hljs-keyword\">import</span> { globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n\n<span class=\"hljs-keyword\">import</span> arctic <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./resources/arctic.gexf"</span>;\n\nconst container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\nconst graph = gexf.parse(Graph, arctic);\n\ngraph.edges().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">(edge)</span> =></span> {\n graph.setEdgeAttribute(edge, <span class=\"hljs-string\">"color"</span>, <span class=\"hljs-string\">"#ccc"</span>);\n});\n\nconst renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\nconst camera = renderer.getCamera();\n\nconst captor = renderer.getMouseCaptor();\n\n<span class=\"hljs-regexp\">//</span> State\nlet draggedNode: NodeKey | <span class=\"hljs-literal\">null</span> = <span class=\"hljs-literal\">null</span>,\n dragging = <span class=\"hljs-literal\">false</span>;\n\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"downNode"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">(e)</span> =></span> {\n dragging = <span class=\"hljs-literal\">true</span>;\n draggedNode = e.node;\n camera.disable();\n});\n\ncaptor.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"mouseup"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">()</span> =></span> {\n dragging = <span class=\"hljs-literal\">false</span>;\n draggedNode = <span class=\"hljs-literal\">null</span>;\n camera.enable();\n});\n\ncaptor.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"mousemove"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">(e)</span> =></span> {\n <span class=\"hljs-keyword\">if</span> (!dragging || !draggedNode) <span class=\"hljs-keyword\">return</span>;\n\n <span class=\"hljs-regexp\">//</span> Get <span class=\"hljs-keyword\">new</span> position <span class=\"hljs-keyword\">of</span> node\n const pos = renderer.viewportToGraph(e);\n\n graph.setNodeAttribute(draggedNode, <span class=\"hljs-string\">"x"</span>, pos.x);\n graph.setNodeAttribute(draggedNode, <span class=\"hljs-string\">"y"</span>, pos.y);\n});\n\nglobalize({ graph, renderer });\n","codePath":"/home/alexis/code/sigma/examples/drag.ts","htmlPath":"/home/alexis/code/sigma/examples/drag.ts","iframePath":"/demos/drag.html"},{"name":"dynamic","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport erdosRenyi from \"graphology-generators/random/erdos-renyi\";\nimport randomLayout from \"graphology-layout/random\";\nimport FA2Layout from \"graphology-layout-forceatlas2/worker\";\nimport choice from \"pandemonium/choice\";\nimport random from \"pandemonium/random\";\nimport chroma from \"chroma-js\";\n\nimport { getRandomName, globalize } from \"./utils\";\nimport Sigma from \"../src/sigma\";\n\nconst container = document.getElementById(\"container\");\n\nconst graph = erdosRenyi(UndirectedGraph, { order: 100, probability: 0.2 });\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach((node) => {\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: Math.max(4, Math.random() * 10),\n color: chroma.random().hex(),\n });\n});\n\nconst renderer = new Sigma(graph, container);\n\n// Randomly editing the graph every second\nconst OPERATIONS = [\"addNode\"];\nlet counter = 0;\n\nfunction edit() {\n const op = choice(OPERATIONS);\n\n // Adding node\n if (op === \"addNode\") {\n const nodeKey = \"added-\" + counter++;\n\n const otherNodes = graph.nodes();\n\n graph.addNode(nodeKey, {\n label: getRandomName(),\n size: Math.max(4, Math.random() * 10) * 2,\n color: chroma.random().hex(),\n x: Math.random(),\n y: Math.random(),\n });\n\n // Adding edges\n const targets = new Set(\n Array.from(new Array(random(1, 5)), () => {\n return choice(otherNodes);\n }),\n );\n\n targets.forEach((target) => {\n graph.addEdge(nodeKey, target, { color: chroma.random().hex() });\n });\n }\n}\n\nsetInterval(edit, 1000);\n\n// Layout experiences\nconst layout = new FA2Layout(graph, { settings: { slowDown: 1000000 } });\n\nglobalize({\n graph,\n renderer,\n startLayout: function () {\n layout.start();\n },\n stopLayout: function () {\n layout.stop();\n },\n});\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> erdosRenyi <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-generators/random/erdos-renyi"</span>;\n<span class=\"hljs-keyword\">import</span> randomLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/random"</span>;\n<span class=\"hljs-keyword\">import</span> FA2Layout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout-forceatlas2/worker"</span>;\n<span class=\"hljs-keyword\">import</span> choice <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"pandemonium/choice"</span>;\n<span class=\"hljs-keyword\">import</span> random <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"pandemonium/random"</span>;\n<span class=\"hljs-keyword\">import</span> chroma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"chroma-js"</span>;\n\n<span class=\"hljs-keyword\">import</span> { getRandomName, globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n\n<span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\n<span class=\"hljs-keyword\">const</span> graph = erdosRenyi(UndirectedGraph, { <span class=\"hljs-attr\">order</span>: <span class=\"hljs-number\">100</span>, <span class=\"hljs-attr\">probability</span>: <span class=\"hljs-number\">0.2</span> });\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">node</span>) =></span> {\n graph.mergeNodeAttributes(node, {\n <span class=\"hljs-attr\">label</span>: getRandomName(),\n <span class=\"hljs-attr\">size</span>: <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">4</span>, <span class=\"hljs-built_in\">Math</span>.random() * <span class=\"hljs-number\">10</span>),\n <span class=\"hljs-attr\">color</span>: chroma.random().hex(),\n });\n});\n\n<span class=\"hljs-keyword\">const</span> renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\n<span class=\"hljs-comment\">// Randomly editing the graph every second</span>\n<span class=\"hljs-keyword\">const</span> OPERATIONS = [<span class=\"hljs-string\">"addNode"</span>];\n<span class=\"hljs-keyword\">let</span> counter = <span class=\"hljs-number\">0</span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">edit</span>(<span class=\"hljs-params\"></span>) </span>{\n <span class=\"hljs-keyword\">const</span> op = choice(OPERATIONS);\n\n <span class=\"hljs-comment\">// Adding node</span>\n <span class=\"hljs-keyword\">if</span> (op === <span class=\"hljs-string\">"addNode"</span>) {\n <span class=\"hljs-keyword\">const</span> nodeKey = <span class=\"hljs-string\">"added-"</span> + counter++;\n\n <span class=\"hljs-keyword\">const</span> otherNodes = graph.nodes();\n\n graph.addNode(nodeKey, {\n <span class=\"hljs-attr\">label</span>: getRandomName(),\n <span class=\"hljs-attr\">size</span>: <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">4</span>, <span class=\"hljs-built_in\">Math</span>.random() * <span class=\"hljs-number\">10</span>) * <span class=\"hljs-number\">2</span>,\n <span class=\"hljs-attr\">color</span>: chroma.random().hex(),\n <span class=\"hljs-attr\">x</span>: <span class=\"hljs-built_in\">Math</span>.random(),\n <span class=\"hljs-attr\">y</span>: <span class=\"hljs-built_in\">Math</span>.random(),\n });\n\n <span class=\"hljs-comment\">// Adding edges</span>\n <span class=\"hljs-keyword\">const</span> targets = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Set</span>(\n <span class=\"hljs-built_in\">Array</span>.from(<span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Array</span>(random(<span class=\"hljs-number\">1</span>, <span class=\"hljs-number\">5</span>)), <span class=\"hljs-function\">() =></span> {\n <span class=\"hljs-keyword\">return</span> choice(otherNodes);\n }),\n );\n\n targets.forEach(<span class=\"hljs-function\">(<span class=\"hljs-params\">target</span>) =></span> {\n graph.addEdge(nodeKey, target, { <span class=\"hljs-attr\">color</span>: chroma.random().hex() });\n });\n }\n}\n\n<span class=\"hljs-built_in\">setInterval</span>(edit, <span class=\"hljs-number\">1000</span>);\n\n<span class=\"hljs-comment\">// Layout experiences</span>\n<span class=\"hljs-keyword\">const</span> layout = <span class=\"hljs-keyword\">new</span> FA2Layout(graph, { <span class=\"hljs-attr\">settings</span>: { <span class=\"hljs-attr\">slowDown</span>: <span class=\"hljs-number\">1000000</span> } });\n\nglobalize({\n graph,\n renderer,\n <span class=\"hljs-attr\">startLayout</span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n layout.start();\n },\n <span class=\"hljs-attr\">stopLayout</span>: <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> (<span class=\"hljs-params\"></span>) </span>{\n layout.stop();\n },\n});\n","codePath":"/home/alexis/code/sigma/examples/dynamic.ts","htmlPath":"/home/alexis/code/sigma/examples/dynamic.ts","iframePath":"/demos/dynamic.html"},{"name":"events","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport erdosRenyi from \"graphology-generators/random/erdos-renyi\";\nimport randomLayout from \"graphology-layout/random\";\nimport chroma from \"chroma-js\";\nimport { EdgeKey, NodeKey } from \"graphology-types\";\n\nimport Sigma from \"../src/sigma\";\nimport { getRandomName, globalize } from \"./utils\";\nimport { EdgeAttributes, NodeAttributes } from \"../src/types\";\n\nconst container = document.getElementById(\"container\");\n\nconst graph = erdosRenyi.sparse(UndirectedGraph, {\n order: 500,\n probability: 0.05,\n});\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach((node) => {\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: Math.max(4, Math.random() * 10),\n color: chroma.random().hex(),\n zIndex: 0,\n });\n});\n\ngraph.edges().forEach((edge) =>\n graph.mergeEdgeAttributes(edge, {\n color: \"#ccc\",\n zIndex: 0,\n }),\n);\n\nlet highlighedNodes = new Set();\nlet highlighedEdges = new Set();\n\nconst nodeReducer = (node: NodeKey, data: NodeAttributes) => {\n if (highlighedNodes.has(node)) return { ...data, color: \"#f00\", zIndex: 1 };\n\n return data;\n};\n\nconst edgeReducer = (edge: EdgeKey, data: EdgeAttributes) => {\n if (highlighedEdges.has(edge)) return { ...data, color: \"#f00\", zIndex: 1 };\n\n return data;\n};\n\nconst renderer = new Sigma(graph, container, {\n nodeReducer,\n edgeReducer,\n zIndex: true,\n});\n\nrenderer.on(\"clickNode\", ({ node, captor, event }) => {\n console.log(\"Clicking:\", node, captor, event);\n});\nrenderer.on(\"rightClickNode\", ({ node, captor, event }) => {\n console.log(\"Right Clicking:\", node, captor, event);\n event.preventDefault();\n});\n\nrenderer.on(\"downStage\", ({ event }) => {\n console.log(\"Downing the stage.\", event);\n});\nrenderer.on(\"clickStage\", ({ event }) => {\n console.log(\"Clicking the stage.\", event);\n});\nrenderer.on(\"rightClickStage\", ({ event }) => {\n console.log(\"Right Clicking the stage.\", event);\n});\n\nrenderer.on(\"enterNode\", ({ node }) => {\n console.log(\"Entering: \", node);\n highlighedNodes = new Set(graph.neighbors(node));\n highlighedNodes.add(node);\n\n highlighedEdges = new Set(graph.edges(node));\n\n renderer.refresh();\n});\n\nrenderer.on(\"leaveNode\", ({ node }) => {\n console.log(\"Leaving:\", node);\n\n highlighedNodes.clear();\n highlighedEdges.clear();\n\n renderer.refresh();\n});\n\nglobalize({ graph, renderer });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> erdosRenyi <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-generators/random/erdos-renyi"</span>;\n<span class=\"hljs-keyword\">import</span> randomLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/random"</span>;\n<span class=\"hljs-keyword\">import</span> chroma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"chroma-js"</span>;\n<span class=\"hljs-keyword\">import</span> { EdgeKey, NodeKey } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-types"</span>;\n\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n<span class=\"hljs-keyword\">import</span> { getRandomName, globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n<span class=\"hljs-keyword\">import</span> { EdgeAttributes, NodeAttributes } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/types"</span>;\n\nconst container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\nconst graph = erdosRenyi.sparse(UndirectedGraph, {\n order: <span class=\"hljs-number\">500</span>,\n probability: <span class=\"hljs-number\">0.05</span>,\n});\nrandomLayout.assign(graph);\n\ngraph.nodes().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">(node)</span> =></span> {\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">4</span>, <span class=\"hljs-built_in\">Math</span>.random() * <span class=\"hljs-number\">10</span>),\n color: chroma.random().hex(),\n zIndex: <span class=\"hljs-number\">0</span>,\n });\n});\n\ngraph.edges().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">(edge)</span> =></span>\n graph.mergeEdgeAttributes(edge, {\n color: <span class=\"hljs-string\">"#ccc"</span>,\n zIndex: <span class=\"hljs-number\">0</span>,\n }),\n);\n\nlet highlighedNodes = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Set</span>();\nlet highlighedEdges = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Set</span>();\n\nconst nodeReducer = <span class=\"hljs-function\"><span class=\"hljs-params\">(node: NodeKey, data: NodeAttributes)</span> =></span> {\n <span class=\"hljs-keyword\">if</span> (highlighedNodes.has(node)) <span class=\"hljs-keyword\">return</span> { ...data, color: <span class=\"hljs-string\">"#f00"</span>, zIndex: <span class=\"hljs-number\">1</span> };\n\n <span class=\"hljs-keyword\">return</span> data;\n};\n\nconst edgeReducer = <span class=\"hljs-function\"><span class=\"hljs-params\">(edge: EdgeKey, data: EdgeAttributes)</span> =></span> {\n <span class=\"hljs-keyword\">if</span> (highlighedEdges.has(edge)) <span class=\"hljs-keyword\">return</span> { ...data, color: <span class=\"hljs-string\">"#f00"</span>, zIndex: <span class=\"hljs-number\">1</span> };\n\n <span class=\"hljs-keyword\">return</span> data;\n};\n\nconst renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container, {\n nodeReducer,\n edgeReducer,\n zIndex: <span class=\"hljs-literal\">true</span>,\n});\n\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"clickNode"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ node, captor, event })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Clicking:"</span>, node, captor, event);\n});\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"rightClickNode"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ node, captor, event })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Right Clicking:"</span>, node, captor, event);\n event.preventDefault();\n});\n\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"downStage"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ event })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Downing the stage."</span>, event);\n});\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"clickStage"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ event })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Clicking the stage."</span>, event);\n});\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"rightClickStage"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ event })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Right Clicking the stage."</span>, event);\n});\n\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"enterNode"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ node })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Entering: "</span>, node);\n highlighedNodes = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Set</span>(graph.neighbors(node));\n highlighedNodes.add(node);\n\n highlighedEdges = <span class=\"hljs-keyword\">new</span> <span class=\"hljs-built_in\">Set</span>(graph.edges(node));\n\n renderer.refresh();\n});\n\nrenderer.<span class=\"hljs-literal\">on</span>(<span class=\"hljs-string\">"leaveNode"</span>, <span class=\"hljs-function\"><span class=\"hljs-params\">({ node })</span> =></span> {\n <span class=\"hljs-built_in\">console</span>.log(<span class=\"hljs-string\">"Leaving:"</span>, node);\n\n highlighedNodes.clear();\n highlighedEdges.clear();\n\n renderer.refresh();\n});\n\nglobalize({ graph, renderer });\n","codePath":"/home/alexis/code/sigma/examples/events.ts","htmlPath":"/home/alexis/code/sigma/examples/events.ts","iframePath":"/demos/events.html"},{"name":"gexf","codeRaw":"import Graph from \"graphology\";\nimport gexf from \"graphology-gexf/browser\";\n\nimport Sigma from \"../src/sigma\";\nimport { globalize } from \"./utils\";\n\nimport arctic from \"./resources/arctic.gexf\";\n\nconst graph = gexf.parse(Graph, arctic);\n\nconst container = document.getElementById(\"container\");\n\nconst renderer = new Sigma(graph, container);\n\nglobalize({ graph, renderer });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> Graph <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> gexf <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-gexf/browser"</span>;\n\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n<span class=\"hljs-keyword\">import</span> { globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n\n<span class=\"hljs-keyword\">import</span> arctic <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./resources/arctic.gexf"</span>;\n\n<span class=\"hljs-keyword\">const</span> graph = gexf.parse(Graph, arctic);\n\n<span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\n<span class=\"hljs-keyword\">const</span> renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\nglobalize({ graph, renderer });\n","codePath":"/home/alexis/code/sigma/examples/gexf.ts","htmlPath":"/home/alexis/code/sigma/examples/gexf.ts","iframePath":"/demos/gexf.html"},{"name":"layout","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport clusters from \"graphology-generators/random/clusters\";\nimport randomLayout from \"graphology-layout/random\";\nimport FA2Layout from \"graphology-layout-forceatlas2/worker\";\n\nimport { getRandomName, globalize } from \"./utils\";\nimport Sigma from \"../src/sigma\";\n\nconst PALETTE = [\"#b4943e\", \"#777acd\", \"#60a862\", \"#c45ca2\", \"#cb5a4c\"];\n\nconst container = document.getElementById(\"container\");\n\nconsole.time(\"Creation\");\nconst graph = clusters(UndirectedGraph, {\n order: 5000,\n size: 25000,\n clusters: 5,\n});\nconsole.timeEnd(\"Creation\");\n\nrandomLayout.assign(graph, { scale: 400, center: 0 });\n\nconsole.time(\"Node Attributes\");\ngraph.nodes().forEach((node) => {\n const attr = graph.getNodeAttributes(node);\n\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: Math.max(4, Math.random() * 10),\n color: PALETTE[attr.cluster],\n });\n});\nconsole.timeEnd(\"Node Attributes\");\n\nconsole.time(\"Edge Attributes\");\ngraph.edges().forEach((edge) => {\n graph.setEdgeAttribute(edge, \"color\", \"#ccc\");\n});\nconsole.timeEnd(\"Edge Attributes\");\n\nconst renderer = new Sigma(graph, container);\n\nconst layout = new FA2Layout(graph, { settings: { barnesHutOptimize: true } });\nlayout.start();\n\nglobalize({ graph, renderer, layout });\n","codeHTML":"<span class=\"hljs-keyword\">import</span> { UndirectedGraph } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology"</span>;\n<span class=\"hljs-keyword\">import</span> clusters <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-generators/random/clusters"</span>;\n<span class=\"hljs-keyword\">import</span> randomLayout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout/random"</span>;\n<span class=\"hljs-keyword\">import</span> FA2Layout <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"graphology-layout-forceatlas2/worker"</span>;\n\n<span class=\"hljs-keyword\">import</span> { getRandomName, globalize } <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"./utils"</span>;\n<span class=\"hljs-keyword\">import</span> Sigma <span class=\"hljs-keyword\">from</span> <span class=\"hljs-string\">"../src/sigma"</span>;\n\n<span class=\"hljs-keyword\">const</span> PALETTE = [<span class=\"hljs-string\">"<span class=\"hljs-subst\">#b4943e</span>"</span>, <span class=\"hljs-string\">"#777acd"</span>, <span class=\"hljs-string\">"#60a862"</span>, <span class=\"hljs-string\">"<span class=\"hljs-subst\">#c45ca2</span>"</span>, <span class=\"hljs-string\">"<span class=\"hljs-subst\">#cb5a4c</span>"</span>];\n\n<span class=\"hljs-keyword\">const</span> container = <span class=\"hljs-built_in\">document</span>.getElementById(<span class=\"hljs-string\">"container"</span>);\n\n<span class=\"hljs-built_in\">console</span>.time(<span class=\"hljs-string\">"Creation"</span>);\n<span class=\"hljs-keyword\">const</span> graph = clusters(UndirectedGraph, {\n order: <span class=\"hljs-number\">5000</span>,\n size: <span class=\"hljs-number\">25000</span>,\n clusters: <span class=\"hljs-number\">5</span>,\n});\n<span class=\"hljs-built_in\">console</span>.timeEnd(<span class=\"hljs-string\">"Creation"</span>);\n\nrandomLayout.assign(graph, { scale: <span class=\"hljs-number\">400</span>, center: <span class=\"hljs-number\">0</span> });\n\n<span class=\"hljs-built_in\">console</span>.time(<span class=\"hljs-string\">"Node Attributes"</span>);\ngraph.nodes().forEach((node) => {\n <span class=\"hljs-keyword\">const</span> attr = graph.getNodeAttributes(node);\n\n graph.mergeNodeAttributes(node, {\n label: getRandomName(),\n size: <span class=\"hljs-built_in\">Math</span>.max(<span class=\"hljs-number\">4</span>, <span class=\"hljs-built_in\">Math</span>.random() * <span class=\"hljs-number\">10</span>),\n color: PALETTE[attr.cluster],\n });\n});\n<span class=\"hljs-built_in\">console</span>.timeEnd(<span class=\"hljs-string\">"Node Attributes"</span>);\n\n<span class=\"hljs-built_in\">console</span>.time(<span class=\"hljs-string\">"Edge Attributes"</span>);\ngraph.edges().forEach((edge) => {\n graph.setEdgeAttribute(edge, <span class=\"hljs-string\">"color"</span>, <span class=\"hljs-string\">"<span class=\"hljs-subst\">#ccc</span>"</span>);\n});\n<span class=\"hljs-built_in\">console</span>.timeEnd(<span class=\"hljs-string\">"Edge Attributes"</span>);\n\n<span class=\"hljs-keyword\">const</span> renderer = <span class=\"hljs-keyword\">new</span> Sigma(graph, container);\n\n<span class=\"hljs-keyword\">const</span> layout = <span class=\"hljs-keyword\">new</span> FA2Layout(graph, { settings: { barnesHutOptimize: <span class=\"hljs-literal\">true</span> } });\nlayout.start();\n\nglobalize({ graph, renderer, layout });\n","codePath":"/home/alexis/code/sigma/examples/layout.ts","htmlPath":"/home/alexis/code/sigma/examples/layout.ts","iframePath":"/demos/layout.html"},{"name":"noverlap","codeRaw":"import { UndirectedGraph } from \"graphology\";\nimport randomLayout from \"graphology-layout/random\";\nimport empty from \"graphology-generators/classic/empty\";\nimport noverlap, { NoverlapNodeReducer } from \"graphology-layout-noverlap\";\nimport NoverlapLayoutSupervisor from \"graphology-layout-noverlap/worker\";\nimport chroma from \"chroma-js\";\nimport random from \"pandemonium/random\";\n\nimport Sigma from \"../src/sigma\";\nimport { animateNodes } from \"../src/utils/animate\";\nimport { globalize } from \"./utils\";\n\nconst NOVERLAP_SETTINGS = {\n margin: 2,\n ratio: 1,\n speed: 3,\n};\n\nconst container = document.getElementById(\"container\") as HTMLDivElement;\n\nconst graph = empty(UndirectedGraph, 1000);\nrandomLayout.assign(graph);\n\ngraph.forEachNode((node) => {\n graph.mergeNodeAttributes(node, {\n label: node,\n size: random(2, 10),\n color: chroma.random().hex(),\n });\n});\n\nconst renderer = new Sigma(graph, container);\n\nfunction createButton(text: string, offset: number) {\n const button = document.createElement(\"button\");\n button.textContent = text;\n button.style.position = \"absolute\";\n button.style.left = \"10px\";\n\n let top = 10;\n\n top += offset * 40;\n\n button.style.top = `${top}px`;\n\n container.appendChild(button);\n\n return button;\n}\n\nconst inputReducer: NoverlapNodeReducer = (key, attr) => {\n return { ...attr, ...renderer.graphToViewport(attr) };\n};\n\nconst outputReducer: NoverlapNodeReducer = (key, attr) => {\n return { ...attr, ...renderer.viewportToGraph(attr) };\n};\n\nconst fixedButton = createButton(\"noverlap 500\", 0);\n\nfixedButton.onclick