Skip to content

Instantly share code, notes, and snippets.

@gregberge
Created November 10, 2017 11:08
Show Gist options
  • Save gregberge/052153dc26f46f434b49883e3bc28fae to your computer and use it in GitHub Desktop.
Save gregberge/052153dc26f46f434b49883e3bc28fae to your computer and use it in GitHub Desktop.
Exercice JS training.
import Node from './Node'
const context = {
interdistances: {
A: { A: 10, B: 50, C: 120 },
B: { A: 50, B: 10, C: 30 },
C: { A: 120, B: 80, C: 10 },
},
}
const motor1 = new Node({ data: { type: 'motor', power: 5 }, context })
const motor2 = new Node({ data: { type: 'motor', power: 5 }, context })
const computeCableData = node => {
const rightPower = node.rightNodes.reduce(
(sum, node) => sum + node.data.power,
0,
)
const current = rightPower / 440
return { ...node.data, current }
}
const cable1 = new Node({
data: { type: 'cable', size: 5 },
context,
computeData: computeCableData,
})
const cable2 = new Node({
data: { type: 'cable', size: 5 },
context,
computeData: computeCableData,
})
const computeCabinetData = node => {
const listOfPowers = node.rightNodes.reduce(
(powers, cable) => [
...powers,
...cable.rightNodes.map(motor => motor.data.power),
],
[],
)
return { ...node.data, listOfPowers }
}
class Cabinet extends Node {
constructor({ data, context }) {
super({ data, computeData: computeCabinetData, context })
}
}
const cabinet = new Cabinet({
data: { type: 'cabinet' },
context,
})
motor1.add(cable1, 'left')
motor2.add(cable2, 'left')
cable1.add(cabinet, 'left')
cable2.add(cabinet, 'left')
const nodes = [motor1, cable1, motor2, cable2, cabinet]
function updateNodes(nodes) {
const rootLeftNodes = nodes.filter(node => !node.leftNodes.length)
setLevel(rootLeftNodes, 0)
const minToMaxLevelNodes = [...nodes].sort(node => -node.level)
const maxToMinLevelNodes = minToMaxLevelNodes.reverse()
minToMaxLevelNodes.forEach(node => node.update())
maxToMinLevelNodes.forEach(node => node.update())
minToMaxLevelNodes.forEach(node => node.update())
}
function setLevel(nodes, level) {
nodes.forEach(node => {
node.level = level
setLevel(node.rightNodes, level + 1)
})
}
updateNodes(nodes)
class Node {
leftNodes = []
rightNodes = []
area = null
level = 0
constructor({ data = {}, context = {}, computeData = node => node.data }) {
this.data = data
this.context = context
this.computeData = computeData
}
update() {
this.data = this.computeData(this)
}
add(node, position) {
switch (position) {
case 'left':
if (this.leftNodes.includes(node)) return node
this.leftNodes.push(node)
node.add(this, 'right')
return node
case 'right':
if (this.rightNodes.includes(node)) return node
this.rightNodes.push(node)
node.add(this, 'left')
return node
default:
throw new Error('position must be "left" or "right"')
}
}
}
export default Node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment