graph.cljs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. (ns frontend.extensions.graph
  2. (:require [rum.core :as rum]
  3. [frontend.rum :as r]
  4. [frontend.ui :as ui]
  5. [shadow.lazy :as lazy]
  6. [frontend.handler.route :as route-handler]
  7. [clojure.string :as string]
  8. [cljs-bean.core :as bean]
  9. [goog.object :as gobj]
  10. [frontend.state :as state]
  11. [frontend.db :as db]
  12. [promesa.core :as p]
  13. [clojure.set :as set]
  14. [cljs-bean.core :as bean]
  15. [frontend.extensions.graph.pixi :as pixi]
  16. [frontend.util :as util :refer [profile]]
  17. [cljs-bean.core :as bean]))
  18. (defn- highlight-node!
  19. [^js graph node]
  20. (.resetNodeStyle graph node
  21. (bean/->js {:color "#6366F1"
  22. :border {:width 2
  23. :color "#6366F1"}})))
  24. (defn- highlight-neighbours!
  25. [^js graph node focus-nodes dark?]
  26. (.forEachNeighbor
  27. (.-graph graph) node
  28. (fn [node attributes]
  29. (when-not (contains? focus-nodes node)
  30. (let [attributes (bean/->clj attributes)
  31. attributes (assoc attributes
  32. :color "#6366F1"
  33. :border {:width 2
  34. :color "#6366F1"})]
  35. (.resetNodeStyle graph node (bean/->js attributes)))))))
  36. (defn- highlight-edges!
  37. [^js graph node dark?]
  38. (.forEachEdge
  39. (.-graph graph) node
  40. (fn [edge attributes]
  41. (.resetEdgeStyle graph edge (bean/->js {:width 1
  42. :color (if dark? "#999" "#A5B4FC")})))))
  43. (defn on-click-handler [graph node event *focus-nodes *n-hops drag? dark?]
  44. ;; shift+click to select the page
  45. (if (or (gobj/get event "shiftKey") drag?)
  46. (let [page-name (string/lower-case node)]
  47. (when-not @*n-hops
  48. ;; Don't trigger re-render
  49. (swap! *focus-nodes
  50. (fn [v]
  51. (vec (distinct (conj v node))))))
  52. ;; highlight current node
  53. (let [node-attributes (-> (.getNodeAttributes (.-graph graph) node)
  54. (bean/->clj))]
  55. (.setNodeAttribute (.-graph graph) node "parent" "ls-selected-nodes"))
  56. (highlight-neighbours! graph node (set @*focus-nodes) dark?)
  57. (highlight-edges! graph node dark?))
  58. (when-not drag?
  59. (let [page-name (string/lower-case node)]
  60. (route-handler/redirect! {:to :page
  61. :path-params {:name page-name}})))))
  62. (defn reset-graph!
  63. [^js graph]
  64. (.resetView graph))
  65. (rum/defcs graph-2d <
  66. (rum/local nil :ref)
  67. {:did-update pixi/render!
  68. :will-unmount (fn [state]
  69. (when-let [graph (:graph state)]
  70. (.destroy graph))
  71. (reset! pixi/*graph-instance nil)
  72. state)}
  73. [state opts]
  74. [:div.graph {:style {:height "100vh"}
  75. :ref (fn [value]
  76. (let [ref (get state :ref)]
  77. (when (and ref value)
  78. (reset! ref value))))}])