From 2ba54c6382d73fee5782aeeb9d3f161dd4d001c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Baumes Date: Tue, 9 Jul 2019 13:19:27 -0400 Subject: [PATCH 1/2] Add vue --- dist/index.html | 71 +------- package-lock.json | 164 ++++++++++++++++++ package.json | 5 +- src/App.vue | 428 ++++++++++++++++++++++++++++++++++++++++++++++ src/index.js | 342 +----------------------------------- webpack.config.js | 16 +- 6 files changed, 619 insertions(+), 407 deletions(-) create mode 100644 src/App.vue diff --git a/dist/index.html b/dist/index.html index df879d3..f3c0414 100644 --- a/dist/index.html +++ b/dist/index.html @@ -3,76 +3,7 @@ Layoutr - -
- +
diff --git a/package-lock.json b/package-lock.json index 2f69f9e..32ffb5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,64 @@ "integrity": "sha512-Uy0PN4R5vgBUXFoJrKryf5aTk3kJ8Rv3PdlHjl6UaX+Cqp1QE0yPQ68MPXGrZOfG7gZVNDIJZYyot0B9ubXUrQ==", "dev": true }, + "@vue/component-compiler-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-2.6.0.tgz", + "integrity": "sha512-IHjxt7LsOFYc0DkTncB7OXJL7UzwOLPPQCfEUNyxL2qt+tF12THV+EO33O1G2Uk4feMSWua3iD39Itszx0f0bw==", + "dev": true, + "requires": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.14", + "postcss-selector-parser": "^5.0.0", + "prettier": "1.16.3", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dev": true, + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -987,6 +1045,15 @@ "date-now": "^0.1.4" } }, + "consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dev": true, + "requires": { + "bluebird": "^3.1.1" + } + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -1435,6 +1502,12 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2990,6 +3063,12 @@ "safe-buffer": "^5.0.1" } }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, "hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -3000,6 +3079,12 @@ "minimalistic-assert": "^1.0.1" } }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -3675,6 +3760,23 @@ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", "dev": true }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -4409,6 +4511,12 @@ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", "dev": true }, + "prettier": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", + "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -4452,6 +4560,12 @@ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "dev": true }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -5867,6 +5981,56 @@ } } }, + "vue": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", + "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==" + }, + "vue-hot-reload-api": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.3.tgz", + "integrity": "sha512-KmvZVtmM26BQOMK1rwUZsrqxEGeKiYSZGA7SNWE6uExx8UX/cj9hq2MRV/wWC3Cq6AoeDGk57rL9YMFRel/q+g==", + "dev": true + }, + "vue-loader": { + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.7.0.tgz", + "integrity": "sha512-x+NZ4RIthQOxcFclEcs8sXGEWqnZHodL2J9Vq+hUz+TDZzBaDIh1j3d9M2IUlTjtrHTZy4uMuRdTi8BGws7jLA==", + "dev": true, + "requires": { + "@vue/component-compiler-utils": "^2.5.1", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + } + }, + "vue-style-loader": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", + "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", + "dev": true, + "requires": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "vue-template-compiler": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz", + "integrity": "sha512-jVZkw4/I/HT5ZMvRnhv78okGusqe0+qH2A0Em0Cp8aq78+NK9TII263CDVz2QXZsIT+yyV/gZc/j/vlwa+Epyg==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", + "dev": true + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/package.json b/package.json index 5a03ad4..69b78b1 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,15 @@ "dependencies": { "d3": "^5.9.7", "geojs": "^0.19.4", - "materialize-css": "^1.0.0" + "materialize-css": "^1.0.0", + "vue": "^2.6.10" }, "devDependencies": { "css-loader": "^3.0.0", "gh-pages": "^2.0.1", "style-loader": "^0.23.1", + "vue-loader": "^15.7.0", + "vue-template-compiler": "^2.6.10", "webpack": "^4.35.2", "webpack-cli": "^3.3.5", "webpack-dev-server": "^3.7.2", diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..0f54fd9 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,428 @@ + + + + + diff --git a/src/index.js b/src/index.js index e3a24ab..5f3852e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,343 +1,15 @@ import 'materialize-css/dist/css/materialize.min.css'; import 'materialize-css/dist/js/materialize.min.js'; import 'materialize-css/extras/noUiSlider/nouislider.css'; -import noUiSlider from 'materialize-css/extras/noUiSlider/nouislider.min.js'; -import geo from 'geojs/geo.js'; - -import LayoutWorker from 'worker-loader!./worker.js'; import './index.css'; -let b = 20000; -let bounds = { - minx: -b, - maxx: b, - miny: -b, - maxy: b, -}; -let params = geo.util.pixelCoordinateParams( - '#map', bounds.maxx - bounds.minx, bounds.maxy - bounds.miny); - -// the utility function assumes top left is 0, 0. Move it to minx, miny. -params.map.maxBounds.left += bounds.minx; -params.map.maxBounds.top += bounds.miny; -params.map.maxBounds.right += bounds.minx; -params.map.maxBounds.bottom += bounds.miny; -params.map.center.x += bounds.minx; -params.map.center.y += bounds.miny; - -// inflate the bounds to add a border -const maxwh = Math.max(bounds.maxx - bounds.minx, bounds.maxy - bounds.miny); -params.map.maxBounds.left -= maxwh * 0.1; -params.map.maxBounds.top -= maxwh * 0.1; -params.map.maxBounds.right += maxwh * 0.1; -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); -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}}); -const tooltipElem = tooltip.canvas(); -tooltipElem.setAttribute('id', 'tooltip'); -tooltipElem.classList.toggle('hidden', true); -tooltipElem.style['pointer-events'] = 'none'; - -map.draw(); - -let points; -let lines; -let graph; -let positions; -let nodeMap; -let radiusFactor = 2; -let edgeVisibility = false; -let edgeOpacity = 0.5; - -var layoutWorker = new LayoutWorker(); -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({ - position: nodeid => graph.nodes[nodeid], - width: 1, - strokeColor: 'black', - strokeOpacity: edgeOpacity, - }); - lines.visible(edgeVisibility); - map.draw(); - - points = layer.createFeature('point', { - primitiveShape: 'triangle', - style: { - strokeColor: 'black', - fillColor: 'grey', - fillOpacity: 0.5, - strokeOpacity: 0.5, - radius: nodeid => Math.max(1, Math.pow(2, map.zoom()) * Math.sqrt(graph.nodes[nodeid].degree) * radiusFactor) - }, - position: nodeid => graph.nodes[nodeid] - }).data(Object.keys(graph.nodes)); - - map.geoOn(geo.event.zoom, () => { - points.modified().draw(); - }); - - map.draw(); - - points - .geoOn(geo.event.feature.mouseon, function (evt) { - const nodeid = evt.data, node = graph.nodes[nodeid]; - let text = node.id; - if (text) { - tooltip.position(evt.mouse.geo); - tooltipElem.innerText = text; - } - tooltipElem.classList.toggle('hidden', !text); - }) - .geoOn(geo.event.feature.mousemove, function (evt) { - tooltip.position(evt.mouse.geo); - }) - .geoOn(geo.event.feature.mouseoff, function (evt) { - tooltipElem.classList.toggle('hidden', true); - }); - } - else if (e.data.type === 'positions') { - positions = e.data.nodes; - points.position(nodeid => positions[nodeid]); - map.draw(); - } - else if (e.data.type === 'alpha') { - alphaFromWorker = true; - alpha.noUiSlider.set(e.data.value); - alphaFromWorker = false; - } -} - -document.getElementById('toggle-start').onclick = () => { - let mode = document.getElementById('toggle-start').innerText.toLowerCase().split(' ')[0]; - layoutWorker.postMessage({type: mode}); - if (mode === 'start') { - alpha.setAttribute('disabled', true); - // Don't draw edges while performing layout for performance reasons - lines.visible(false); - } else { - alpha.removeAttribute('disabled'); - // Reenable edge drawing - if (edgeVisibility) { - lines.visible(true); - lines.position(nodeid => positions[nodeid]); - map.draw(); - } - } - document.getElementById('toggle-start').innerText = (mode === 'start' ? 'Stop Layout': 'Start Layout'); -} - -document.getElementById('save').onclick = () => { - const nodesWithPositions = graph.nodes.map((n, i) => ({ - ...n, - ...positions[i], - })); - const saveGraph = { - nodes: nodesWithPositions, - edges: graph.edges, - } - var blob = new Blob([JSON.stringify(saveGraph, null, 2)], { - type : "data:text/json;charset=utf-8;" - }); - const dl = document.getElementById('download'); - dl.setAttribute("href", URL.createObjectURL(blob)); - dl.setAttribute("download", "scene.json"); - dl.click(); -} - -document.getElementById('init-upload-edge-list').onclick = () => { - const upload = document.getElementById('upload-edge-list'); - upload.click(); -} - -document.getElementById('upload-edge-list').onchange = () => { - var file = document.getElementById('upload-edge-list').files[0]; - if (file) { - var reader = new FileReader(); - reader.readAsText(file, 'UTF-8'); - reader.onload = function (evt) { - layoutWorker.postMessage({type: 'loadEdgeList', text: evt.target.result}); - } - reader.onerror = function (evt) { - console.log('Error: ', evt); - } - } -} - -document.getElementById('init-upload-json').onclick = () => { - const upload = document.getElementById('upload-json'); - upload.click(); -} - -document.getElementById('upload-json').onchange = () => { - var file = document.getElementById('upload-json').files[0]; - if (file) { - var reader = new FileReader(); - reader.readAsText(file, 'UTF-8'); - reader.onload = function (evt) { - layoutWorker.postMessage({type: 'loadJSON', text: evt.target.result}); - } - reader.onerror = function (evt) { - console.log('Error: ', evt); - } - } -} - -function fixedFormat(n) { - return { - to: function (value) { - return value.toFixed(n); - }, - from: function (value) { - return Number(value); - }, - }; -} - -let theta = document.getElementById('theta'); -noUiSlider.create(theta, { - start: 1.5, - step: 0.1, - range: {min: 0.5, max: 3.0}, - format: fixedFormat(1), -}); -theta.noUiSlider.on('update', () => { - layoutWorker.postMessage({ - type: 'theta', - value: theta.noUiSlider.get(), - }); -}); - -let alpha = document.getElementById('alpha'); -let alphaFromWorker = false; -noUiSlider.create(alpha, { - start: 1.0, - step: 0.01, - range: {min: 0.0, max: 1.0}, - format: fixedFormat(2), -}); -alpha.noUiSlider.on('update', () => { - if (!alphaFromWorker) { - layoutWorker.postMessage({ - type: 'alpha', - value: alpha.noUiSlider.get(), - }); - } -}); - -let radiusFactorSlider = document.getElementById('radius-factor'); -noUiSlider.create(radiusFactorSlider, { - start: 2.0, - step: 0.1, - range: {min: 0.1, max: 10.0}, - format: fixedFormat(1), -}); -radiusFactorSlider.noUiSlider.on('update', () => { - radiusFactor = radiusFactorSlider.noUiSlider.get(); - if (points) { - points.modified(); - map.draw(); - } - layoutWorker.postMessage({ - type: 'radiusFactor', - value: radiusFactorSlider.noUiSlider.get(), - }); -}); - -let linkStrengthSlider = document.getElementById('link-strength'); -noUiSlider.create(linkStrengthSlider, { - start: 1.0, - step: 0.01, - range: {min: 0.0, max: 1.0}, - format: fixedFormat(2), -}); -linkStrengthSlider.noUiSlider.on('update', () => { - layoutWorker.postMessage({ - type: 'linkStrength', - value: linkStrengthSlider.noUiSlider.get(), - }); -}); +import Vue from 'vue'; +import App from './App'; -let chargeStrengthSlider = document.getElementById('charge-strength'); -noUiSlider.create(chargeStrengthSlider, { - start: -30, - step: 1, - range: {min: -50, max: 50}, - format: fixedFormat(0), -}); -chargeStrengthSlider.noUiSlider.on('update', () => { - layoutWorker.postMessage({ - type: 'chargeStrength', - value: chargeStrengthSlider.noUiSlider.get(), - }); -}); - -let collideStrengthSlider = document.getElementById('collide-strength'); -noUiSlider.create(collideStrengthSlider, { - start: 0.7, - step: 0.01, - range: {min: 0.0, max: 1.0}, - format: fixedFormat(2), -}); -collideStrengthSlider.noUiSlider.on('update', () => { - layoutWorker.postMessage({ - type: 'collideStrength', - value: collideStrengthSlider.noUiSlider.get(), - }); -}); - -document.getElementById('charge').onchange = () => { - layoutWorker.postMessage({type: 'charge', value: !!document.getElementById('charge').checked}); -} +Vue.config.productionTip = false; -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}); -} - -document.getElementById('show-edges').onchange = () => { - edgeVisibility = !!document.getElementById('show-edges').checked; - if (lines) { - lines.visible(edgeVisibility); - if (edgeVisibility) { - lines.position(nodeid => positions[nodeid]); - } - map.draw(); - } -} - -let edgeOpacitySlider = document.getElementById('edge-opacity'); -noUiSlider.create(edgeOpacitySlider, { - start: 0.5, - step: 0.01, - range: {min: 0.01, max: 1.0}, - format: fixedFormat(2), -}); -edgeOpacitySlider.noUiSlider.on('update', () => { - edgeOpacity = edgeOpacitySlider.noUiSlider.get(); - if (lines) { - lines.style('strokeOpacity', edgeOpacity); - lines.modified(); - map.draw(); - } +new Vue({ + el: '#app', + components: { App }, + template: '', }); diff --git a/webpack.config.js b/webpack.config.js index c703b71..a23891e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,4 +1,5 @@ const path = require('path'); +const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { mode: 'development', @@ -8,14 +9,27 @@ module.exports = { }, module: { rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + }, { test: /\.css$/i, use: ['style-loader', 'css-loader'], }, ], }, + resolve: { + extensions: ['.js', '.vue'], + alias: { + 'vue$': 'vue/dist/vue.js', + } + }, output: { path: path.resolve(__dirname, 'dist'), - filename: 'bundle.js' + filename: 'bundle.js', }, + plugins: [ + new VueLoaderPlugin(), + ], }; From 59c8c1fd388babe41d0c313b5493227927708dfa Mon Sep 17 00:00:00 2001 From: Jeffrey Baumes Date: Wed, 10 Jul 2019 10:46:14 -0400 Subject: [PATCH 2/2] Vuetify --- dist/index.html | 1 + package-lock.json | 10 +- package.json | 4 +- src/App.vue | 508 +++++++++++++++++++--------------------------- src/index.css | 41 ---- src/index.js | 7 +- src/worker.js | 25 +-- 7 files changed, 237 insertions(+), 359 deletions(-) delete mode 100644 src/index.css diff --git a/dist/index.html b/dist/index.html index f3c0414..fbfed9f 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,6 +1,7 @@ Layoutr +
diff --git a/package-lock.json b/package-lock.json index 32ffb5a..dd04e61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3711,11 +3711,6 @@ "object-visit": "^1.0.0" } }, - "materialize-css": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/materialize-css/-/materialize-css-1.0.0.tgz", - "integrity": "sha512-4/oecXl8y/1i8RDZvyvwAICyqwNoKU4or5uf8uoAd74k76KzZ0Llym4zhJ5lLNUskcqjO0AuMcvNyDkpz8Z6zw==" - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -6031,6 +6026,11 @@ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", "dev": true }, + "vuetify": { + "version": "1.5.16", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-1.5.16.tgz", + "integrity": "sha512-yBgOsfurKQkeS+l+rrTQZ2bFk0D9ezjHhkuVM5A/yVzcg62sY2nfYaq/H++uezBWC9WYFrp/5OmSocJQcWn9Qw==" + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", diff --git a/package.json b/package.json index 69b78b1..95a4e26 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "dependencies": { "d3": "^5.9.7", "geojs": "^0.19.4", - "materialize-css": "^1.0.0", - "vue": "^2.6.10" + "vue": "^2.6.10", + "vuetify": "^1.5.16" }, "devDependencies": { "css-loader": "^3.0.0", diff --git a/src/App.vue b/src/App.vue index 0f54fd9..6ad1a51 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,76 +1,72 @@ - diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 032c53a..0000000 --- a/src/index.css +++ /dev/null @@ -1,41 +0,0 @@ -html,body,#map{ - width: 100%; - height: 100%; - padding: 0; - margin: 0; - overflow: hidden; -} -#tooltip { - margin-left: 0px; - margin-top: -20px; - height: 16px; - line-height: 16px; - padding: 2px 5px; - background: rgba(255, 255, 255, 0.75); - border-radius: 10px; - border-bottom-left-radius: 0; - border: 1px solid rgba(0, 0, 0, 0.75); - font-size: 12px; - color: black; -} -#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 */ - line-height: 1.6; -} -.slider-wrapper .slider-label { - line-height: 3; -} -.noUi-horizontal .noUi-handle, .noUi-vertical .noUi-handle { - background-color: #2196f3; -} -.noUi-target.noUi-horizontal .noUi-tooltip { - background-color: #2196f3; -} diff --git a/src/index.js b/src/index.js index 5f3852e..3b7cd8c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,11 +1,10 @@ -import 'materialize-css/dist/css/materialize.min.css'; -import 'materialize-css/dist/js/materialize.min.js'; -import 'materialize-css/extras/noUiSlider/nouislider.css'; -import './index.css'; +import 'vuetify/dist/vuetify.min.css'; import Vue from 'vue'; +import Vuetify from 'vuetify'; import App from './App'; +Vue.use(Vuetify); Vue.config.productionTip = false; new Vue({ diff --git a/src/worker.js b/src/worker.js index 2bd5f8a..126b36a 100644 --- a/src/worker.js +++ b/src/worker.js @@ -1,7 +1,7 @@ let d3 = require('d3/dist/d3.js'); -let radiusFactor = 2; -let linkStrength = 0.1; +let radius = 2; +let linkStrength = 1; let linkStrengthFunctions = { inverseMinDegree: link => linkStrength / Math.min(link.source.degree, link.target.degree), @@ -10,12 +10,12 @@ let linkStrengthFunctions = { }; let linkDistanceFunctions = { - sumSqrtDegree: link => (Math.sqrt(link.source.degree) + Math.sqrt(link.target.degree)) * radiusFactor, + sumSqrtDegree: link => (Math.sqrt(link.source.degree) + Math.sqrt(link.target.degree)) * radius, }; 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 collide = d3.forceCollide().radius(d => Math.sqrt(d.degree) * radius); let center = d3.forceCenter(); // let radial = d3.forceX(d => ((d.discovery ? d.discovery : 2020) - 1900) * 150).strength(1); let simulation = d3.forceSimulation() @@ -67,11 +67,12 @@ loadGraph = function(graph) { } onmessage = function(e) { - if (e.data.type === 'stop') { - simulation.stop(); - } - else if (e.data.type === 'start') { - simulation.restart(); + if (e.data.type === 'layout') { + if (e.data.value) { + simulation.restart(); + } else { + simulation.stop(); + } } else if (e.data.type === 'loadEdgeList') { loadGraph({edges: d3.csvParse(e.data.text)}); @@ -85,10 +86,10 @@ onmessage = function(e) { else if (e.data.type === 'alpha') { simulation.alpha(e.data.value); } - else if (e.data.type === 'radiusFactor') { - radiusFactor = e.data.value; + else if (e.data.type === 'radius') { + radius = e.data.value; link.strength(linkStrengthFunctions.inverseMinDegree); - collide.radius(d => Math.sqrt(d.degree) * radiusFactor); + collide.radius(d => Math.sqrt(d.degree) * radius); } else if (e.data.type === 'linkStrength') { linkStrength = e.data.value;