Skip to content

Commit

Permalink
Refactoring structure
Browse files Browse the repository at this point in the history
  • Loading branch information
luizguilhermesj committed Aug 26, 2018
1 parent 62da546 commit 1159ff4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 184 deletions.
2 changes: 0 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import './css/App.css';

import React, { Component } from 'react';
import Container from './components/Container';
import Positioning from './services/Positioning';


import mockEntities from './fixtures/EntitiesMock';
Expand All @@ -22,7 +21,6 @@ class App extends Component {

componentWillMount() {
this.fetchEntity()
.then(root => Positioning.tree(root))
.then(root => this.hydrateObjectives(root));
}

Expand Down
143 changes: 18 additions & 125 deletions src/components/Container.js
Original file line number Diff line number Diff line change
@@ -1,152 +1,45 @@
import React, { Component } from 'react';
import Viewport from './Viewport';
import Positioning from '../services/Positioning';

class Container extends Component {
constructor(props) {
super(props);

this.state = {
nodes: [],
edges: [],
depthMap: {},
bounds: { x: 0, y: 0 },
offset: { x: 0, y: 0 }
nodes: []
};
}

componentDidMount() {
this.updateBounds();
this.updateGraph();
}

updateBounds() {
this.setState({
bounds: {
x: window.innerWidth,
y: window.innerHeight
}
});
}

updateGraph() {
const root = this.props.root;

this.hydrateNodes(root, null, 0);

const depthMap = this.getDepthMap();
const edges = this.getEdges(depthMap);

this.setState({ edges, depthMap });

/*
root.objectives.forEach( objective => {
nodes.push({
id: `objective__${objective.id}`,
label: objective.title
type: 'objective',
depth: depth
});
});
*/
componentWillMount() {
let nodes = this.hydrateNodes(this.props.root, null);
nodes = [Positioning.tree(nodes)];
this.setState({ nodes });
}

hydrateNodes(root, parentId, depth) {
const nodeId = `${root.name}__${root.id}`;
hydrateNodes(root, depth, removeId) {
root.depth = depth;
root.children = root.child_entities || [];

this.pushNode({
id: nodeId,
parentId: parentId,
label: root.name,
type: root.name,
depth: depth,
position: root.position
});
root.children.forEach(child => this.hydrateNodes(child, depth + 1));

if (! root.child_entities) root.child_entities = [];
root.child_entities.forEach(child => this.hydrateNodes(child, nodeId, depth + 1));
return root;
}

getEdges(depthMap = null) {
if( ! depthMap )
depthMap = this.state;

const edges = [];
Object.keys(depthMap).forEach(depth => {
// eslint-disable-next-line
depth = parseInt(depth);

if( depth === 0 )
return;

const parentLevel = depthMap[depth - 1];
const currentLevel = depthMap[depth];
removeNode(id) {
console.log(this);
let nodes = this.hydrateNodes(this.state.nodes, null, id);

currentLevel.forEach( currentLevelNode => {
const matchedNodes = parentLevel.filter( parentLevelNode => parentLevelNode.id === currentLevelNode.parentId );

matchedNodes.forEach( parentMatch => {
edges.push({
parent: parentMatch.id,
child: currentLevelNode.id
});
});
});
});

return edges;
}

pushNode(node) {
const nodes = this.state.nodes;
nodes.push(node);
nodes = [Positioning.tree(nodes)];
this.setState({ nodes });
}

pushEdge(edge) {
const edges = this.state.edges;
edges.push(edge);
this.setState({ edges });
}

updateOffset(x, y) {
this.setState({
offsets: { x, y }
});
}

getDepthMap() {
const { nodes } = this.state;

const nodesSorted = nodes.sort((a, b) => a.depth - b.depth);
const depthMap = nodesSorted.reduce((depthMap, node) => {
if( ! depthMap[node.depth] )
depthMap[node.depth] = [];

depthMap[node.depth].push(node);

return depthMap;
}, {} );

return depthMap;
}

render() {
const { bounds, offset, nodes, edges, depthMap } = this.state;

const style = {
width: bounds.x,
height: bounds.y,
left: offset.x,
top: offset.y
};

return (
<div className="container" style={style}>
<div className="container">
<Viewport
nodes={nodes}
edges={edges}
depthMap={depthMap}
updateOffset={this.updateOffset.bind(this)}
nodes={this.state.nodes}
removeNode={this.removeNode}
/>
</div>
);
Expand Down
57 changes: 16 additions & 41 deletions src/components/Viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,37 @@ class Viewport extends Component {

this.state = { domNodes: [] };
}

componentDidUpdate(prevProps) {
if( ! prevProps.edges.length )
this.createNodesForDom();
componentWillMount(prevProps) {
const domNodes = this.createNodesForDom(this.props.nodes);
this.setState({ domNodes });
}

createNodesForDom() {
const domNodes = [];
const { depthMap, edges } = this.props;
console.log(this.props);
const rows = {};

Object.keys(depthMap).forEach(depth => {
let rowWidth = 0;
let rowHeight = 0;

depthMap[depth].forEach((node, xDepth) => {
const style = {
top: depth * 100,
left: rowWidth + xDepth * 100
};
createNodesForDom(nodes) {
if (nodes.length == 0) return [];

rowWidth += node.label.length * 6;
let node = nodes.shift();

domNodes.push({
style: style,
node: node,
width: node.label.length * 6
});
});
node.style = {
top: node.position.offsetY,
left: node.position.offsetX
};

rows[depth] = {
width: rowWidth,
nodeCount: depthMap[depth].length
};
});

domNodes[0].style.left = (rows[1].nodeCount * 100 + rows[1].width) / 2 - domNodes[0].width;


this.setState({ domNodes });
return [node, ...this.createNodesForDom(nodes), ...this.createNodesForDom(node.children)];
}

render() {
// const nodes = this.createNodesForDom();
const { domNodes } = this.state;

return (
<div className="viewport">
{ domNodes.map( o =>
{ domNodes.map( (o,i) =>
<div
className={`node node--${o.node.type}`}
className={`node node--${o.type}`}
style={o.style}
key={o.node.id}
key={o.id}
>
{ o.node.label }
{ o.name }
</div>
) }
</div>
Expand Down
12 changes: 7 additions & 5 deletions src/css/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
}

.node {
border-radius: 500px;
width: auto;
height: auto;
max-width: 100px;
border-radius: 100%;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border: 1px solid #000;
position: absolute;
text-align: center;
padding: 5px;
font-family: monospace;
font-size: 12px;
Expand Down
36 changes: 25 additions & 11 deletions src/services/Positioning.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,47 @@
const DEFAULTS = {
canvas: {
height: 1000,
width: 1000
width: window.innerWidth
},
nodes: {
width: 100,
height: 100,
width: 112,
height: 112,
}
}

class Positioning {

updateTreePosition(root, levelNodesCount = 1) {
let nodes_width = DEFAULTS.nodes.width * levelNodesCount;
let in_between = Math.floor((DEFAULTS.canvas.height - nodes_width) / levelNodesCount);

updateTreePosition(root, depthNodesCount = 0, column = 0) {
root.position = {
width: DEFAULTS.nodes.width,
in_between: in_between
offsetX: this.getOffsetX(DEFAULTS.canvas.width, DEFAULTS.nodes.width, depthNodesCount, column),
offsetY: this.getOffsetY(DEFAULTS.nodes.height, root.depth, depthNodesCount, column)
}

if (! root.child_entities) return root;

levelNodesCount = root.child_entities.length;
root.child_entities.forEach(child => this.updateTreePosition(child, levelNodesCount));
depthNodesCount = root.child_entities.length;
root.child_entities.map( (child, pos) => this.updateTreePosition(child, depthNodesCount, pos));

return root;
}

getOffsetX(canvasWidth, width, depthNodesCount, column) {
let nodes_width = width * depthNodesCount;
let inBetween = depthNodesCount !== 0 ? Math.floor((canvasWidth - nodes_width) / depthNodesCount) : canvasWidth / 2;

return ((inBetween * (column + 1)) + column * width) - (width / 2)
}

getOffsetY(height, depth, depthNodesCount, column) {
let middle = (depthNodesCount - 1) / 2;
let offsetY = ((height * (depth + 1)) + depth * height / 2);

column = column > middle ? depthNodesCount - 1 - column : column;


return offsetY + offsetY * 0.2 * column;
}

tree(root) {
return this.updateTreePosition(root);
}
Expand Down

0 comments on commit 1159ff4

Please sign in to comment.