d3Data.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. if (text[type]) {
  13. text[type].forEach((item, i) => {
  14. item.linkType = type
  15. })
  16. return [...acc, ...text[type]]
  17. }
  18. return acc
  19. }, [])
  20. }
  21. export function toSingleManyData (rawData) {
  22. rawData.isOrigin = true
  23. const h = hierarchy(rawData, d => getLinked(d))
  24. h.each(node => {
  25. if (node.parent && node.children) {
  26. const id = node.parent.data.id
  27. node.children = node.children.filter(child => child.data.id !== id)
  28. }
  29. })
  30. const nodes = h.descendants()
  31. const links = h.links()
  32. nodes.forEach(node => {
  33. Object.assign(node.data, {
  34. type: node.data.type.toLowerCase()
  35. })
  36. })
  37. return { nodes, links }
  38. }
  39. export function toManyManyData (rawData) {
  40. rawData.isOrigin = true
  41. const h = hierarchy(rawData, d => getLinked(d))
  42. h.each(node => {
  43. if (node.parent && node.children) {
  44. const id = node.parent.data.id
  45. // Remove reference of parent in child's children.
  46. node.children = node.children.filter(child => child.data.id !== id)
  47. }
  48. })
  49. const links = []
  50. const nodes = flatten(h.descendants()).reduce((nodes, node) => {
  51. const sameNode = nodes.find(n => node.data.id === n.data.id)
  52. if (sameNode) {
  53. if (!node.children) return nodes
  54. node.children.forEach(child => {
  55. if (!sameNode.children.find(c => child.data.id === c.data.id)) {
  56. sameNode.children.push(child)
  57. }
  58. })
  59. } else {
  60. if (!node.children) node.children = []
  61. nodes.push(node)
  62. }
  63. return nodes
  64. }, []).map(({ data, children, depth }) => {
  65. if (children) {
  66. children.forEach(child => {
  67. links.push({ source: data.id, target: child.data.id, linkType: child.data.linkType })
  68. })
  69. }
  70. return {
  71. id: data.id,
  72. data: {
  73. ...data,
  74. type: data.type.toLowerCase()
  75. }
  76. }
  77. })
  78. return { nodes, links }
  79. }