diff --git a/CHANGES.md b/CHANGES.md
index 378cfa8c..2ee6947e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,21 @@
## dev
+## 0.10.0 (unreleased)
+
+Breaking changes
+
+* Polymer element `the-graph-thumb` has been removed.
+Should instead use the JavaScript API `TheGraph.thumb.render()`,
+as shown in `examples/demo-thumbnail.html`.
+* Polymer element `the-graph-nav` has been removed.
+Should instead use the new React component `TheGraph.nav.Component`,
+as shown in `examples/demo-full.html`
+
+Internal changes
+
+* All dependencies except Polymer (deprecated) are installed via NPM
+* Some more modules have been converted to proper CommonJS
+
## 0.9.0 (2017 May 6)
New features
diff --git a/examples/demo-full.html b/examples/demo-full.html
index 1f293de3..7ceb963e 100644
--- a/examples/demo-full.html
+++ b/examples/demo-full.html
@@ -18,7 +18,6 @@
-
@@ -76,7 +75,7 @@
theme="dark">
-
+
autolayout
@@ -113,22 +112,40 @@
// Remove loading message
var loading = document.getElementById("loading");
loading.parentNode.removeChild(loading);
+
+ renderNav();
});
// Attach nav
- var nav = document.getElementById('nav');
- editor.addEventListener('viewchanged', function(e) {
- nav.view = e.detail;
- });
- nav.addEventListener('panto', function(e) {
- var pan = e.detail;
+ function fitGraphInView() {
+ editor.triggerFit();
+ }
+ function panEditorTo(pan) {
editor.pan[0] = pan.x;
editor.pan[1] = pan.y;
- });
- nav.addEventListener('tap', function() {
- editor.triggerFit();
- });
-
+ }
+ function renderNav() {
+ var props = {
+ height: 162,
+ width: 216,
+ graph: editor.graph,
+ onTap: fitGraphInView,
+ onPanTo: panEditorTo,
+ viewrectangle: [
+ -editor.pan[0],
+ -editor.pan[1],
+ editor.width,
+ editor.height
+ ],
+ viewscale: editor.scale,
+ };
+
+ var element = React.createElement(TheGraph.nav.Component, props);
+ ReactDOM.render(element, document.getElementById('nav'));
+ }
+ editor.graph.on('endTransaction', renderNav); // graph changed
+ editor.addEventListener('viewchanged', renderNav); // editor viewport changed
+
// Simulate a library update
setTimeout(function () {
var originalComponent = editor.getComponent('core/Split');
@@ -206,7 +223,6 @@
document.getElementById("theme").addEventListener("click", function () {
theme = (theme==="dark" ? "light" : "dark");
editor.theme = theme;
- nav.theme = theme;
});
// Focus a node
diff --git a/examples/demo-thumbnail.html b/examples/demo-thumbnail.html
index c7eb36c2..6717494f 100644
--- a/examples/demo-thumbnail.html
+++ b/examples/demo-thumbnail.html
@@ -1,36 +1,42 @@
-
the-graph-thumb documentation
+
the-graph-thumb example
-
-
-
-
-
+
diff --git a/spec/runner.html b/spec/runner.html
index 0356d283..64938c72 100644
--- a/spec/runner.html
+++ b/spec/runner.html
@@ -50,8 +50,6 @@
theme="dark">
-
-
diff --git a/the-graph-nav/the-graph-nav.html b/the-graph-nav/the-graph-nav.html
deleted file mode 100644
index c40d0419..00000000
--- a/the-graph-nav/the-graph-nav.html
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/the-graph-nav/the-graph-nav.js b/the-graph-nav/the-graph-nav.js
index 7c3e0a25..275f8ee7 100644
--- a/the-graph-nav/the-graph-nav.js
+++ b/the-graph-nav/the-graph-nav.js
@@ -1,4 +1,6 @@
+var thumb = require('../the-graph-thumb/the-graph-thumb.js');
+
function calculateStyleFromTheme(theme) {
var style = {};
if (theme === "dark") {
@@ -86,7 +88,175 @@ function renderViewRectangle(context, viewrect, props) {
}
+function renderThumbnailFromProps(context, props) {
+ var style = {};
+ for (var name in props) {
+ style[name] = props[name];
+ }
+ style.graph = null;
+ style.lineWidth = props.nodeLineWidth;
+ var info = thumb.render(context, props.graph, style);
+ return info;
+}
+function renderViewboxFromProps(context, viewbox, thumbInfo, props) {
+ var style = {};
+ for (var name in props) {
+ style[name] = props[name];
+ }
+ style.graph = null;
+ style.scale = props.viewscale;
+ var thumbW = thumbInfo.rectangle[2];
+ var thumbH = thumbInfo.rectangle[3];
+ style.thumbscale = (thumbW>thumbH) ? props.width/thumbW : props.height/thumbH;
+ style.thumbrectangle = thumbInfo.rectangle;
+ var info = renderViewRectangle(context, viewbox, style);
+ return info;
+}
+
+// https://toddmotto.com/react-create-class-versus-component/
+var Component = React.createClass({
+ propTypes: {
+ },
+ getDefaultProps: function() {
+ return {
+ width: 200,
+ height: 150,
+ hidden: false, // FIXME: drop??
+ backgroundColor: "hsla(184, 8%, 75%, 0.9)",
+ outsideFill: "hsla(0, 0%, 0%, 0.4)",
+ nodeSize: 60,
+ nodeLineWidth: 1,
+ viewrectangle: [0, 0, 0, 0],
+ viewscale: 1.0,
+ viewBoxBorder: "hsla(190, 100%, 80%, 0.4)",
+ viewBoxBorder2: "hsla( 10, 60%, 32%, 0.3)",
+ viewBoxBorderStyle: 'dotted',
+ graph: null, // NOTE: should not attach to events, that is responsibility of outer code
+ };
+ },
+ getInitialState: function() {
+ return {
+ thumbscale: 1.0,
+ currentPan: [0.0, 0.0],
+ };
+ },
+ render: function() {
+ var p = this.props;
+ var thumbStyle = {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ };
+ var wrapperStyle = {
+ height: p.height,
+ width: p.width,
+ overflow: "hidden",
+ cursor: "move",
+ backgroundColor: p.backgroundColor,
+ };
+ var thumbProps = {
+ key: 'thumb',
+ ref: this._refThumbCanvas,
+ width: p.width,
+ height: p.height,
+ style: thumbStyle,
+ };
+ var viewboxCanvas = {
+ key: 'viewbox',
+ ref: this._refViewboxCanvas,
+ width: p.width,
+ height: p.height,
+ style: thumbStyle,
+ };
+ // FIXME: find better way to populate the props from render function
+ var viewboxDiv = {
+ key: 'viewboxdiv',
+ ref: this._refViewboxElement,
+ style: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ width: p.width,
+ height: p.height,
+ borderStyle: 'dotted',
+ borderWidth: 1,
+ },
+ };
+ // Elements
+ var d = React.DOM;
+ return d.div( { key: 'nav', style: wrapperStyle, ref: this._refTopElement }, [
+ d.div( viewboxDiv ),
+ d.canvas( viewboxCanvas ),
+ d.canvas( thumbProps ),
+ ]);
+ },
+ componentDidUpdate: function() {
+ this._updatePan();
+ this._renderElements();
+ },
+ componentDidMount: function() {
+ this._updatePan();
+ this._renderElements();
+ this._setupEvents();
+ },
+ _refThumbCanvas: function(canvas) {
+ this._thumbContext = canvas.getContext('2d');
+ },
+ _refViewboxCanvas: function(canvas) {
+ this._viewboxContext = canvas.getContext('2d');
+ },
+ _refViewboxElement: function(el) {
+ this._viewboxElement = el;
+ },
+ _refTopElement: function(el) {
+ this._topElement = el;
+ },
+ _renderElements: function() {
+ var t = renderThumbnailFromProps(this._thumbContext, this.props);
+ //this.state.thumbscale = t.scale;
+ renderViewboxFromProps(this._viewboxContext, this._viewboxElement, t, this.props);
+ },
+ _updatePan: function() {
+ this.state.currentPan = [
+ -(this.props.viewrectangle[0]),
+ -(this.props.viewrectangle[1]),
+ ];
+ },
+ _setupEvents: function() {
+ this.hammer = new Hammer.Manager(this._topElement, {
+ recognizers: [
+ [ Hammer.Tap ],
+ [ Hammer.Pan, { direction: Hammer.DIRECTION_ALL } ],
+ ],
+ });
+ this.hammer.on('tap', (function(event) {
+ if (this.props.onTap) {
+ this.props.onTap(null, event);
+ }
+ }).bind(this));
+ this.hammer.on('panmove', (function(event) {
+ if (this.props.onPanTo) {
+ // Calculate where event pans to, in editor coordinates
+ var x = this.state.currentPan[0];
+ var y = this.state.currentPan[1];
+ var panscale = this.state.thumbscale / this.props.viewscale;
+ console.log('panmove', event.deltaX, event.deltaY, panscale, this.state.thumbscale, this.props.viewscale);
+ x -= event.deltaX / panscale;
+ y -= event.deltaY / panscale;
+ var panTo = { x: Math.round(x), y: Math.round(y) };
+ // keep track of the current pan, because prop/component update
+ // may be delayed, or never arrive.
+ this.state.currentPan[0] = panTo.x;
+ this.state.currentPan[1] = panTo.y;
+ this.props.onPanTo(panTo, event);
+ }
+ }).bind(this));
+ }
+});
+
+
module.exports = {
render: renderViewRectangle,
calculateStyleFromTheme: calculateStyleFromTheme,
+ Component: Component,
};
diff --git a/the-graph-thumb/the-graph-thumb.html b/the-graph-thumb/the-graph-thumb.html
deleted file mode 100644
index 3623a2bd..00000000
--- a/the-graph-thumb/the-graph-thumb.html
+++ /dev/null
@@ -1,112 +0,0 @@
-
-
-
-
-
-
-
-