diff --git a/packages/foam-vscode/static/dataviz/graph.css b/packages/foam-vscode/static/dataviz/graph.css index 780b76b7..1e599f3b 100644 --- a/packages/foam-vscode/static/dataviz/graph.css +++ b/packages/foam-vscode/static/dataviz/graph.css @@ -1,10 +1,6 @@ body { overflow: hidden; } -/* - [INFO] Custom width rules for dat.GUI controls (10% for controls, 90% for labels) were intentionally removed. - This change was made to better accommodate new sliders, and to use dat.GUI's default proportions, which allocate more space to controls. If you notice any display issues (especially with type filter checkboxes), please verify in both light and dark VS Code themes. -*/ .vscode-light .dg.main.taller-than-window .close-button { border-top: 1px solid #ddd; diff --git a/packages/foam-vscode/static/dataviz/graph.js b/packages/foam-vscode/static/dataviz/graph.js index 690beaba..3434e234 100644 --- a/packages/foam-vscode/static/dataviz/graph.js +++ b/packages/foam-vscode/static/dataviz/graph.js @@ -4,6 +4,39 @@ const initGUI = () => { const gui = new dat.gui.GUI(); const nodeTypeFilterFolder = gui.addFolder('Filter by type'); const nodeTypeFilterControllers = new Map(); + const forcesFolder = gui.addFolder('Forces'); + + forcesFolder + .add(model.forces, 'collide', 0, 4) + .step(0.1) + .name('Collide Force') + .onFinishChange(v => { + graph.d3Force('collide').radius(graph.nodeRelSize() * v); + graph.d3ReheatSimulation(); + }); + forcesFolder + .add(model.forces, 'repel', 0, 200) + .name('Repel Force') + .onFinishChange(v => { + model.forces.charge = -v; + graph.d3Force('charge').strength(-v); + graph.d3ReheatSimulation(); + }); + forcesFolder + .add(model.forces, 'link', 0, 100) + .step(1) + .name('Link Distance') + .onFinishChange(v => { + graph.d3Force('link').distance(v); + graph.d3ReheatSimulation(); + }); + forcesFolder + .add(model.forces, 'velocityDecay', 0, 1) + .step(0.01) + .name('Velocity Decay') + .onChange(v => { + graph.d3VelocityDecay(1 - v); + }); const selectionFolder = gui.addFolder('Selection'); selectionFolder @@ -103,7 +136,13 @@ let model = { note: true, tag: true, }, - + forces: { + collide: 2, + repel: 30, + charge: -30, + link: 30, + velocityDecay: 0.4, + }, selection: { neighborDepth: 1, enableRefocus: true, @@ -240,7 +279,13 @@ function initDataviz(channel) { .linkHoverPrecision(8) .d3Force('x', d3.forceX()) .d3Force('y', d3.forceY()) - .d3Force('collide', d3.forceCollide(graph.nodeRelSize())) + .d3Force( + 'collide', + d3.forceCollide(graph.nodeRelSize() * model.forces.collide) + ) + .d3Force('charge', d3.forceManyBody().strength(model.forces.charge)) + .d3Force('link', d3.forceLink(model.data.links).distance(model.forces.link)) + .d3VelocityDecay(1 - model.forces.velocityDecay) .linkWidth(() => model.style.lineWidth) .linkDirectionalParticles(1) .linkDirectionalParticleWidth(link => @@ -404,6 +449,7 @@ function updateForceGraphDataFromModel(m) { // annoying we need to call this function, but I haven't found a good workaround graph.graphData(m.data); + graph.d3Force('link').links(m.data.links); } const getNodeSize = d3