router.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. define(function () {
  2. return function () {
  3. var self = this
  4. var objects = { nodes: {}, links: {} }
  5. var targets = []
  6. var views = {}
  7. var currentView
  8. var currentObject
  9. var running = false
  10. function saveState() {
  11. var e = []
  12. if (currentView)
  13. e.push("v:" + currentView)
  14. if (currentObject) {
  15. if ("node" in currentObject)
  16. e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id))
  17. if ("link" in currentObject)
  18. e.push("l:" + encodeURIComponent(currentObject.link.id))
  19. }
  20. var s = "#!" + e.join(";")
  21. window.history.pushState(s, undefined, s)
  22. }
  23. function resetView(push) {
  24. push = trueDefault(push)
  25. targets.forEach( function (t) {
  26. t.resetView()
  27. })
  28. if (push) {
  29. currentObject = undefined
  30. saveState()
  31. }
  32. }
  33. function gotoNode(d) {
  34. if (!d)
  35. return false
  36. targets.forEach( function (t) {
  37. t.gotoNode(d)
  38. })
  39. return true
  40. }
  41. function gotoLink(d) {
  42. if (!d)
  43. return false
  44. targets.forEach( function (t) {
  45. t.gotoLink(d)
  46. })
  47. return true
  48. }
  49. function loadState(s) {
  50. if (!s)
  51. return false
  52. if (!s.startsWith("#!"))
  53. return false
  54. var targetSet = false
  55. s.slice(2).split(";").forEach(function (d) {
  56. var args = d.split(":")
  57. if (args[0] === "v" && args[1] in views) {
  58. currentView = args[1]
  59. views[args[1]]()
  60. }
  61. var id
  62. if (args[0] === "n") {
  63. id = decodeURIComponent(args[1])
  64. if (id in objects.nodes) {
  65. currentObject = { node: objects.nodes[id] }
  66. gotoNode(objects.nodes[id])
  67. targetSet = true
  68. }
  69. }
  70. if (args[0] === "l") {
  71. id = decodeURIComponent(args[1])
  72. if (id in objects.links) {
  73. currentObject = { link: objects.links[id] }
  74. gotoLink(objects.links[id])
  75. targetSet = true
  76. }
  77. }
  78. })
  79. return targetSet
  80. }
  81. self.start = function () {
  82. running = true
  83. if (!loadState(window.location.hash))
  84. resetView(false)
  85. window.onpopstate = function (d) {
  86. if (!loadState(d.state))
  87. resetView(false)
  88. }
  89. }
  90. self.view = function (d) {
  91. if (d in views) {
  92. views[d]()
  93. if (!currentView || running)
  94. currentView = d
  95. if (!running)
  96. return
  97. saveState()
  98. if (!currentObject) {
  99. resetView(false)
  100. return
  101. }
  102. if ("node" in currentObject)
  103. gotoNode(currentObject.node)
  104. if ("link" in currentObject)
  105. gotoLink(currentObject.link)
  106. }
  107. }
  108. self.node = function (d) {
  109. return function () {
  110. var sidebar = document.getElementById("sidebar")
  111. sidebar.classList.remove("hidden")
  112. if (gotoNode(d)) {
  113. currentObject = { node: d }
  114. saveState()
  115. }
  116. return false
  117. }
  118. }
  119. self.link = function (d) {
  120. return function () {
  121. if (gotoLink(d)) {
  122. currentObject = { link: d }
  123. saveState()
  124. }
  125. return false
  126. }
  127. }
  128. self.reset = function () {
  129. resetView()
  130. }
  131. self.addTarget = function (d) {
  132. targets.push(d)
  133. }
  134. self.removeTarget = function (d) {
  135. targets = targets.filter( function (e) {
  136. return d !== e
  137. })
  138. }
  139. self.addView = function (k, d) {
  140. views[k] = d
  141. }
  142. self.setData = function (data) {
  143. objects.nodes = {}
  144. objects.links = {}
  145. data.nodes.all.forEach( function (d) {
  146. objects.nodes[d.nodeinfo.node_id] = d
  147. })
  148. data.graph.links.forEach( function (d) {
  149. objects.links[d.id] = d
  150. })
  151. }
  152. return self
  153. }
  154. })