mirror of
https://github.com/org-roam/org-roam
synced 2025-08-03 12:27:23 -05:00
(feat): graph of bfs from given node (#418)
This commit is contained in:
@ -263,6 +263,32 @@ If the file does not have any connections, nil is returned."
|
|||||||
(files (mapcar 'car-safe (emacsql (org-roam-db) query file))))
|
(files (mapcar 'car-safe (emacsql (org-roam-db) query file))))
|
||||||
files))
|
files))
|
||||||
|
|
||||||
|
(defun org-roam-db--links-with-max-distance (file max-distance)
|
||||||
|
"Return all files reachable from/connected to FILE in at most MAX-DISTANCE steps,
|
||||||
|
including the file itself. If the file does not have any connections, nil is returned."
|
||||||
|
(let* ((query "WITH RECURSIVE
|
||||||
|
links_of(file, link) AS
|
||||||
|
(SELECT \"from\", \"to\" FROM links UNION
|
||||||
|
SELECT \"to\", \"from\" FROM links),
|
||||||
|
-- Links are traversed in a breadth-first search. In order to calculate the
|
||||||
|
-- distance of nodes and to avoid following cyclic links, the visited nodes
|
||||||
|
-- are tracked in 'trace'.
|
||||||
|
connected_component(file, trace) AS
|
||||||
|
(VALUES($s1, json_array($s1))
|
||||||
|
UNION
|
||||||
|
SELECT lo.link, json_insert(cc.trace, '$[' || json_array_length(cc.trace) || ']', lo.link) FROM
|
||||||
|
connected_component AS cc JOIN links_of AS lo USING(file)
|
||||||
|
WHERE (
|
||||||
|
-- Avoid cycles by only visiting each file once.
|
||||||
|
(SELECT count(*) FROM json_each(cc.trace) WHERE json_each.value == lo.link) == 0
|
||||||
|
-- Note: BFS is cut off early here.
|
||||||
|
AND json_array_length(cc.trace) < ($s2 + 1)))
|
||||||
|
SELECT DISTINCT file, min(json_array_length(trace)) AS distance
|
||||||
|
FROM connected_component GROUP BY file ORDER BY distance;")
|
||||||
|
;; In principle the distance would be available in the second column.
|
||||||
|
(files (mapcar 'car-safe (emacsql (org-roam-db) query file max-distance))))
|
||||||
|
files))
|
||||||
|
|
||||||
;;;;; Updating
|
;;;;; Updating
|
||||||
(defun org-roam-db--update-titles ()
|
(defun org-roam-db--update-titles ()
|
||||||
"Update the title of the current buffer into the cache."
|
"Update the title of the current buffer into the cache."
|
||||||
|
@ -130,7 +130,7 @@ into a digraph."
|
|||||||
(let* ((nodes (org-roam-db-query node-query))
|
(let* ((nodes (org-roam-db-query node-query))
|
||||||
(edges-query
|
(edges-query
|
||||||
`[:with selected :as [:select [file] :from ,node-query]
|
`[:with selected :as [:select [file] :from ,node-query]
|
||||||
:select [to from] :from links
|
:select :distinct [to from] :from links
|
||||||
:where (and (in to selected) (in from selected))])
|
:where (and (in to selected) (in from selected))])
|
||||||
(edges (org-roam-db-query edges-query)))
|
(edges (org-roam-db-query edges-query)))
|
||||||
(insert "digraph \"org-roam\" {\n")
|
(insert "digraph \"org-roam\" {\n")
|
||||||
@ -186,18 +186,22 @@ If PREFIX, then the graph is generated but the viewer is not invoked."
|
|||||||
(call-process org-roam-graph-viewer nil 0 nil temp-graph)
|
(call-process org-roam-graph-viewer nil 0 nil temp-graph)
|
||||||
(view-file temp-graph)))))
|
(view-file temp-graph)))))
|
||||||
|
|
||||||
(defun org-roam-graph-show-connected-component (&optional prefix)
|
(defun org-roam-graph-show-connected-component (&optional max-distance no-display)
|
||||||
"Like `org-roam-graph-show', but only show nodes connected to the current entry.
|
"Like `org-roam-graph-show', but only show nodes connected to the current entry.
|
||||||
If PREFIX is non-nil, the graph is generated but the viewer is not invoked."
|
If MAX-DISTANCE is non-nil, only nodes within the given number of steps are shown.
|
||||||
|
If NO-DISPLAY is non-nil, the graph is generated but the viewer is not invoked."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(unless (org-roam--org-roam-file-p)
|
(unless (org-roam--org-roam-file-p)
|
||||||
(user-error "Not in an Org-roam file"))
|
(user-error "Not in an Org-roam file"))
|
||||||
(let* ((file (file-truename (buffer-file-name)))
|
(let* ((file (file-truename (buffer-file-name)))
|
||||||
(files (or (org-roam-db--connected-component file) (list file)))
|
(files (or (if (and max-distance (>= (prefix-numeric-value max-distance) 0))
|
||||||
|
(org-roam-db--links-with-max-distance file max-distance)
|
||||||
|
(org-roam-db--connected-component file))
|
||||||
|
(list file)))
|
||||||
(query `[:select [file titles]
|
(query `[:select [file titles]
|
||||||
:from titles
|
:from titles
|
||||||
:where (in file [,@files])]))
|
:where (in file [,@files])]))
|
||||||
(org-roam-graph-show prefix query)))
|
(org-roam-graph-show no-display query)))
|
||||||
|
|
||||||
(provide 'org-roam-graph)
|
(provide 'org-roam-graph)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user