From ac780f98d140de3efcb18902643fee594dec8b00 Mon Sep 17 00:00:00 2001 From: Jeff Baumes Date: Fri, 5 Jul 2019 16:06:54 -0400 Subject: [PATCH 01/16] Create README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..df121c8 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# Layoutr +A graph layout web application + +## Installation + +After a git checkout, run the following to serve the application locally: + +``` +npm i +npm run serve +``` + +## Usage + +* Click "Upload Edge List CSV" to upload a file of the form: +``` +source,target +a,b +b,c +c,d +d,a +``` +* Click "Start Layout". +* Play with the controls! From 5cc65b34ceaac002e25dd01b21ddc749f6a7dd7f Mon Sep 17 00:00:00 2001 From: Jeffrey Baumes Date: Sat, 6 Jul 2019 23:13:30 -0400 Subject: [PATCH 02/16] Enable control of forces --- dist/index.html | 56 +++++++++++++++++++++++++++++++++++-------------- src/index.css | 4 ++++ src/index.js | 34 +++++++++++++++++++++++++----- src/worker.js | 19 ++++++++++++++--- 4 files changed, 89 insertions(+), 24 deletions(-) diff --git a/dist/index.html b/dist/index.html index e6c4c1d..fee8ffe 100644 --- a/dist/index.html +++ b/dist/index.html @@ -5,22 +5,46 @@
diff --git a/src/index.css b/src/index.css index b79f19e..032c53a 100644 --- a/src/index.css +++ b/src/index.css @@ -21,6 +21,10 @@ html,body,#map{ #tooltip.hidden { display: none; } +.checkbox-wrapper { + padding: 24px 24px 0px 24px; + line-height: 1.6; +} .slider-wrapper { padding: 0px 24px; /* Need to reset line-height since we're in a side nav */ diff --git a/src/index.js b/src/index.js index 9952074..9db38b0 100644 --- a/src/index.js +++ b/src/index.js @@ -35,7 +35,7 @@ params.map.maxBounds.bottom += maxwh * 0.1; // allow zoomming in until 1 unit of space is 2^(value) bigger. params.map.max += 3; const map = geo.map(params.map); -const layer = map.createLayer('feature', {features: ['point', 'line']}); +let layer = map.createLayer('feature', {features: ['point', 'line']}); const uiLayer = map.createLayer('ui', {zIndex: 2}); const tooltip = uiLayer.createWidget('dom', {position: {x: 0, y: 0}}); @@ -58,6 +58,9 @@ layoutWorker.onmessage = function(e) { if (e.data.type === 'graph') { graph = e.data.graph; + map.deleteLayer(layer); + layer = map.createLayer('feature', {features: ['point', 'line']}); + nodeMap = {}; graph.nodes.forEach((n, i) => nodeMap[n.id] = i); lines = layer.createFeature('line').data(graph.edges.map(e => [nodeMap[e.source], nodeMap[e.target]])).style({ @@ -111,7 +114,9 @@ layoutWorker.onmessage = function(e) { map.draw(); } else if (e.data.type === 'alpha') { + alphaFromWorker = true; alpha.noUiSlider.set(e.data.value); + alphaFromWorker = false; } } @@ -189,6 +194,7 @@ theta.noUiSlider.on('update', () => { }); let alpha = document.getElementById('alpha'); +let alphaFromWorker = false; noUiSlider.create(alpha, { start: 1.0, step: 0.01, @@ -196,10 +202,12 @@ noUiSlider.create(alpha, { format: fixedFormat(2), }); alpha.noUiSlider.on('update', () => { - layoutWorker.postMessage({ - type: 'alpha', - value: alpha.noUiSlider.get(), - }); + if (!alphaFromWorker) { + layoutWorker.postMessage({ + type: 'alpha', + value: alpha.noUiSlider.get(), + }); + } }); let radiusFactorSlider = document.getElementById('radius-factor'); @@ -220,3 +228,19 @@ radiusFactorSlider.noUiSlider.on('update', () => { value: radiusFactorSlider.noUiSlider.get(), }); }); + +document.getElementById('charge').onchange = () => { + layoutWorker.postMessage({type: 'charge', value: !!document.getElementById('charge').checked}); +} + +document.getElementById('link').onchange = () => { + layoutWorker.postMessage({type: 'link', value: !!document.getElementById('link').checked}); +} + +document.getElementById('collide').onchange = () => { + layoutWorker.postMessage({type: 'collide', value: !!document.getElementById('collide').checked}); +} + +document.getElementById('center').onchange = () => { + layoutWorker.postMessage({type: 'center', value: !!document.getElementById('center').checked}); +} diff --git a/src/worker.js b/src/worker.js index f1c8b06..37c4d53 100644 --- a/src/worker.js +++ b/src/worker.js @@ -15,10 +15,12 @@ let linkDistanceFunctions = { let link = d3.forceLink().id(d => d.id).distance(linkDistanceFunctions.sumSqrtDegree).strength(linkStrengthFunctions.inverseMinDegree); let charge = d3.forceManyBody(); let collide = d3.forceCollide().radius(d => Math.sqrt(d.degree) * radiusFactor); +let center = d3.forceCenter(); let simulation = d3.forceSimulation() .force('link', link) .force('charge', charge) .force('collide', collide) + .force('center', center) .alphaMin(0) .alphaTarget(0) .stop(); @@ -56,8 +58,10 @@ loadGraph = function(graph) { edges: graph.edges, }}); - simulation.force('link') - .links(graph.edges); + let oldLink = simulation.force('link'); + simulation.force('link', link); + link.links(graph.edges); + simulation.force('link', oldLink); } onmessage = function(e) { @@ -82,7 +86,16 @@ onmessage = function(e) { collide.radius(d => Math.sqrt(d.degree) * radiusFactor); } else if (e.data.type === 'collide') { - simulation.collide(e.data.enabled ? collide : null); + simulation.force('collide', e.data.value ? collide : null); + } + else if (e.data.type === 'link') { + simulation.force('link', e.data.value ? link : null); + } + else if (e.data.type === 'charge') { + simulation.force('charge', e.data.value ? charge : null); + } + else if (e.data.type === 'center') { + simulation.force('center', e.data.value ? center : null); } else { throw Error(`Unknown message type '${e.data.type}'`); From 7ab2326fe27704f69f031c21b8f49c5f0bafc430 Mon Sep 17 00:00:00 2001 From: Jeffrey Baumes Date: Mon, 8 Jul 2019 14:57:20 -0400 Subject: [PATCH 03/16] Add edge visibility --- dist/index.html | 22 ++++++ src/force/periodicTable.js | 144 +++++++++++++++++++++++++++++++++++++ src/index.js | 84 +++++++++++++++++++++- src/worker.js | 17 ++++- 4 files changed, 261 insertions(+), 6 deletions(-) create mode 100644 src/force/periodicTable.js diff --git a/dist/index.html b/dist/index.html index fee8ffe..0bc20e1 100644 --- a/dist/index.html +++ b/dist/index.html @@ -6,6 +6,16 @@
  • Upload edge list (CSV) +
    + +
    +
    + Edge opacity +
    +
    Start layout
    @@ -18,6 +28,10 @@ Charge force
    +
    + Charge strength +
    +
    Theta
    @@ -28,6 +42,10 @@ Collide force
    +
    + Collide strength +
    +
    Radius factor
    @@ -38,6 +56,10 @@ Link force
    +
    + Link strength + +