mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 22:25:01 +00:00
@@ -120,6 +120,13 @@ dummy.commit = function() {};
|
||||
dummy.raw = function() {};
|
||||
dummy.onHeadersReceived = function() {};
|
||||
dummy.responseHeaders = function() {};
|
||||
dummy.velocityDecay = function() {};
|
||||
dummy.velocityDecay = function() {};
|
||||
dummy.updatePosition = function() {};
|
||||
dummy.getNodesObjects = function() {};
|
||||
dummy.getEdgesObjects = function() {};
|
||||
dummy.alphaTarget = function() {};
|
||||
dummy.restart = function() {};
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
"jszip": "3.5.0",
|
||||
"mldoc": "1.2.5",
|
||||
"path": "0.12.7",
|
||||
"pixi-graph-fork": "0.1.6",
|
||||
"pixi-graph-fork": "0.2.0",
|
||||
"pixi.js": "6.2.0",
|
||||
"posthog-js": "1.10.2",
|
||||
"react": "17.0.2",
|
||||
|
||||
@@ -582,7 +582,7 @@
|
||||
(global-graph-inner graph settings theme)))
|
||||
|
||||
(rum/defc page-graph-inner < rum/static
|
||||
[graph dark?]
|
||||
[page graph dark?]
|
||||
[:div.sidebar-item.flex-col
|
||||
(graph/graph-2d {:nodes (:nodes graph)
|
||||
:links (:links graph)
|
||||
@@ -605,7 +605,7 @@
|
||||
(graph-handler/build-block-graph (uuid page) theme)
|
||||
(graph-handler/build-page-graph page theme))]
|
||||
(when (seq (:nodes graph))
|
||||
(page-graph-inner graph dark?))))
|
||||
(page-graph-inner page graph dark?))))
|
||||
|
||||
(defn- sort-pages-by
|
||||
[by-item desc? pages]
|
||||
|
||||
@@ -336,8 +336,8 @@
|
||||
(ui/loading (t :loading))]]
|
||||
|
||||
:else
|
||||
[:div.pb-24 {:class (if global-graph-pages? "" (util/hiccup->class "max-w-7xl.mx-auto"))
|
||||
:style {:margin-bottom (if global-graph-pages? 0 120)}}
|
||||
[:div {:class (if global-graph-pages? "" (util/hiccup->class "max-w-7xl.mx-auto.pb-24"))
|
||||
:style {:margin-bottom (if global-graph-pages? 0 120)}}
|
||||
main-content])]]])))
|
||||
|
||||
(rum/defc footer
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
[goog.object :as gobj]
|
||||
[rum.core :as rum]))
|
||||
|
||||
(defn- highlight-node!
|
||||
[^js graph node]
|
||||
(.resetNodeStyle graph node
|
||||
(bean/->js {:color "#6366F1"
|
||||
:border {:width 2
|
||||
:color "#6366F1"}})))
|
||||
|
||||
(defn- highlight-neighbours!
|
||||
[^js graph node focus-nodes dark?]
|
||||
(.forEachNeighbor
|
||||
@@ -61,14 +54,16 @@
|
||||
(rum/defcs graph-2d <
|
||||
(rum/local nil :ref)
|
||||
{:did-update pixi/render!
|
||||
:should-update (fn [old-state new-state]
|
||||
(not= (select-keys (first (:rum/args old-state))
|
||||
[:nodes :links :dark?])
|
||||
(select-keys (first (:rum/args new-state))
|
||||
[:nodes :links :dark?])))
|
||||
:will-unmount (fn [state]
|
||||
(when-let [graph (:graph state)]
|
||||
(.destroy graph))
|
||||
(reset! pixi/*graph-instance nil)
|
||||
state)}
|
||||
[state opts]
|
||||
[:div.graph {:style {:height "100vh"}
|
||||
:ref (fn [value]
|
||||
[:div.graph {:ref (fn [value]
|
||||
(let [ref (get state :ref)]
|
||||
(when (and ref value)
|
||||
(reset! ref value))))}])
|
||||
|
||||
@@ -7,3 +7,7 @@
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.graph {
|
||||
height: calc(100vh - 100px) !important;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
["graphology" :as graphology]
|
||||
["pixi-graph-fork" :as Pixi-Graph]))
|
||||
|
||||
(defonce *graph-instance (atom nil))
|
||||
(defonce *simulation (atom nil))
|
||||
|
||||
(def Graph (gobj/get graphology "Graph"))
|
||||
|
||||
(defonce colors
|
||||
@@ -38,7 +41,6 @@
|
||||
:type (.-TEXT (.-TextType Pixi-Graph))
|
||||
:fontSize 12
|
||||
:color (if dark? "rgba(255, 255, 255, 0.8)" "rgba(0, 0, 0, 0.8)")
|
||||
; :backgroundColor "rgba(255, 255, 255, 0.5)"
|
||||
:padding 4}}
|
||||
:edge {:width 1
|
||||
:color (if dark? "#094b5a" "#cccccc")}})
|
||||
@@ -46,15 +48,14 @@
|
||||
(defn default-hover-style
|
||||
[dark?]
|
||||
{:node {:color "#6366F1"
|
||||
:border {:width 2
|
||||
:color "#6366F1"}
|
||||
:label {:backgroundColor "rgba(238, 238, 238, 1)"
|
||||
:color "#333333"}}
|
||||
:edge {:color "#A5B4FC"}})
|
||||
|
||||
(defn layout!
|
||||
[nodes links]
|
||||
(let [simulation (forceSimulation nodes)]
|
||||
(let [nodes-count (count nodes)
|
||||
simulation (forceSimulation nodes)]
|
||||
(-> simulation
|
||||
(.force "link"
|
||||
(-> (forceLink)
|
||||
@@ -63,19 +64,19 @@
|
||||
(.links links)))
|
||||
(.force "charge"
|
||||
(-> (forceManyBody)
|
||||
(.distanceMax 4000)
|
||||
(.distanceMax (if (> nodes-count 500) 4000 600))
|
||||
(.theta 0.5)
|
||||
(.strength -600)))
|
||||
(.force "collision"
|
||||
(-> (forceCollide)
|
||||
(.radius (+ 8 18))))
|
||||
(.radius (+ 8 18))
|
||||
(.iterations 2)))
|
||||
(.force "x" (-> (forceX 0) (.strength 0.02)))
|
||||
(.force "y" (-> (forceY 0) (.strength 0.02)))
|
||||
(.force "center" (forceCenter))
|
||||
(.tick 3)
|
||||
(.stop))))
|
||||
|
||||
(defonce *graph-instance (atom nil))
|
||||
(.velocityDecay 0.8))
|
||||
(reset! *simulation simulation)
|
||||
simulation))
|
||||
|
||||
(defn- clear-nodes!
|
||||
[graph]
|
||||
@@ -83,63 +84,118 @@
|
||||
(fn [node]
|
||||
(.dropNode graph node))))
|
||||
|
||||
;; (defn- clear-edges!
|
||||
;; [graph]
|
||||
;; (.forEachEdge graph
|
||||
;; (fn [edge]
|
||||
;; (.dropEdge graph edge))))
|
||||
|
||||
(defn destroy-instance!
|
||||
[]
|
||||
(when-let [instance (:pixi @*graph-instance)]
|
||||
(.destroy instance)
|
||||
(reset! *graph-instance nil)))
|
||||
(reset! *graph-instance nil)
|
||||
(reset! *simulation nil)))
|
||||
|
||||
(defonce *dark? (atom nil))
|
||||
|
||||
(defn- update-position!
|
||||
[node obj]
|
||||
(.updatePosition node #js {:x (.-x obj)
|
||||
:y (.-y obj)}))
|
||||
|
||||
(defn- tick!
|
||||
[pixi graph nodes-js links-js]
|
||||
(fn []
|
||||
(let [nodes-objects (.getNodesObjects pixi)
|
||||
edges-objects (.getEdgesObjects pixi)]
|
||||
(doseq [node nodes-js]
|
||||
(when-let [node-object (.get nodes-objects (.-id node))]
|
||||
(update-position! node-object node)))
|
||||
(doseq [edge links-js]
|
||||
(when-let [edge-object (.get edges-objects (str (.-index edge)))]
|
||||
(.updatePosition edge-object
|
||||
#js {:x (.-x (.-source edge))
|
||||
:y (.-y (.-source edge))}
|
||||
#js {:x (.-x (.-target edge))
|
||||
:y (.-y (.-target edge))}))))))
|
||||
|
||||
(defn- set-up-listeners!
|
||||
[pixi-graph]
|
||||
(when pixi-graph
|
||||
;; drag start
|
||||
(let [*dragging? (atom false)
|
||||
nodes (.getNodesObjects pixi-graph)
|
||||
on-drag-end (fn [node event]
|
||||
(.stopPropagation event)
|
||||
(when-let [s @*simulation]
|
||||
(when-not (.-active event)
|
||||
(.alphaTarget s 0)))
|
||||
(reset! *dragging? false))]
|
||||
(.on pixi-graph "nodeMousedown"
|
||||
(fn [event node-key]
|
||||
(when-let [node (.get nodes node-key)]
|
||||
(when-let [s @*simulation]
|
||||
(when-not (.-active event)
|
||||
(-> (.alphaTarget s 0.3)
|
||||
(.restart))
|
||||
(js/setTimeout #(.alphaTarget s 0) 2000))
|
||||
(reset! *dragging? true)))))
|
||||
|
||||
(.on pixi-graph "nodeMouseup"
|
||||
(fn [event node-key]
|
||||
(when-let [node (.get nodes node-key)]
|
||||
(on-drag-end node event))))
|
||||
|
||||
(.on pixi-graph "nodeMousemove"
|
||||
(fn [event node-key]
|
||||
(when-let [node (.get nodes node-key)]
|
||||
(when @*dragging?
|
||||
(update-position! node event))))))))
|
||||
|
||||
(defn render!
|
||||
[state]
|
||||
(let [dark? (:dark? (first (:rum/args state)))]
|
||||
(when (and (some? @*dark?) (not= @*dark? dark?))
|
||||
(destroy-instance!))
|
||||
(reset! *dark? dark?))
|
||||
|
||||
(try
|
||||
(let [old-instance @*graph-instance
|
||||
{:keys [graph pixi]} old-instance]
|
||||
(when (and graph pixi)
|
||||
(clear-nodes! graph))
|
||||
(let [{:keys [nodes links style hover-style height register-handlers-fn dark?]} (first (:rum/args state))
|
||||
style (or style (default-style dark?))
|
||||
hover-style (or hover-style (default-hover-style dark?))
|
||||
graph (or graph (Graph.))
|
||||
nodes-set (set (map :id nodes))
|
||||
links (->>
|
||||
(filter
|
||||
(fn [link]
|
||||
(and (nodes-set (:source link)) (nodes-set (:target link))))
|
||||
links)
|
||||
(distinct))
|
||||
nodes (remove nil? nodes)
|
||||
links (remove (fn [{:keys [source target]}] (or (nil? source) (nil? target))) links)
|
||||
nodes-js (bean/->js nodes)
|
||||
links-js (bean/->js links)]
|
||||
(layout! nodes-js links-js)
|
||||
(when @*graph-instance
|
||||
(clear-nodes! (:graph @*graph-instance))
|
||||
(destroy-instance!))
|
||||
(let [{:keys [nodes links style hover-style height register-handlers-fn dark?]} (first (:rum/args state))
|
||||
style (or style (default-style dark?))
|
||||
hover-style (or hover-style (default-hover-style dark?))
|
||||
graph (Graph.)
|
||||
nodes-set (set (map :id nodes))
|
||||
links (->>
|
||||
(filter
|
||||
(fn [link]
|
||||
(and (nodes-set (:source link)) (nodes-set (:target link))))
|
||||
links)
|
||||
(distinct))
|
||||
nodes (remove nil? nodes)
|
||||
links (remove (fn [{:keys [source target]}] (or (nil? source) (nil? target))) links)
|
||||
nodes-js (bean/->js nodes)
|
||||
links-js (bean/->js links)]
|
||||
(let [simulation (layout! nodes-js links-js)]
|
||||
(doseq [node nodes-js]
|
||||
(.addNode graph (.-id node) node))
|
||||
(doseq [link links-js]
|
||||
(let [source (.-id (.-source link))
|
||||
target (.-id (.-target link))]
|
||||
(.addEdge graph source target link)))
|
||||
(if pixi
|
||||
(.resetView pixi)
|
||||
(when-let [container-ref (:ref state)]
|
||||
(let [pixi-graph (new (.-PixiGraph Pixi-Graph)
|
||||
(bean/->js
|
||||
{:container @container-ref
|
||||
:graph graph
|
||||
:style style
|
||||
:hoverStyle hover-style
|
||||
:height height}))]
|
||||
(reset! *graph-instance
|
||||
{:graph graph
|
||||
:pixi pixi-graph})
|
||||
(when register-handlers-fn
|
||||
(register-handlers-fn pixi-graph)))))))
|
||||
(when-let [container-ref (:ref state)]
|
||||
(let [pixi-graph (new (.-PixiGraph Pixi-Graph)
|
||||
(bean/->js
|
||||
{:container @container-ref
|
||||
:graph graph
|
||||
:style style
|
||||
:hoverStyle hover-style
|
||||
:height height}))]
|
||||
(reset! *graph-instance
|
||||
{:graph graph
|
||||
:pixi pixi-graph})
|
||||
(when register-handlers-fn
|
||||
(register-handlers-fn pixi-graph))
|
||||
(set-up-listeners! pixi-graph)
|
||||
(.on simulation "tick" (tick! pixi-graph graph nodes-js links-js))))))
|
||||
(catch js/Error e
|
||||
(js/console.error e)))
|
||||
state)
|
||||
|
||||
Reference in New Issue
Block a user