Custom layout engine

This commit is contained in:
futpib 2018-11-14 06:04:39 +03:00
parent c3deec41d7
commit e2b2a4fc55
3 changed files with 70 additions and 16 deletions

View File

@ -1,5 +1,9 @@
/* global document */ /* global document */
const {
merge,
} = require('ramda');
const r = require('r-dom'); const r = require('r-dom');
const { const {
@ -13,8 +17,18 @@ const math = require('mathjs');
class GraphView extends GraphViewBase { class GraphView extends GraphViewBase {
constructor(props) { constructor(props) {
if (!props.layoutEngine) {
props = merge(props, {
layoutEngineType: 'None',
});
}
super(props); super(props);
if (props.layoutEngine) {
this.layoutEngine = props.layoutEngine;
}
Object.assign(this, { Object.assign(this, {
_super_handleNodeMove: this.handleNodeMove, _super_handleNodeMove: this.handleNodeMove,
handleNodeMove: this.constructor.prototype.handleNodeMove.bind(this), handleNodeMove: this.constructor.prototype.handleNodeMove.bind(this),
@ -27,6 +41,16 @@ class GraphView extends GraphViewBase {
}); });
} }
static getDerivedStateFromProps(props, state) {
const derivedState = super.getDerivedStateFromProps(props, state);
if (props.layoutEngine) {
derivedState.nodes = props.layoutEngine.adjustNodes(derivedState.nodes, derivedState.nodesMap);
}
return derivedState;
}
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return super.shouldComponentUpdate(nextProps, nextState) || return super.shouldComponentUpdate(nextProps, nextState) ||
this.state.edgeEndNode !== nextState.edgeEndNode; this.state.edgeEndNode !== nextState.edgeEndNode;
@ -123,6 +147,10 @@ class GraphView extends GraphViewBase {
} }
} }
GraphView.defaultProps = merge(GraphViewBase.defaultProps, {
layoutEngineType: null,
});
const size = 120; const size = 120;
class Node extends NodeBase { class Node extends NodeBase {

View File

@ -41,6 +41,8 @@ const {
Edge, Edge,
} = require('./base'); } = require('./base');
const LayoutEngine = require('./layout-engine');
const dgoToPai = new WeakMap(); const dgoToPai = new WeakMap();
const key = pao => `${pao.type}-${pao.index}`; const key = pao => `${pao.type}-${pao.index}`;
@ -422,6 +424,8 @@ const renderEdgeText = state => ({ data: dgo, transform, selected }) => {
])); ]));
}; };
const layoutEngine = new LayoutEngine();
class Graph extends React.Component { class Graph extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -579,22 +583,6 @@ class Graph extends React.Component {
return filteredNodeKeys.has(edge.source) && filteredNodeKeys.has(edge.target); return filteredNodeKeys.has(edge.source) && filteredNodeKeys.has(edge.target);
}, edges); }, edges);
nodes.forEach(node => {
if (node.x !== undefined) {
return;
}
if (node.type === 'source') {
node.x = 0 * size;
} else if (node.type === 'sink') {
node.x = 10 * size;
} else {
node.x = (2 * size) + (Math.round(6 * Math.random()) * size);
}
node.y = Math.random() * 1200;
});
nodes.forEach(node => { nodes.forEach(node => {
const pai = getPaiByTypeAndIndex(node.type, node.index)({ pulse: this.props }); const pai = getPaiByTypeAndIndex(node.type, node.index)({ pulse: this.props });
dgoToPai.set(node, pai); dgoToPai.set(node, pai);
@ -632,6 +620,8 @@ class Graph extends React.Component {
edgeArrowSize: 64, edgeArrowSize: 64,
layoutEngine,
backgroundFillId: '#background-pattern', backgroundFillId: '#background-pattern',
renderDefs, renderDefs,

View File

@ -0,0 +1,36 @@
const size = 200;
module.exports = class LayoutEngine {
constructor(graphViewProps) {
this.graphViewProps = graphViewProps;
}
calculatePosition(node) {
return node;
}
adjustNodes(nodes, nodesMap) {
nodes.forEach(node => {
if (node.x !== undefined) {
return;
}
if (node.type === 'source') {
node.x = 0 * size;
} else if (node.type === 'sink') {
node.x = 10 * size;
} else {
node.x = (2 * size) + (Math.round(6 * Math.random()) * size);
}
node.y = Math.random() * 1200;
});
return nodes;
}
getPositionForNode(node) {
return this.calculatePosition(node);
}
};