diff --git a/client/app/scripts/charts/edge.js b/client/app/scripts/charts/edge.js
index c7bb9f4ccb..97797195f4 100644
--- a/client/app/scripts/charts/edge.js
+++ b/client/app/scripts/charts/edge.js
@@ -1,5 +1,7 @@
+const _ = require('lodash');
const d3 = require('d3');
const React = require('react');
+const Spring = require('react-motion').Spring;
const AppActions = require('../actions/app-actions');
@@ -8,19 +10,81 @@ const line = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
+const animConfig = [80, 20]; // stiffness, bounce
+
+const flattenPoints = function(points) {
+ const flattened = {};
+ points.forEach(function(point, i) {
+ flattened['x' + i] = {val: point.x, config: animConfig};
+ flattened['y' + i] = {val: point.y, config: animConfig};
+ });
+ return flattened;
+};
+
+const extractPoints = function(points) {
+ const extracted = [];
+ _.each(points, function(value, key) {
+ const axis = key[0];
+ const index = key.slice(1);
+ if (!extracted[index]) {
+ extracted[index] = {};
+ }
+ extracted[index][axis] = value.val;
+ });
+ return extracted;
+};
+
const Edge = React.createClass({
+ getInitialState: function() {
+ return {
+ points: []
+ };
+ },
+
+ componentWillMount: function() {
+ this.ensureSameLength(this.props.points);
+ },
+
+ componentWillReceiveProps: function(nextProps) {
+ this.ensureSameLength(nextProps.points);
+ },
+
render: function() {
const className = this.props.highlighted ? 'edge highlighted' : 'edge';
+ const points = flattenPoints(this.props.points);
+ const props = this.props;
+ const handleMouseEnter = this.handleMouseEnter;
+ const handleMouseLeave = this.handleMouseLeave;
return (
-
-
-
-
+
+ {function(interpolated) {
+ const path = line(extractPoints(interpolated));
+ return (
+
+
+
+
+ );
+ }}
+
);
},
+ ensureSameLength: function(points) {
+ // Spring needs constant list length, hoping that dagre will insert never more than 10
+ const length = 10;
+ let missing = length - points.length;
+
+ while (missing) {
+ points.unshift(points[0]);
+ missing = length - points.length;
+ }
+
+ return points;
+ },
+
handleMouseEnter: function(ev) {
AppActions.enterEdge(ev.currentTarget.id);
},
diff --git a/client/app/scripts/charts/node.js b/client/app/scripts/charts/node.js
index e47691470c..eff188b02d 100644
--- a/client/app/scripts/charts/node.js
+++ b/client/app/scripts/charts/node.js
@@ -1,46 +1,16 @@
const React = require('react');
-const tweenState = require('react-tween-state');
+const Spring = require('react-motion').Spring;
const AppActions = require('../actions/app-actions');
const NodeColorMixin = require('../mixins/node-color-mixin');
const Node = React.createClass({
mixins: [
- NodeColorMixin,
- tweenState.Mixin
+ NodeColorMixin
],
- getInitialState: function() {
- return {
- x: 0,
- y: 0
- };
- },
-
- componentWillMount: function() {
- // initial node position when rendered the first time
- this.setState({
- x: this.props.dx,
- y: this.props.dy
- });
- },
-
- componentWillReceiveProps: function(nextProps) {
- // animate node transition to next position
- this.tweenState('x', {
- easing: tweenState.easingTypes.easeInOutQuad,
- duration: 500,
- endValue: nextProps.dx
- });
- this.tweenState('y', {
- easing: tweenState.easingTypes.easeInOutQuad,
- duration: 500,
- endValue: nextProps.dy
- });
- },
-
render: function() {
- const transform = 'translate(' + this.getTweeningValue('x') + ',' + this.getTweeningValue('y') + ')';
+ const props = this.props;
const scale = this.props.scale;
const textOffsetX = 0;
const textOffsetY = scale(0.5) + 18;
@@ -50,6 +20,8 @@ const Node = React.createClass({
const onMouseEnter = this.handleMouseEnter;
const onMouseLeave = this.handleMouseLeave;
const classNames = ['node'];
+ const ellipsis = this.ellipsis;
+ const animConfig = [80, 20]; // stiffness, bounce
if (this.props.highlighted) {
classNames.push('highlighted');
@@ -60,19 +32,26 @@ const Node = React.createClass({
}
return (
-
- {this.props.highlighted && }
-
-
-
-
- {this.ellipsis(this.props.label, 14)}
-
-
- {this.ellipsis(this.props.subLabel, 12)}
-
-
+
+ {function(interpolated) {
+ const transform = 'translate(' + interpolated.x.val + ',' + interpolated.y.val + ')';
+ return (
+
+ {props.highlighted && }
+
+
+
+
+ {ellipsis(props.label, 14)}
+
+
+ {ellipsis(props.subLabel, 12)}
+
+
+ );
+ }}
+
);
},
diff --git a/client/package.json b/client/package.json
index c14726dc49..0d38001c60 100644
--- a/client/package.json
+++ b/client/package.json
@@ -20,6 +20,7 @@
"object-assign": "^2.0.0",
"page": "^1.6.3",
"react": "^0.13.3",
+ "react-motion": "^0.2.7",
"react-tap-event-plugin": "^0.1.7",
"react-tween-state": "0.0.5",
"reqwest": "~1.1.5",