its workking
This commit is contained in:
parent
ba230e1eed
commit
fd54eb718a
1 changed files with 106 additions and 42 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import { findIndex, orderBy } from 'lodash'
|
||||||
|
|
||||||
// an array of synapses
|
// an array of synapses
|
||||||
// an array of topics
|
// an array of topics
|
||||||
|
|
||||||
|
@ -20,27 +22,22 @@ animate
|
||||||
|
|
||||||
// synapses = [{ topic1_id: 4, topic2_id: 5, direction: 'from-to' }]
|
// synapses = [{ topic1_id: 4, topic2_id: 5, direction: 'from-to' }]
|
||||||
|
|
||||||
|
const isEven = n => n % 2 === 0
|
||||||
|
const isOdd = n => Math.abs(n % 2) === 1
|
||||||
|
|
||||||
|
|
||||||
export const generateLayoutObject = (topics, synapses, focalTopicId) => {
|
export const generateLayoutObject = (topics, synapses, focalTopicId) => {
|
||||||
let layout = [] // will be the final output
|
let layout = [] // will be the final output
|
||||||
const usedTopics = {} // will store the topics that have been placed into islands
|
const usedTopics = {} // will store the topics that have been placed into islands
|
||||||
let newRoot
|
let newRoot
|
||||||
let currentTopic
|
let currentTopic
|
||||||
|
|
||||||
const addParentsAndChildren = (topic, getParents, getChildren) => {
|
const addParentsAndChildren = (topic, getParents, getChildren, degreeFromFocus) => {
|
||||||
if (!topic.id) return topic
|
if (!topic.id) return topic
|
||||||
|
|
||||||
usedTopics[topic.id] = true
|
usedTopics[topic.id] = true
|
||||||
|
topic.degreeFromFocus = degreeFromFocus
|
||||||
if (getParents) {
|
const nextDegree = degreeFromFocus + 1
|
||||||
topic.parents = []
|
|
||||||
synapses.filter(synapse => {
|
|
||||||
return synapse.topic2_id === topic.id
|
|
||||||
&& !usedTopics[synapse.topic1_id]
|
|
||||||
&& synapse.category === 'from-to'
|
|
||||||
})
|
|
||||||
.map(synapse => synapse.topic1_id)
|
|
||||||
.forEach(parentId => topic.parents.push(addParentsAndChildren({id: parentId}, true, false)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getChildren) {
|
if (getChildren) {
|
||||||
topic.children = []
|
topic.children = []
|
||||||
|
@ -50,7 +47,28 @@ export const generateLayoutObject = (topics, synapses, focalTopicId) => {
|
||||||
&& synapse.category === 'from-to'
|
&& synapse.category === 'from-to'
|
||||||
})
|
})
|
||||||
.map(synapse => synapse.topic2_id)
|
.map(synapse => synapse.topic2_id)
|
||||||
.forEach(childId => topic.children.push(addParentsAndChildren({id: childId}, false, true)))
|
.forEach(childId => topic.children.push(addParentsAndChildren({id: childId}, false, true, nextDegree)))
|
||||||
|
|
||||||
|
topic.children = orderBy(topic.children, 'maxDescendants', 'desc')
|
||||||
|
topic.maxDescendants = topic.children.length ? topic.children[0].maxDescendants + 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getParents) {
|
||||||
|
topic.parents = []
|
||||||
|
synapses.filter(synapse => {
|
||||||
|
return synapse.topic2_id === topic.id
|
||||||
|
&& !usedTopics[synapse.topic1_id]
|
||||||
|
&& synapse.category === 'from-to'
|
||||||
|
})
|
||||||
|
.map(synapse => synapse.topic1_id)
|
||||||
|
.forEach(parentId => topic.parents.push(addParentsAndChildren({id: parentId}, true, false, nextDegree)))
|
||||||
|
|
||||||
|
topic.parents = orderBy(topic.parents, 'maxAncestors', 'desc')
|
||||||
|
topic.maxAncestors = topic.parents.length ? topic.parents[0].maxAncestors + 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getParents && getChildren) {
|
||||||
|
topic.longestThread = topic.maxDescendants + topic.maxAncestors + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return topic
|
return topic
|
||||||
|
@ -65,22 +83,28 @@ export const generateLayoutObject = (topics, synapses, focalTopicId) => {
|
||||||
newRoot = {
|
newRoot = {
|
||||||
id: currentTopic.id
|
id: currentTopic.id
|
||||||
}
|
}
|
||||||
layout.push(addParentsAndChildren(newRoot, true, true))
|
layout.push(addParentsAndChildren(newRoot, true, true, 0))
|
||||||
// do the rest
|
|
||||||
|
// right now there's no reasoning going on about the selection of focal topics
|
||||||
|
// its just whichever ones happen to be found in the array first
|
||||||
topics.forEach(topic => {
|
topics.forEach(topic => {
|
||||||
if (topic && topic.id && !usedTopics[topic.id]) {
|
if (topic && topic.id && !usedTopics[topic.id]) {
|
||||||
newRoot = {
|
newRoot = {
|
||||||
id: topic.id
|
id: topic.id
|
||||||
}
|
}
|
||||||
layout.push(addParentsAndChildren(newRoot, true, true))
|
layout.push(addParentsAndChildren(newRoot, true, true, 0))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(JSON.stringify(layout))
|
||||||
return layout
|
return layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoords) => {
|
export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoords) => {
|
||||||
const coords = {}
|
const coords = {}
|
||||||
|
const X_GRID_SPACE = 250
|
||||||
|
const Y_GRID_SPACE = 200
|
||||||
|
|
||||||
const traverseIsland = (island, func, parent, child) => {
|
const traverseIsland = (island, func, parent, child) => {
|
||||||
func(island, parent, child)
|
func(island, parent, child)
|
||||||
|
@ -92,28 +116,68 @@ export const generateObjectCoordinates = (layoutObject, focalTopicId, focalCoord
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const positionTopic = (topic, parent, child) => {
|
// const myFunction = n => n*5
|
||||||
if (topic.id === focalTopicId) {
|
|
||||||
// set the focalCoord to be what it already was
|
// myFunction(2) === 10
|
||||||
coords[topic.id] = focalCoords
|
|
||||||
} else if (!parent && !child) {
|
const positionTopic = tempPosStore => (topic, parent, child) => {
|
||||||
coords[topic.id] = {x: 0, y: 250}
|
let pos = {}
|
||||||
} else if (parent) {
|
|
||||||
coords[topic.id] = {
|
const getYValueForX = (x, attempt = 0) => {
|
||||||
x: coords[parent.id].x + 250,
|
tempPosStore[x] = tempPosStore[x] || {}
|
||||||
y: coords[parent.id].y - (parent.id === focalTopicId ? 250 : 0)
|
let yValue
|
||||||
|
let relationSign
|
||||||
|
let indexOfTopic
|
||||||
|
let relation = parent || child
|
||||||
|
let arrayOfTopics = parent ? parent.children : (child ? child.parents : [])
|
||||||
|
|
||||||
|
// first figure out what you'd like it to be
|
||||||
|
// then figure out if that spot's taken
|
||||||
|
// and if it is then call this function again with another attempt
|
||||||
|
|
||||||
|
// after the focal topic only, ODD indexes will move negatively on the Y axis
|
||||||
|
// and EVEN indexes will move positively on the Y axis
|
||||||
|
|
||||||
|
// for everything beyond the direct parents and children of the focal topic
|
||||||
|
// maintain the positivity or negativity on the Y axis of its parent or child
|
||||||
|
|
||||||
|
if (!relation) yValue = 0
|
||||||
|
else if (attempt === 0) yValue = coords[relation.id].y
|
||||||
|
else if (attempt > 0) {
|
||||||
|
// if the relations sign is 0, alternate between putting this topic into the upper and lower quadrants
|
||||||
|
if (coords[relation.id].y === 0) {
|
||||||
|
indexOfTopic = findIndex(arrayOfTopics, t => t.id === topic.id)
|
||||||
|
relationSign = isOdd(indexOfTopic) ? 1 : -1
|
||||||
|
} else {
|
||||||
|
// if the quadrant of the related topic is already decided, make sure to keep it
|
||||||
|
relationSign = coords[relation.id].y > 0 ? 1 : -1
|
||||||
}
|
}
|
||||||
} else if (child) {
|
yValue = coords[relation.id].y + (Y_GRID_SPACE * attempt * relationSign)
|
||||||
coords[topic.id] = {
|
|
||||||
x: coords[child.id].x - 250,
|
|
||||||
y: coords[child.id].y
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tempPosStore[x][yValue]) yValue = getYValueForX(x, attempt + 1)
|
||||||
|
tempPosStore[x][yValue] = true
|
||||||
|
return yValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pos.x = topic.degreeFromFocus * X_GRID_SPACE * (parent ? 1 : -1),
|
||||||
|
pos.y = getYValueForX(pos.x)
|
||||||
|
coords[topic.id] = pos
|
||||||
|
}
|
||||||
|
|
||||||
|
const translateIsland = (island, x, y) => {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// lay all of them out as if there were no other ones
|
// lay all of them out as if there were no other ones
|
||||||
layoutObject.forEach(island => {
|
layoutObject.forEach((island, index) => {
|
||||||
traverseIsland(island, positionTopic)
|
const tempPosStore = {}
|
||||||
|
if (index === 0) {
|
||||||
|
tempPosStore[X_GRID_SPACE] = {
|
||||||
|
0: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traverseIsland(island, positionTopic(tempPosStore))
|
||||||
})
|
})
|
||||||
|
|
||||||
// calculate the bounds of each island
|
// calculate the bounds of each island
|
||||||
|
|
Loading…
Add table
Reference in a new issue