From fb549ba6c66e06aa38e52dc833886a51dfd69105 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Tue, 20 Dec 2016 19:39:46 +0100 Subject: [PATCH 01/14] the-graph-node: Don't access globals at module load time --- the-graph/the-graph-node.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/the-graph/the-graph-node.js b/the-graph/the-graph-node.js index 5d3d6aff..5d30dfb2 100644 --- a/the-graph/the-graph-node.js +++ b/the-graph/the-graph-node.js @@ -81,16 +81,19 @@ } // PolymerGestures monkeypatch - PolymerGestures.dispatcher.gestures.forEach( function (gesture) { - // hold - if (gesture.HOLD_DELAY) { - gesture.HOLD_DELAY = 500; - } - // track - if (gesture.WIGGLE_THRESHOLD) { - gesture.WIGGLE_THRESHOLD = 8; - } - }); + function patchGestures() { + PolymerGestures.dispatcher.gestures.forEach( function (gesture) { + // hold + if (gesture.HOLD_DELAY) { + gesture.HOLD_DELAY = 500; + } + // track + if (gesture.WIGGLE_THRESHOLD) { + gesture.WIGGLE_THRESHOLD = 8; + } + }); + } + // Node view TheGraph.Node = React.createFactory( React.createClass({ @@ -99,6 +102,7 @@ TheGraph.mixins.Tooltip ], componentDidMount: function () { + patchGestures(); var domNode = ReactDOM.findDOMNode(this); // Dragging From e4c40c3c3011e67efc33f56ef974d58ab178e430 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Tue, 20 Dec 2016 19:10:40 +0100 Subject: [PATCH 02/14] JS: Use proper modules instead of self-executing closure --- Gruntfile.js | 10 +++++----- index.js | 20 ++++++++++++++++++++ package.json | 2 +- scripts/build-font-awesome-javascript.js | 8 ++++---- the-graph/font-awesome-unicode-map.js | 5 ++--- the-graph/the-graph-app.js | 5 ++--- the-graph/the-graph-clipboard.js | 6 +++--- the-graph/the-graph-edge.js | 5 ++--- the-graph/the-graph-graph.js | 5 ++--- the-graph/the-graph-group.js | 5 ++--- the-graph/the-graph-iip.js | 5 ++--- the-graph/the-graph-menu.js | 5 ++--- the-graph/the-graph-node-menu-port.js | 5 ++--- the-graph/the-graph-node-menu-ports.js | 5 ++--- the-graph/the-graph-node-menu.js | 5 ++--- the-graph/the-graph-node.js | 5 ++--- the-graph/the-graph-port.js | 5 ++--- the-graph/the-graph-tooltip.js | 5 ++--- the-graph/the-graph.html | 16 ---------------- the-graph/the-graph.js | 17 +++++++++-------- 20 files changed, 68 insertions(+), 76 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index d6595c0d..c842040d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -54,17 +54,17 @@ 'build/the-graph.js': ['index.js'], }, options: { - transform: ['coffeeify'] - }, - browserifyOptions: { - require: 'noflo' + transform: ['coffeeify'], + browserifyOptions: { + standalone: 'TheGraph' + } } } }, jshint: { options: { extract: 'auto', - strict: true, + strict: false, newcap: false, "globals": { "Polymer": true } }, diff --git a/index.js b/index.js index 78ff79c3..9576cd3e 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,22 @@ // Build required libs fbpGraph = require('fbp-graph'); + +var g = { TheGraph: {} }; + +require("./the-graph/the-graph.js").register(g); +require("./the-graph/the-graph-app.js").register(g); +require("./the-graph/the-graph-graph.js").register(g); +require("./the-graph/the-graph-node.js").register(g); +require("./the-graph/the-graph-node-menu.js").register(g); +require("./the-graph/the-graph-node-menu-port.js").register(g); +require("./the-graph/the-graph-node-menu-ports.js").register(g); +require("./the-graph/the-graph-port.js").register(g); +require("./the-graph/the-graph-edge.js").register(g); +require("./the-graph/the-graph-iip.js").register(g); +require("./the-graph/the-graph-group.js").register(g); +require("./the-graph/the-graph-tooltip.js").register(g); +require("./the-graph/the-graph-menu.js").register(g); +require("./the-graph/the-graph-clipboard.js").register(g); +require("./the-graph/font-awesome-unicode-map.js").register(g); + +module.exports = g.TheGraph; diff --git a/package.json b/package.json index be66975d..fd596ad0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "flow-based programming graph editing", "author": "Forrest Oliphant, the Grid", "license": "MIT", - "main": "the-graph-editor/index.html", + "main": "index.js", "dependencies": { "fbp-graph": "^0.1.0", "font-awesome": "^4.6.3", diff --git a/scripts/build-font-awesome-javascript.js b/scripts/build-font-awesome-javascript.js index f2157477..da5906d4 100644 --- a/scripts/build-font-awesome-javascript.js +++ b/scripts/build-font-awesome-javascript.js @@ -26,10 +26,10 @@ var generateFile = function (err, data) { }); var output = "/*\n this file is generated via `grunt build` \n*/\n\n"+ - "(function (context) {\n"+ - "\"use strict\";\n\n"+ + "module.exports.register = function (context) {\n"+ + "\n"+ "context.TheGraph.FONT_AWESOME = "+JSON.stringify(icons, null, 2)+";\n\n"+ - "})(this);"; + "};"; fs.writeFile(__dirname+'/../the-graph/font-awesome-unicode-map.js', output, function (err) { if (err) { @@ -39,4 +39,4 @@ var generateFile = function (err, data) { }); }; -fs.readFile( __dirname+'/../node_modules/font-awesome/less/variables.less', 'utf8', generateFile ); +fs.readFile( __dirname+'/../node_modules/font-awesome/less/variables.less', 'utf8', generateFile); diff --git a/the-graph/font-awesome-unicode-map.js b/the-graph/font-awesome-unicode-map.js index 586aa99d..5dd8e5c3 100644 --- a/the-graph/font-awesome-unicode-map.js +++ b/the-graph/font-awesome-unicode-map.js @@ -2,8 +2,7 @@ this file is generated via `grunt build` */ -(function (context) { -"use strict"; +module.exports.register = function (context) { context.TheGraph.FONT_AWESOME = { "500px": "", @@ -738,4 +737,4 @@ context.TheGraph.FONT_AWESOME = { "youtube-square": "" }; -})(this); \ No newline at end of file +}; \ No newline at end of file diff --git a/the-graph/the-graph-app.js b/the-graph/the-graph-app.js index 9e8a7c9d..653a56c1 100644 --- a/the-graph/the-graph-app.js +++ b/the-graph/the-graph-app.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -625,4 +624,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-clipboard.js b/the-graph/the-graph-clipboard.js index cf8531a4..c7e87100 100644 --- a/the-graph/the-graph-clipboard.js +++ b/the-graph/the-graph-clipboard.js @@ -2,8 +2,8 @@ * Created by mpricope on 05.09.14. */ -(function (context) { - "use strict"; +module.exports.register = function (context) { + var TheGraph = context.TheGraph; TheGraph.Clipboard = {}; @@ -78,4 +78,4 @@ return pasted; }; -})(this); +}; diff --git a/the-graph/the-graph-edge.js b/the-graph/the-graph-edge.js index 2f1c0c76..eaf84d4a 100644 --- a/the-graph/the-graph-edge.js +++ b/the-graph/the-graph-edge.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -277,4 +276,4 @@ } })); -})(this); +}; diff --git a/the-graph/the-graph-graph.js b/the-graph/the-graph-graph.js index 3dedffba..2251fec1 100644 --- a/the-graph/the-graph-graph.js +++ b/the-graph/the-graph-graph.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -839,4 +838,4 @@ } })); -})(this); +}; diff --git a/the-graph/the-graph-group.js b/the-graph/the-graph-group.js index bcc99121..86c3c8b5 100644 --- a/the-graph/the-graph-group.js +++ b/the-graph/the-graph-group.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -180,4 +179,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-iip.js b/the-graph/the-graph-iip.js index d962daed..29142cf5 100644 --- a/the-graph/the-graph-iip.js +++ b/the-graph/the-graph-iip.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -73,4 +72,4 @@ } })); -})(this); \ No newline at end of file +}; diff --git a/the-graph/the-graph-menu.js b/the-graph/the-graph-menu.js index 1a96d572..eadc8c11 100644 --- a/the-graph/the-graph-menu.js +++ b/the-graph/the-graph-menu.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -293,4 +292,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-node-menu-port.js b/the-graph/the-graph-node-menu-port.js index 309470aa..d8166016 100644 --- a/the-graph/the-graph-node-menu-port.js +++ b/the-graph/the-graph-node-menu-port.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -93,4 +92,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-node-menu-ports.js b/the-graph/the-graph-node-menu-ports.js index 4399ae74..8e9adac7 100644 --- a/the-graph/the-graph-node-menu-ports.js +++ b/the-graph/the-graph-node-menu-ports.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -95,4 +94,4 @@ })); -})(this); \ No newline at end of file +}; diff --git a/the-graph/the-graph-node-menu.js b/the-graph/the-graph-node-menu.js index fa087d4a..fa03b00f 100644 --- a/the-graph/the-graph-node-menu.js +++ b/the-graph/the-graph-node-menu.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -106,4 +105,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-node.js b/the-graph/the-graph-node.js index 5d30dfb2..44ea30ae 100644 --- a/the-graph/the-graph-node.js +++ b/the-graph/the-graph-node.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -533,4 +532,4 @@ return result; } -})(this); +}; diff --git a/the-graph/the-graph-port.js b/the-graph/the-graph-port.js index f67b735e..6631d14f 100644 --- a/the-graph/the-graph-port.js +++ b/the-graph/the-graph-port.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -185,4 +184,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph-tooltip.js b/the-graph/the-graph-tooltip.js index 2b9a8286..251a61f1 100644 --- a/the-graph/the-graph-tooltip.js +++ b/the-graph/the-graph-tooltip.js @@ -1,5 +1,4 @@ -(function (context) { - "use strict"; +module.exports.register = function (context) { var TheGraph = context.TheGraph; @@ -50,4 +49,4 @@ })); -})(this); +}; diff --git a/the-graph/the-graph.html b/the-graph/the-graph.html index a1da291a..4bf556c0 100644 --- a/the-graph/the-graph.html +++ b/the-graph/the-graph.html @@ -7,22 +7,6 @@
- - - - - - - - - - - - - - - - - + diff --git a/examples/demo-simple.html b/examples/demo-simple.html index 22c20644..26aeff19 100644 --- a/examples/demo-simple.html +++ b/examples/demo-simple.html @@ -14,7 +14,7 @@ - + diff --git a/examples/demo-thumbnail.html b/examples/demo-thumbnail.html index 0d8d5541..ab3bf5ed 100644 --- a/examples/demo-thumbnail.html +++ b/examples/demo-thumbnail.html @@ -6,7 +6,7 @@ - + diff --git a/spec/runner.html b/spec/runner.html index c1165210..92a935f9 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -15,7 +15,7 @@ - + From 22724a1e088c6d0bfd7b25117ffd80bdd4f2e76c Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Thu, 5 Jan 2017 23:20:47 +0100 Subject: [PATCH 04/14] NPM: Ensure dist/ is included in package --- .gitignore | 1 + .npmignore | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 .npmignore diff --git a/.gitignore b/.gitignore index 72a38cea..43956891 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ bower_components/ node_modules/ /.idea /build +/dist npm-debug.log /spec/*.js diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..48dabdee --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +/build +/bower_components +*.tgz From 10a10624ff73dee57d29d7a9893b9ee346de3857 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Thu, 5 Jan 2017 23:56:27 +0100 Subject: [PATCH 05/14] the-graph-thumb: Move rendering out of Polymer element --- examples/demo-thumbnail.html | 4 +- index.js | 2 + the-graph-thumb/the-graph-thumb.html | 176 +++----------------------- the-graph-thumb/the-graph-thumb.js | 179 +++++++++++++++++++++++++++ 4 files changed, 198 insertions(+), 163 deletions(-) create mode 100644 the-graph-thumb/the-graph-thumb.js diff --git a/examples/demo-thumbnail.html b/examples/demo-thumbnail.html index ab3bf5ed..c7eb36c2 100644 --- a/examples/demo-thumbnail.html +++ b/examples/demo-thumbnail.html @@ -4,8 +4,10 @@ the-graph-thumb documentation - + + + diff --git a/index.js b/index.js index 9576cd3e..55edf979 100644 --- a/index.js +++ b/index.js @@ -19,4 +19,6 @@ require("./the-graph/the-graph-menu.js").register(g); require("./the-graph/the-graph-clipboard.js").register(g); require("./the-graph/font-awesome-unicode-map.js").register(g); +g.TheGraph.thumb = require('./the-graph-thumb/the-graph-thumb.js'); + module.exports = g.TheGraph; diff --git a/the-graph-thumb/the-graph-thumb.html b/the-graph-thumb/the-graph-thumb.html index c02a967e..105fc16f 100644 --- a/the-graph-thumb/the-graph-thumb.html +++ b/the-graph-thumb/the-graph-thumb.html @@ -46,6 +46,7 @@ this.themeChanged(); }, themeChanged: function () { + // TODO: move to JS if (this.theme === "dark") { this.fillStyle = "hsl(184, 8%, 10%)"; this.strokeStyle = "hsl(180, 11%, 70%)"; @@ -85,25 +86,6 @@ // Redraw this.redrawGraph(); }, - drawEdge: function (context, scale, source, target, route) { - // Draw path - try { - context.strokeStyle = this.edgeColors[0]; - if (route) { - // Color if route defined - context.strokeStyle = this.edgeColors[route]; - } - var fromX = Math.round(source.metadata.x*scale)-0.5; - var fromY = Math.round(source.metadata.y*scale)-0.5; - var toX = Math.round(target.metadata.x*scale)-0.5; - var toY = Math.round(target.metadata.y*scale)-0.5; - context.beginPath(); - context.moveTo(fromX, fromY); - context.lineTo(toX, toY); - context.stroke(); - } catch (error) { - } - }, redrawGraph: function () { if (!this.graph) { return; @@ -117,149 +99,19 @@ // Need the actual context, not polymer-wrapped one context = unwrap(context); - // Reset origin - context.setTransform(1,0,0,1,0,0); - // Clear - context.clearRect(0, 0, this.width, this.height); - context.lineWidth = this.lineWidth; - // Find dimensions - var toDraw = []; - var minX = Infinity; - var minY = Infinity; - var maxX = -Infinity; - var maxY = -Infinity; - var nodes = {}; - - // Process nodes - this.graph.nodes.forEach(function(process){ - if ( process.metadata && !isNaN(process.metadata.x) && !isNaN(process.metadata.y) ) { - toDraw.push(process); - nodes[process.id] = process; - minX = Math.min(minX, process.metadata.x); - minY = Math.min(minY, process.metadata.y); - maxX = Math.max(maxX, process.metadata.x); - maxY = Math.max(maxY, process.metadata.y); - } - }.bind(this)); - - // Process exported ports - if (this.graph.inports) { - Object.keys(this.graph.inports).forEach(function(key){ - var exp = this.graph.inports[key]; - if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { - toDraw.push(exp); - minX = Math.min(minX, exp.metadata.x); - minY = Math.min(minY, exp.metadata.y); - maxX = Math.max(maxX, exp.metadata.x); - maxY = Math.max(maxY, exp.metadata.y); - } - }.bind(this)); - } - if (this.graph.outports) { - Object.keys(this.graph.outports).forEach(function(key){ - var exp = this.graph.outports[key]; - if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { - toDraw.push(exp); - minX = Math.min(minX, exp.metadata.x); - minY = Math.min(minY, exp.metadata.y); - maxX = Math.max(maxX, exp.metadata.x); - maxY = Math.max(maxY, exp.metadata.y); - } - }.bind(this)); - } - - // Sanity check graph size - if (!isFinite(minX) || !isFinite(minY) || !isFinite(maxX) || !isFinite(maxY) ) { - return; - } - - minX -= this.nodeSize; - minY -= this.nodeSize; - maxX += this.nodeSize*2; - maxY += this.nodeSize*2; - var w = maxX - minX; - var h = maxY - minY; - // For the-graph-nav to bind - this.thumbrectangle[0] = minX; - this.thumbrectangle[1] = minY; - this.thumbrectangle[2] = w; - this.thumbrectangle[3] = h; - // Scale dimensions - var scale = (w > h) ? this.width/w : this.height/h; - this.thumbscale = scale; - var size = Math.round(this.nodeSize * scale); - var sizeHalf = size / 2; - // Translate origin to match - context.setTransform(1,0,0,1,0-minX*scale,0-minY*scale); - - // Draw connection from inports to nodes - if (this.graph.inports) { - Object.keys(this.graph.inports).forEach(function(key){ - var exp = this.graph.inports[key]; - if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { - var target = nodes[exp.process]; - if (!target) { - return; - } - this.drawEdge(context, scale, exp, target, 2); - } - }.bind(this)); - } - // Draw connection from nodes to outports - if (this.graph.outports) { - Object.keys(this.graph.outports).forEach(function(key){ - var exp = this.graph.outports[key]; - if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { - var source = nodes[exp.process]; - if (!source) { - return; - } - this.drawEdge(context, scale, source, exp, 5); - } - }.bind(this)); - } - - // Draw edges - this.graph.edges.forEach(function (connection){ - var source = nodes[connection.from.node]; - var target = nodes[connection.to.node]; - if (!source || !target) { - return; - } - this.drawEdge(context, scale, source, target, connection.metadata.route); - }.bind(this)); - - // Draw nodes - toDraw.forEach(function (node){ - var x = Math.round(node.metadata.x * scale); - var y = Math.round(node.metadata.y * scale); - - // Outer circle - context.strokeStyle = this.strokeStyle; - context.fillStyle = this.fillStyle; - context.beginPath(); - if (node.process && !node.component) { - context.arc(x, y, sizeHalf / 2, 0, 2*Math.PI, false); - } else { - context.arc(x, y, sizeHalf, 0, 2*Math.PI, false); - } - context.fill(); - context.stroke(); - - // Inner circle - context.beginPath(); - var smallRadius = Math.max(sizeHalf-1.5, 1); - if (node.process && !node.component) { - // Exported port - context.arc(x, y, smallRadius / 2, 0, 2*Math.PI, false); - } else { - // Regular node - context.arc(x, y, smallRadius, 0, 2*Math.PI, false); - } - context.fill(); - - }.bind(this)); - + var properties = { + width: this.width, + height: this.height, + edgeColors: this.edgeColors, + nodeSize: this.nodeSize, + strokeStyle: this.strokeStyle, + fillStyle: this.fillStyle, + lineWidth: this.lineWidth, + }; + var thumb = TheGraph.thumb.render(context, this.graph, properties); + + this.thumbrectangle = thumb.rectangle; + this.thumbscale = thumb.scale; }, listener: null, graphChanged: function (oldGraph, newGraph) { diff --git a/the-graph-thumb/the-graph-thumb.js b/the-graph-thumb/the-graph-thumb.js new file mode 100644 index 00000000..96dde01c --- /dev/null +++ b/the-graph-thumb/the-graph-thumb.js @@ -0,0 +1,179 @@ + +function drawEdge(context, scale, source, target, route, properties) { + // Draw path + try { + context.strokeStyle = properties.edgeColors[0]; + if (route) { + // Color if route defined + context.strokeStyle = properties.edgeColors[route]; + } + var fromX = Math.round(source.metadata.x*scale)-0.5; + var fromY = Math.round(source.metadata.y*scale)-0.5; + var toX = Math.round(target.metadata.x*scale)-0.5; + var toY = Math.round(target.metadata.y*scale)-0.5; + context.beginPath(); + context.moveTo(fromX, fromY); + context.lineTo(toX, toY); + context.stroke(); + } catch (error) { + // FIXME: handle? + } +} + + +function renderThumbnail(context, graph, properties) { + + // Reset origin + context.setTransform(1,0,0,1,0,0); + // Clear + context.clearRect(0, 0, properties.width, properties.height); + context.lineWidth = properties.lineWidth; + + // Find dimensions + var toDraw = []; + var minX = Infinity; + var minY = Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + var nodes = {}; + + // Process nodes + graph.nodes.forEach(function(process){ + if ( process.metadata && !isNaN(process.metadata.x) && !isNaN(process.metadata.y) ) { + toDraw.push(process); + nodes[process.id] = process; + minX = Math.min(minX, process.metadata.x); + minY = Math.min(minY, process.metadata.y); + maxX = Math.max(maxX, process.metadata.x); + maxY = Math.max(maxY, process.metadata.y); + } + }.bind(this)); + + // Process exported ports + if (graph.inports) { + Object.keys(graph.inports).forEach(function(key){ + var exp = graph.inports[key]; + if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { + toDraw.push(exp); + minX = Math.min(minX, exp.metadata.x); + minY = Math.min(minY, exp.metadata.y); + maxX = Math.max(maxX, exp.metadata.x); + maxY = Math.max(maxY, exp.metadata.y); + } + }.bind(this)); + } + if (graph.outports) { + Object.keys(graph.outports).forEach(function(key){ + var exp = graph.outports[key]; + if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { + toDraw.push(exp); + minX = Math.min(minX, exp.metadata.x); + minY = Math.min(minY, exp.metadata.y); + maxX = Math.max(maxX, exp.metadata.x); + maxY = Math.max(maxY, exp.metadata.y); + } + }.bind(this)); + } + + // Sanity check graph size + if (!isFinite(minX) || !isFinite(minY) || !isFinite(maxX) || !isFinite(maxY) ) { + return; + } + + minX -= properties.nodeSize; + minY -= properties.nodeSize; + maxX += properties.nodeSize*2; + maxY += properties.nodeSize*2; + var w = maxX - minX; + var h = maxY - minY; + // For the-graph-nav to bind + var thumbrectangle = []; + thumbrectangle[0] = minX; + thumbrectangle[1] = minY; + thumbrectangle[2] = w; + thumbrectangle[3] = h; + // Scale dimensions + var scale = (w > h) ? properties.width/w : properties.height/h; + var thumbscale = scale; + var size = Math.round(properties.nodeSize * scale); + var sizeHalf = size / 2; + // Translate origin to match + context.setTransform(1,0,0,1,0-minX*scale,0-minY*scale); + + // Draw connection from inports to nodes + if (graph.inports) { + Object.keys(graph.inports).forEach(function(key){ + var exp = graph.inports[key]; + if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { + var target = nodes[exp.process]; + if (!target) { + return; + } + drawEdge(context, scale, exp, target, 2, properties); + } + }.bind(this)); + } + // Draw connection from nodes to outports + if (graph.outports) { + Object.keys(graph.outports).forEach(function(key){ + var exp = graph.outports[key]; + if ( exp.metadata && !isNaN(exp.metadata.x) && !isNaN(exp.metadata.y) ) { + var source = nodes[exp.process]; + if (!source) { + return; + } + drawEdge(context, scale, source, exp, 5, properties); + } + }.bind(this)); + } + + // Draw edges + graph.edges.forEach(function (connection){ + var source = nodes[connection.from.node]; + var target = nodes[connection.to.node]; + if (!source || !target) { + return; + } + drawEdge(context, scale, source, target, connection.metadata.route, properties); + }.bind(this)); + + // Draw nodes + toDraw.forEach(function (node){ + var x = Math.round(node.metadata.x * scale); + var y = Math.round(node.metadata.y * scale); + + // Outer circle + context.strokeStyle = properties.strokeStyle; + context.fillStyle = properties.fillStyle; + context.beginPath(); + if (node.process && !node.component) { + context.arc(x, y, sizeHalf / 2, 0, 2*Math.PI, false); + } else { + context.arc(x, y, sizeHalf, 0, 2*Math.PI, false); + } + context.fill(); + context.stroke(); + + // Inner circle + context.beginPath(); + var smallRadius = Math.max(sizeHalf-1.5, 1); + if (node.process && !node.component) { + // Exported port + context.arc(x, y, smallRadius / 2, 0, 2*Math.PI, false); + } else { + // Regular node + context.arc(x, y, smallRadius, 0, 2*Math.PI, false); + } + context.fill(); + + }.bind(this)); + + return { + rectangle: thumbrectangle, + scale: thumbscale + }; +} + +module.exports = { + render: renderThumbnail, +}; From 2d214203064f5691b175d7825e6ff1f8dac88f39 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Thu, 5 Jan 2017 23:57:07 +0100 Subject: [PATCH 06/14] Grunt: Run browserify when .js files change --- Gruntfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 5e68edcf..5977db51 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -7,7 +7,7 @@ "* Copyright (c) <%= grunt.template.today('yyyy') %> <%= pkg.author.name %>; Licensed <%= _.pluck(pkg.licenses, 'type').join(', ') %> */\n"; var sources = { - scripts: ['Gruntfile.js', 'the-*/*.js', 'the-*/*.html'], + scripts: ['Gruntfile.js', 'the-*/*.js', 'the-*/*.html', 'index.js'], // elements: ['the-*/*.html'], stylus: ['themes/*/*.styl'], css: ['themes/*.css'], @@ -88,7 +88,7 @@ watch: { scripts: { files: sources.scripts, - tasks: ['jshint:force'], + tasks: ['jshint:force', 'browserify:libs'], options: { livereload: true } From 33c5fd0c3dce4ccd01029848da6af9eabdcdcc8e Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 00:05:42 +0100 Subject: [PATCH 07/14] the-graph-thumb: Move style calculation out of Polymer element --- the-graph-thumb/the-graph-thumb.html | 41 +++------------------------- the-graph-thumb/the-graph-thumb.js | 41 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/the-graph-thumb/the-graph-thumb.html b/the-graph-thumb/the-graph-thumb.html index 105fc16f..3623a2bd 100644 --- a/the-graph-thumb/the-graph-thumb.html +++ b/the-graph-thumb/the-graph-thumb.html @@ -46,43 +46,10 @@ this.themeChanged(); }, themeChanged: function () { - // TODO: move to JS - if (this.theme === "dark") { - this.fillStyle = "hsl(184, 8%, 10%)"; - this.strokeStyle = "hsl(180, 11%, 70%)"; - this.edgeColors = [ - "white", - "hsl( 0, 100%, 46%)", - "hsl( 35, 100%, 46%)", - "hsl( 60, 100%, 46%)", - "hsl(135, 100%, 46%)", - "hsl(160, 100%, 46%)", - "hsl(185, 100%, 46%)", - "hsl(210, 100%, 46%)", - "hsl(285, 100%, 46%)", - "hsl(310, 100%, 46%)", - "hsl(335, 100%, 46%)" - ]; - - } else { - // Light - this.fillStyle = "hsl(184, 8%, 75%)"; - this.strokeStyle = "hsl(180, 11%, 20%)"; - // Tweaked to make thin lines more visible - this.edgeColors = [ - "hsl( 0, 0%, 50%)", - "hsl( 0, 100%, 40%)", - "hsl( 29, 100%, 40%)", - "hsl( 47, 100%, 40%)", - "hsl(138, 100%, 40%)", - "hsl(160, 73%, 50%)", - "hsl(181, 100%, 40%)", - "hsl(216, 100%, 40%)", - "hsl(260, 100%, 40%)", - "hsl(348, 100%, 50%)", - "hsl(328, 100%, 40%)" - ]; - } + var style = TheGraph.thumb.styleFromTheme(this.theme); + this.edgeColors = style.edgeColors; + this.fillStyle = style.fill; + this.strokeStyle = style.stroke; // Redraw this.redrawGraph(); }, diff --git a/the-graph-thumb/the-graph-thumb.js b/the-graph-thumb/the-graph-thumb.js index 96dde01c..5487596c 100644 --- a/the-graph-thumb/the-graph-thumb.js +++ b/the-graph-thumb/the-graph-thumb.js @@ -20,6 +20,46 @@ function drawEdge(context, scale, source, target, route, properties) { } } +function styleFromTheme(theme) { + var style = {}; + if (theme === "dark") { + style.fill = "hsl(184, 8%, 10%)"; + style.stroke = "hsl(180, 11%, 70%)"; + style.edgeColors = [ + "white", + "hsl( 0, 100%, 46%)", + "hsl( 35, 100%, 46%)", + "hsl( 60, 100%, 46%)", + "hsl(135, 100%, 46%)", + "hsl(160, 100%, 46%)", + "hsl(185, 100%, 46%)", + "hsl(210, 100%, 46%)", + "hsl(285, 100%, 46%)", + "hsl(310, 100%, 46%)", + "hsl(335, 100%, 46%)" + ]; + + } else { + // Light + style.fill = "hsl(184, 8%, 75%)"; + style.stroke = "hsl(180, 11%, 20%)"; + // Tweaked to make thin lines more visible + style.edgeColors = [ + "hsl( 0, 0%, 50%)", + "hsl( 0, 100%, 40%)", + "hsl( 29, 100%, 40%)", + "hsl( 47, 100%, 40%)", + "hsl(138, 100%, 40%)", + "hsl(160, 73%, 50%)", + "hsl(181, 100%, 40%)", + "hsl(216, 100%, 40%)", + "hsl(260, 100%, 40%)", + "hsl(348, 100%, 50%)", + "hsl(328, 100%, 40%)" + ]; + } + return style; +} function renderThumbnail(context, graph, properties) { @@ -176,4 +216,5 @@ function renderThumbnail(context, graph, properties) { module.exports = { render: renderThumbnail, + styleFromTheme: styleFromTheme, }; From 9b17ae1e719f18306983565d9a3dc7bc2f9eeb47 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 12:54:37 +0100 Subject: [PATCH 08/14] the-graph-nav: Move rendering out of Polymer element --- index.js | 1 + the-graph-nav/the-graph-nav.html | 71 ++++++------------------------ the-graph-nav/the-graph-nav.js | 75 ++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 58 deletions(-) create mode 100644 the-graph-nav/the-graph-nav.js diff --git a/index.js b/index.js index 55edf979..144b44ac 100644 --- a/index.js +++ b/index.js @@ -20,5 +20,6 @@ require("./the-graph/the-graph-clipboard.js").register(g); require("./the-graph/font-awesome-unicode-map.js").register(g); g.TheGraph.thumb = require('./the-graph-thumb/the-graph-thumb.js'); +g.TheGraph.nav = require('./the-graph-nav/the-graph-nav.js'); module.exports = g.TheGraph; diff --git a/the-graph-nav/the-graph-nav.html b/the-graph-nav/the-graph-nav.html index 2d466449..d4c6ed3d 100644 --- a/the-graph-nav/the-graph-nav.html +++ b/the-graph-nav/the-graph-nav.html @@ -138,65 +138,20 @@ // Canvas to grey out outside view var context = this.$.outcanvas.getContext('2d'); context = unwrap(context); - context.clearRect(0, 0, this.width, this.height); - context.fillStyle = this.outsideFill; - // Scaled view rectangle - var x = Math.round( (this.viewrectangle[0]/this.scale - this.thumbrectangle[0]) * this.thumbscale ); - var y = Math.round( (this.viewrectangle[1]/this.scale - this.thumbrectangle[1]) * this.thumbscale ); - var w = Math.round( this.viewrectangle[2] * this.thumbscale / this.scale ); - var h = Math.round( this.viewrectangle[3] * this.thumbscale / this.scale ); - - if (x<0 && y<0 && w>this.width-x && h>this.height-y) { - // Hide map - this.hide = true; - return; - } else { - // Show map - this.hide = false; - } - - // Clip to bounds - // Left - if (x < 0) { - w += x; - x = 0; - this.$.viewrect.style.borderLeftColor = this.viewBoxBorder2; - } else { - this.$.viewrect.style.borderLeftColor = this.viewBoxBorder; - context.fillRect(0, 0, x, this.height); - } - // Top - if (y < 0) { - h += y; - y = 0; - this.$.viewrect.style.borderTopColor = this.viewBoxBorder2; - } else { - this.$.viewrect.style.borderTopColor = this.viewBoxBorder; - context.fillRect(x, 0, w, y); - } - // Right - if (w > this.width-x) { - w = this.width-x; - this.$.viewrect.style.borderRightColor = this.viewBoxBorder2; - } else { - this.$.viewrect.style.borderRightColor = this.viewBoxBorder; - context.fillRect(x+w, 0, this.width-(x+w), this.height); - } - // Bottom - if (h > this.height-y) { - h = this.height-y; - this.$.viewrect.style.borderBottomColor = this.viewBoxBorder2; - } else { - this.$.viewrect.style.borderBottomColor = this.viewBoxBorder; - context.fillRect(x, y+h, w, this.height-(y+h)); - } - - // Size and translate rect - this.$.viewrect.style.left = x+"px"; - this.$.viewrect.style.top = y+"px"; - this.$.viewrect.style.width = w+"px"; - this.$.viewrect.style.height = h+"px"; + var properties = { + width: this.width, + height: this.height, + scale: this.scale, + thumbscale: this.thumbscale, + thumbrectangle: this.thumbrectangle, + viewrectangle: this.viewrectangle, + viewBoxBorder: this.viewBoxBorder, + viewBoxBorder2: this.viewBoxBorder2, + outsideFill: this.outsideFill, + }; + var nav = TheGraph.nav.render(context, this.$.viewrect, properties); + this.hide = nav.hide; // this.scaledviewrectangle = [x, y, w, h]; }, hideChanged: function () { diff --git a/the-graph-nav/the-graph-nav.js b/the-graph-nav/the-graph-nav.js new file mode 100644 index 00000000..741de46d --- /dev/null +++ b/the-graph-nav/the-graph-nav.js @@ -0,0 +1,75 @@ + +function renderViewRectangle(context, viewrect, props) { + + context.clearRect(0, 0, props.width, props.height); + context.fillStyle = props.outsideFill; + + // Scaled view rectangle + var x = Math.round( (props.viewrectangle[0]/props.scale - props.thumbrectangle[0]) * props.thumbscale ); + var y = Math.round( (props.viewrectangle[1]/props.scale - props.thumbrectangle[1]) * props.thumbscale ); + var w = Math.round( props.viewrectangle[2] * props.thumbscale / props.scale ); + var h = Math.round( props.viewrectangle[3] * props.thumbscale / props.scale ); + + var hide = false; + if (x<0 && y<0 && w>props.width-x && h>props.height-y) { + // Hide map + hide = true; + return { + hide: hide + }; + } else { + // Show map + hide = false; + } + + // Clip to bounds + // Left + if (x < 0) { + w += x; + x = 0; + viewrect.style.borderLeftColor = props.viewBoxBorder2; + } else { + viewrect.style.borderLeftColor = props.viewBoxBorder; + context.fillRect(0, 0, x, props.height); + } + // Top + if (y < 0) { + h += y; + y = 0; + viewrect.style.borderTopColor = props.viewBoxBorder2; + } else { + viewrect.style.borderTopColor = props.viewBoxBorder; + context.fillRect(x, 0, w, y); + } + // Right + if (w > props.width-x) { + w = props.width-x; + viewrect.style.borderRightColor = props.viewBoxBorder2; + } else { + viewrect.style.borderRightColor = props.viewBoxBorder; + context.fillRect(x+w, 0, props.width-(x+w), props.height); + } + // Bottom + if (h > props.height-y) { + h = props.height-y; + viewrect.style.borderBottomColor = props.viewBoxBorder2; + } else { + viewrect.style.borderBottomColor = props.viewBoxBorder; + context.fillRect(x, y+h, w, props.height-(y+h)); + } + + // Size and translate rect + viewrect.style.left = x+"px"; + viewrect.style.top = y+"px"; + viewrect.style.width = w+"px"; + viewrect.style.height = h+"px"; + + return { + hide: hide + }; + +} + +module.exports = { + render: renderViewRectangle +}; From 9488fcb5ab5e24b9b45b443120c3e3055193c841 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 13:05:03 +0100 Subject: [PATCH 09/14] the-graph-nav: Move style calculation out of Polymer element --- the-graph-nav/the-graph-nav.html | 16 +++++----------- the-graph-nav/the-graph-nav.js | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/the-graph-nav/the-graph-nav.html b/the-graph-nav/the-graph-nav.html index d4c6ed3d..8061d90d 100644 --- a/the-graph-nav/the-graph-nav.html +++ b/the-graph-nav/the-graph-nav.html @@ -119,17 +119,11 @@ this.scale = this.editor.scale; }, editorThemeChanged: function () { - if (this.editor.theme === "dark") { - this.viewBoxBorder = "hsla(190, 100%, 80%, 0.4)"; - this.viewBoxBorder2 = "hsla( 10, 60%, 32%, 0.3)"; - this.outsideFill = "hsla(0, 0%, 0%, 0.4)"; - this.backgroundColor = "hsla(0, 0%, 0%, 0.9)"; - } else { - this.viewBoxBorder = "hsla(190, 100%, 20%, 0.8)"; - this.viewBoxBorder2 = "hsla( 10, 60%, 80%, 0.8)"; - this.outsideFill = "hsla(0, 0%, 100%, 0.4)"; - this.backgroundColor = "hsla(0, 0%, 100%, 0.9)"; - } + var style = TheGraph.nav.calculateStyleFromTheme(this.theme); + this.backgroundColor = style.backgroundColor; + this.viewBoxBorder = style.viewBoxBorder; + this.viewBoxBorder2 = style.viewBoxBorder2; + this.outsideFill = style.outsideFill; this.style.backgroundColor = this.backgroundColor; // Redraw rectangle this.viewrectangleChanged(); diff --git a/the-graph-nav/the-graph-nav.js b/the-graph-nav/the-graph-nav.js index 741de46d..7c3e0a25 100644 --- a/the-graph-nav/the-graph-nav.js +++ b/the-graph-nav/the-graph-nav.js @@ -1,4 +1,20 @@ +function calculateStyleFromTheme(theme) { + var style = {}; + if (theme === "dark") { + style.viewBoxBorder = "hsla(190, 100%, 80%, 0.4)"; + style.viewBoxBorder2 = "hsla( 10, 60%, 32%, 0.3)"; + style.outsideFill = "hsla(0, 0%, 0%, 0.4)"; + style.backgroundColor = "hsla(0, 0%, 0%, 0.9)"; + } else { + style.viewBoxBorder = "hsla(190, 100%, 20%, 0.8)"; + style.viewBoxBorder2 = "hsla( 10, 60%, 80%, 0.8)"; + style.outsideFill = "hsla(0, 0%, 100%, 0.4)"; + style.backgroundColor = "hsla(0, 0%, 100%, 0.9)"; + } + return style; +} + function renderViewRectangle(context, viewrect, props) { context.clearRect(0, 0, props.width, props.height); @@ -71,5 +87,6 @@ function renderViewRectangle(context, viewrect, props) { } module.exports = { - render: renderViewRectangle + render: renderViewRectangle, + calculateStyleFromTheme: calculateStyleFromTheme, }; From b5ce8fb4ad26d8562d81f1bf9006162dca41ee52 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 13:20:53 +0100 Subject: [PATCH 10/14] the-graph: Move autolayout logic out of Polymer element --- index.js | 1 + the-graph/the-graph-autolayout.js | 56 +++++++++++++++++++++++++++++++ the-graph/the-graph.html | 52 ++-------------------------- 3 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 the-graph/the-graph-autolayout.js diff --git a/index.js b/index.js index 144b44ac..a43468f8 100644 --- a/index.js +++ b/index.js @@ -21,5 +21,6 @@ require("./the-graph/font-awesome-unicode-map.js").register(g); g.TheGraph.thumb = require('./the-graph-thumb/the-graph-thumb.js'); g.TheGraph.nav = require('./the-graph-nav/the-graph-nav.js'); +g.TheGraph.autolayout = require('./the-graph/the-graph-autolayout.js'); module.exports = g.TheGraph; diff --git a/the-graph/the-graph-autolayout.js b/the-graph/the-graph-autolayout.js new file mode 100644 index 00000000..c1aeeddc --- /dev/null +++ b/the-graph/the-graph-autolayout.js @@ -0,0 +1,56 @@ + +// NOTE: caller should wrap in a graph transaction, to group all changes made to @graph +function applyAutolayout(graph, keilerGraph, props) { + + // Update original graph nodes with the new coordinates from KIELER graph + var children = keilerGraph.children.slice(); + + var i, len; + for (i=0, len = children.length; i Date: Fri, 6 Jan 2017 13:49:55 +0100 Subject: [PATCH 11/14] the-graph: Move component merging logic out of Polymer element --- index.js | 1 + the-graph/the-graph-library.js | 63 ++++++++++++++++++++++++++++++++++ the-graph/the-graph.html | 60 +------------------------------- 3 files changed, 65 insertions(+), 59 deletions(-) create mode 100644 the-graph/the-graph-library.js diff --git a/index.js b/index.js index a43468f8..ef0ed1ec 100644 --- a/index.js +++ b/index.js @@ -22,5 +22,6 @@ require("./the-graph/font-awesome-unicode-map.js").register(g); g.TheGraph.thumb = require('./the-graph-thumb/the-graph-thumb.js'); g.TheGraph.nav = require('./the-graph-nav/the-graph-nav.js'); g.TheGraph.autolayout = require('./the-graph/the-graph-autolayout.js'); +g.TheGraph.library = require('./the-graph/the-graph-library.js'); module.exports = g.TheGraph; diff --git a/the-graph/the-graph-library.js b/the-graph/the-graph-library.js new file mode 100644 index 00000000..d1de5eb9 --- /dev/null +++ b/the-graph/the-graph-library.js @@ -0,0 +1,63 @@ +// Component library functionality +function mergeComponentDefinition(component, definition) { + // In cases where a component / subgraph ports change, + // we don't want the connections hanging in middle of node + // TODO visually indicate that port is a ghost + if (component === definition) { + return definition; + } + var _i, _j, _len, _len1, exists; + var cInports = component.inports; + var dInports = definition.inports; + + if (cInports !== dInports) { + for (_i = 0, _len = cInports.length; _i < _len; _i++) { + var cInport = cInports[_i]; + exists = false; + for (_j = 0, _len1 = dInports.length; _j < _len1; _j++) { + var dInport = dInports[_j]; + if (cInport.name === dInport.name) { + exists = true; + } + } + if (!exists) { + dInports.push(cInport); + } + } + } + + var cOutports = component.outports; + var dOutports = definition.outports; + + if (cOutports !== dOutports) { + for (_i = 0, _len = cOutports.length; _i < _len; _i++) { + var cOutport = cOutports[_i]; + exists = false; + for (_j = 0, _len1 = dOutports.length; _j < _len1; _j++) { + var dOutport = dOutports[_j]; + if (cOutport.name === dOutport.name) { + exists = true; + } + } + if (!exists) { + dOutports.push(cOutport); + } + } + } + + if (definition.icon !== 'cog') { + // Use the latest icon given + component.icon = definition.icon; + } else { + // we should use the icon from the library + definition.icon = component.icon; + } + // a component could also define a svg icon + definition.iconsvg = component.iconsvg; + + return definition; +} + +module.exports = { + mergeComponentDefinition: mergeComponentDefinition, +}; diff --git a/the-graph/the-graph.html b/the-graph/the-graph.html index ce68f698..456e9d6c 100644 --- a/the-graph/the-graph.html +++ b/the-graph/the-graph.html @@ -312,64 +312,6 @@ this.rerender({libraryDirty:true}); }.bind(this), 200); }, - mergeComponentDefinition: function (component, definition) { - // In cases where a component / subgraph ports change, - // we don't want the connections hanging in middle of node - // TODO visually indicate that port is a ghost - if (component === definition) { - return definition; - } - var _i, _j, _len, _len1, exists; - var cInports = component.inports; - var dInports = definition.inports; - - if (cInports !== dInports) { - for (_i = 0, _len = cInports.length; _i < _len; _i++) { - var cInport = cInports[_i]; - exists = false; - for (_j = 0, _len1 = dInports.length; _j < _len1; _j++) { - var dInport = dInports[_j]; - if (cInport.name === dInport.name) { - exists = true; - } - } - if (!exists) { - dInports.push(cInport); - } - } - } - - var cOutports = component.outports; - var dOutports = definition.outports; - - if (cOutports !== dOutports) { - for (_i = 0, _len = cOutports.length; _i < _len; _i++) { - var cOutport = cOutports[_i]; - exists = false; - for (_j = 0, _len1 = dOutports.length; _j < _len1; _j++) { - var dOutport = dOutports[_j]; - if (cOutport.name === dOutport.name) { - exists = true; - } - } - if (!exists) { - dOutports.push(cOutport); - } - } - } - - if (definition.icon !== 'cog') { - // Use the latest icon given - component.icon = definition.icon; - } else { - // we should use the icon from the library - definition.icon = component.icon; - } - // a component could also define a svg icon - definition.iconsvg = component.iconsvg; - - return definition; - }, registerComponent: function (definition, generated) { var component = this.library[definition.name]; var def = definition; @@ -378,7 +320,7 @@ // Don't override real one with generated dummy return; } - def = this.mergeComponentDefinition(component, definition); + def = TheGraph.library.mergeComponentDefinition(component, definition); } this.library[definition.name] = def; // So changes are rendered From 62b67fdb0d26f261d0a634ceb9a03a496a001f20 Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 14:06:48 +0100 Subject: [PATCH 12/14] the-graph-editor: Move component creation from graph out of Polymer element --- the-graph-editor/the-graph-editor.html | 81 +----------------------- the-graph/the-graph-library.js | 85 ++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 78 deletions(-) diff --git a/the-graph-editor/the-graph-editor.html b/the-graph-editor/the-graph-editor.html index 64b71365..50281ae8 100644 --- a/the-graph-editor/the-graph-editor.html +++ b/the-graph-editor/the-graph-editor.html @@ -286,84 +286,9 @@ // TODO what about loading a new graph? Are we making a new editor? return; }*/ - - fbpGraph.nodes.forEach(function (node) { - var component = { - name: node.component, - icon: 'cog', - description: '', - inports: [], - outports: [] - }; - - Object.keys(fbpGraph.inports).forEach(function (pub) { - var exported = fbpGraph.inports[pub]; - if (exported.process === node.id) { - for (var i = 0; i < component.inports.length; i++) { - if (component.inports[i].name === exported.port) { - return; - } - } - component.inports.push({ - name: exported.port, - type: 'all' - }); - } - }); - Object.keys(fbpGraph.outports).forEach(function (pub) { - var exported = fbpGraph.outports[pub]; - if (exported.process === node.id) { - for (var i = 0; i < component.outports.length; i++) { - if (component.outports[i].name === exported.port) { - return; - } - } - component.outports.push({ - name: exported.port, - type: 'all' - }); - } - }); - fbpGraph.initializers.forEach(function (iip) { - if (iip.to.node === node.id) { - for (var i = 0; i < component.inports.length; i++) { - if (component.inports[i].name === iip.to.port) { - return; - } - } - component.inports.push({ - name: iip.to.port, - type: 'all' - }); - } - }); - - fbpGraph.edges.forEach(function (edge) { - var i; - if (edge.from.node === node.id) { - for (i = 0; i < component.outports.length; i++) { - if (component.outports[i].name === edge.from.port) { - return; - } - } - component.outports.push({ - name: edge.from.port, - type: 'all' - }); - } - if (edge.to.node === node.id) { - for (i = 0; i < component.inports.length; i++) { - if (component.inports[i].name === edge.to.port) { - return; - } - } - component.inports.push({ - name: edge.to.port, - type: 'all' - }); - } - }); - this.registerComponent(component, true); + var components = TheGraph.library.componentsFromGraph(fbpGraph); + components.forEach(function(component) { + this.registerComponent(component, true); }.bind(this)); }, registerComponent: function (definition, generated) { diff --git a/the-graph/the-graph-library.js b/the-graph/the-graph-library.js index d1de5eb9..ae2774cf 100644 --- a/the-graph/the-graph-library.js +++ b/the-graph/the-graph-library.js @@ -58,6 +58,91 @@ function mergeComponentDefinition(component, definition) { return definition; } +function componentsFromGraph(fbpGraph) { + var components = []; + + fbpGraph.nodes.forEach(function (node) { + var component = { + name: node.component, + icon: 'cog', + description: '', + inports: [], + outports: [] + }; + + Object.keys(fbpGraph.inports).forEach(function (pub) { + var exported = fbpGraph.inports[pub]; + if (exported.process === node.id) { + for (var i = 0; i < component.inports.length; i++) { + if (component.inports[i].name === exported.port) { + return; + } + } + component.inports.push({ + name: exported.port, + type: 'all' + }); + } + }); + Object.keys(fbpGraph.outports).forEach(function (pub) { + var exported = fbpGraph.outports[pub]; + if (exported.process === node.id) { + for (var i = 0; i < component.outports.length; i++) { + if (component.outports[i].name === exported.port) { + return; + } + } + component.outports.push({ + name: exported.port, + type: 'all' + }); + } + }); + fbpGraph.initializers.forEach(function (iip) { + if (iip.to.node === node.id) { + for (var i = 0; i < component.inports.length; i++) { + if (component.inports[i].name === iip.to.port) { + return; + } + } + component.inports.push({ + name: iip.to.port, + type: 'all' + }); + } + }); + + fbpGraph.edges.forEach(function (edge) { + var i; + if (edge.from.node === node.id) { + for (i = 0; i < component.outports.length; i++) { + if (component.outports[i].name === edge.from.port) { + return; + } + } + component.outports.push({ + name: edge.from.port, + type: 'all' + }); + } + if (edge.to.node === node.id) { + for (i = 0; i < component.inports.length; i++) { + if (component.inports[i].name === edge.to.port) { + return; + } + } + component.inports.push({ + name: edge.to.port, + type: 'all' + }); + } + }); + components.push(component); + }); + return components; +} + module.exports = { mergeComponentDefinition: mergeComponentDefinition, + componentsFromGraph: componentsFromGraph, }; From 0f258cae281347bc6c3f2493e3725280696c2e4c Mon Sep 17 00:00:00 2001 From: Jon Nordby Date: Fri, 6 Jan 2017 14:28:35 +0100 Subject: [PATCH 13/14] the-graph-editor: Move default menus out of Polymer element --- index.js | 1 + the-graph-editor/the-graph-editor.html | 164 +---------------------- the-graph-editor/the-graph-editor.js | 175 +++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 163 deletions(-) create mode 100644 the-graph-editor/the-graph-editor.js diff --git a/index.js b/index.js index ef0ed1ec..162b4b7e 100644 --- a/index.js +++ b/index.js @@ -23,5 +23,6 @@ g.TheGraph.thumb = require('./the-graph-thumb/the-graph-thumb.js'); g.TheGraph.nav = require('./the-graph-nav/the-graph-nav.js'); g.TheGraph.autolayout = require('./the-graph/the-graph-autolayout.js'); g.TheGraph.library = require('./the-graph/the-graph-library.js'); +g.TheGraph.editor = require('./the-graph-editor/the-graph-editor.js'); module.exports = g.TheGraph; diff --git a/the-graph-editor/the-graph-editor.html b/the-graph-editor/the-graph-editor.html index 50281ae8..2e61ff22 100644 --- a/the-graph-editor/the-graph-editor.html +++ b/the-graph-editor/the-graph-editor.html @@ -44,169 +44,7 @@ forceSelection: false, created: function () { this.pan = [0,0]; - var pasteAction = function (graph, itemKey, item) { - var pasted = TheGraph.Clipboard.paste(graph); - this.selectedNodes = pasted.nodes; - this.selectedEdges = []; - }.bind(this); - var pasteMenu = { - icon: "paste", - iconLabel: "paste", - action: pasteAction - }; - // Default context menu defs - - var nodeActions = { - delete: function (graph, itemKey, item) { - graph.removeNode(itemKey); - // Remove selection - var newSelection = []; - for (var i=0, len=this.selectedNodes.length; i Date: Fri, 6 Jan 2017 14:47:00 +0100 Subject: [PATCH 14/14] CHANGES: Update --- CHANGES.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 062a71e4..499a16db 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,14 @@ ## dev +## 0.7.0 (unreleased) + +Breaking changes + +* Polymer elements no longer automatically include the neccesary JS files. +Instead users must include `dist/the-graph.js`, which bundles the needed JavaScript and provides API under `window.TheGraph`. +The file is included in `the-graph` NPM packages. +This is preparation for removing the Polymer dependency, instead providing JS APIs and React components. + ## 0.6.0 (2017 January 5) * Add all dependencies besides Polymer to NPM.