83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
import { hierarchy } from 'd3-hierarchy'
|
|
|
|
function flatten (arr, accumulator = []) {
|
|
return arr.reduce((acc, child) => {
|
|
acc.push(child)
|
|
return child.children ? flatten(child.children, acc) : acc
|
|
}, accumulator)
|
|
}
|
|
|
|
function getLinked (text) {
|
|
const types = ['siblings', 'children', 'parents']
|
|
return types.reduce((acc, type) => {
|
|
// Handle `null` and `undefined`
|
|
return text[type] ? [...acc, ...text[type]] : acc
|
|
}, [])
|
|
}
|
|
|
|
export function toSingleManyData (rawData) {
|
|
rawData.first = true
|
|
const h = hierarchy(rawData, d => getLinked(d))
|
|
h.each(node => {
|
|
if (node.parent && node.children) {
|
|
const id = node.parent.data.id
|
|
node.children = node.children.filter(child => child.data.id !== id)
|
|
}
|
|
})
|
|
|
|
const nodes = h.descendants()
|
|
const links = h.links()
|
|
nodes.forEach(node => {
|
|
Object.assign(node.data, {
|
|
type: node.data.type.toLowerCase(),
|
|
class: 'family-' + node.data.families[0].id
|
|
})
|
|
})
|
|
return { nodes, links }
|
|
}
|
|
|
|
|
|
export function toManyManyData (rawData) {
|
|
rawData.first = true
|
|
const h = hierarchy(rawData, d => getLinked(d))
|
|
h.each(node => {
|
|
if (node.parent && node.children) {
|
|
const id = node.parent.data.id
|
|
// Remove reference of parent in child's children.
|
|
node.children = node.children.filter(child => child.data.id !== id)
|
|
}
|
|
})
|
|
|
|
const links = []
|
|
const nodes = flatten(h.descendants()).reduce((nodes, node) => {
|
|
const sameNode = nodes.find(n => node.data.id === n.data.id)
|
|
if (sameNode) {
|
|
if (!node.children) return nodes
|
|
node.children.forEach(child => {
|
|
if (!sameNode.children.find(c => child.data.id === c.data.id)) {
|
|
sameNode.children.push(child)
|
|
}
|
|
})
|
|
} else {
|
|
if (!node.children) node.children = []
|
|
nodes.push(node)
|
|
}
|
|
return nodes
|
|
}, []).map(({ data, children, depth }) => {
|
|
if (children) {
|
|
children.forEach(child => {
|
|
links.push({ source: data.id, target: child.data.id })
|
|
})
|
|
}
|
|
return {
|
|
id: data.id,
|
|
data: {
|
|
...data,
|
|
type: data.type.toLowerCase(),
|
|
class: 'family-' + data.families[0].id
|
|
}
|
|
}
|
|
})
|
|
return { nodes, links }
|
|
}
|