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 = ['text_en_rebond', 'text_produits', 'text_de_depart'] 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.__typename.toLowerCase(), class: 'family-' + node.data.familles[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.__typename.toLowerCase(), class: 'family-' + data.familles[0].id } } }) return { nodes, links } }