d3Data.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { hierarchy } from 'd3-hierarchy'
  2. function flatten (arr, accumulator = []) {
  3. return arr.reduce((acc, child) => {
  4. acc.push(child)
  5. return child.children ? flatten(child.children, acc) : acc
  6. }, accumulator)
  7. }
  8. function getLinked (text) {
  9. const types = ['siblings', 'children', 'parents']
  10. return types.reduce((acc, type) => {
  11. // Handle `null` and `undefined`
  12. return text[type] ? [...acc, ...text[type]] : acc
  13. }, [])
  14. }
  15. export function toSingleManyData (rawData) {
  16. rawData.first = true
  17. const h = hierarchy(rawData, d => getLinked(d))
  18. h.each(node => {
  19. if (node.parent && node.children) {
  20. const id = node.parent.data.id
  21. node.children = node.children.filter(child => child.data.id !== id)
  22. }
  23. })
  24. const nodes = h.descendants()
  25. const links = h.links()
  26. nodes.forEach(node => {
  27. Object.assign(node.data, {
  28. type: node.data.type.toLowerCase(),
  29. class: 'family-' + node.data.families[0].id
  30. })
  31. })
  32. return { nodes, links }
  33. }
  34. export function toManyManyData (rawData) {
  35. rawData.first = true
  36. const h = hierarchy(rawData, d => getLinked(d))
  37. h.each(node => {
  38. if (node.parent && node.children) {
  39. const id = node.parent.data.id
  40. // Remove reference of parent in child's children.
  41. node.children = node.children.filter(child => child.data.id !== id)
  42. }
  43. })
  44. const links = []
  45. const nodes = flatten(h.descendants()).reduce((nodes, node) => {
  46. const sameNode = nodes.find(n => node.data.id === n.data.id)
  47. if (sameNode) {
  48. if (!node.children) return nodes
  49. node.children.forEach(child => {
  50. if (!sameNode.children.find(c => child.data.id === c.data.id)) {
  51. sameNode.children.push(child)
  52. }
  53. })
  54. } else {
  55. if (!node.children) node.children = []
  56. nodes.push(node)
  57. }
  58. return nodes
  59. }, []).map(({ data, children, depth }) => {
  60. if (children) {
  61. children.forEach(child => {
  62. links.push({ source: data.id, target: child.data.id })
  63. })
  64. }
  65. return {
  66. id: data.id,
  67. data: {
  68. ...data,
  69. type: data.type.toLowerCase(),
  70. class: 'family-' + data.families[0].id
  71. }
  72. }
  73. })
  74. return { nodes, links }
  75. }