(feat): allow creation of connected-component graph (#398)

This commit is contained in:
Johann Klähn 2020-04-08 04:52:40 +02:00 committed by GitHub
parent 72faa591fb
commit 67495e269a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 17 deletions

View file

@ -257,6 +257,21 @@ This is equivalent to removing the node from the graph."
file file
:limit 1))) :limit 1)))
(defun org-roam-db--connected-component (file)
"Return all files reachable from/connected to FILE, 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),
connected_component(file) AS
(SELECT link FROM links_of WHERE file = $s1
UNION
SELECT link FROM links_of JOIN connected_component USING(file))
SELECT * FROM connected_component;")
(files (mapcar 'car-safe (emacsql (org-roam-db) query file))))
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."

View file

@ -38,6 +38,8 @@
(defvar org-roam-directory) (defvar org-roam-directory)
(declare-function org-roam-db--ensure-built "org-roam-db") (declare-function org-roam-db--ensure-built "org-roam-db")
(declare-function org-roam-db-query "org-roam-db") (declare-function org-roam-db-query "org-roam-db")
(declare-function org-roam-db--connected-component "org-roam-db")
(declare-function org-roam--org-roam-file-p "org-roam")
(declare-function org-roam--path-to-slug "org-roam") (declare-function org-roam--path-to-slug "org-roam")
;;;; Options ;;;; Options
@ -122,21 +124,18 @@ set WHERE to true if WHERE query already exists."
(push match res)) (push match res))
(nreverse res))) (nreverse res)))
(defun org-roam-graph--build () (defun org-roam-graph--build (node-query)
"Build the graphviz string. "Build the graphviz string for NODE-QUERY.
The Org-roam database titles table is read, to obtain the list of The Org-roam database titles table is read, to obtain the list of titles.
titles. The links table is then read to obtain all directed The links table is then read to obtain all directed links, and formatted
links, and formatted into a digraph." into a digraph."
(org-roam-db--ensure-built) (org-roam-db--ensure-built)
(org-roam--with-temp-buffer (org-roam--with-temp-buffer
(let* ((node-query `[:select [file titles] (let* ((nodes (org-roam-db-query node-query))
:from titles (edges-query
,@(org-roam-graph--expand-matcher 'file t)]) `[:with selected :as [:select [file] :from ,node-query]
(nodes (org-roam-db-query node-query)) :select [to from] :from links
(edges-query `[:select :distinct [to from] :where (and (in to selected) (in from selected))])
:from links
,@(org-roam-graph--expand-matcher 'to t)
,@(org-roam-graph--expand-matcher 'from t t)])
(edges (org-roam-db-query edges-query))) (edges (org-roam-db-query edges-query)))
(insert "digraph \"org-roam\" {\n") (insert "digraph \"org-roam\" {\n")
(dolist (option org-roam-graph-extra-config) (dolist (option org-roam-graph-extra-config)
@ -171,7 +170,7 @@ links, and formatted into a digraph."
(defalias 'org-roam-show-graph 'org-roam-graph-show) (defalias 'org-roam-show-graph 'org-roam-graph-show)
(make-obsolete 'org-roam-show-graph 'org-roam-graph-show "2020/03/28") (make-obsolete 'org-roam-show-graph 'org-roam-graph-show "2020/03/28")
(defun org-roam-graph-show (&optional prefix) (defun org-roam-graph-show (&optional prefix node-query)
"Generate and displays the Org-roam graph using `org-roam-graph-viewer'. "Generate and displays the Org-roam graph using `org-roam-graph-viewer'.
If PREFIX, then the graph is generated but the viewer is not invoked." If PREFIX, then the graph is generated but the viewer is not invoked."
(interactive "P") (interactive "P")
@ -179,9 +178,12 @@ If PREFIX, then the graph is generated but the viewer is not invoked."
(unless org-roam-graph-executable (unless org-roam-graph-executable
(user-error "Can't find %s executable. Please check if it is in your path" (user-error "Can't find %s executable. Please check if it is in your path"
org-roam-graph-executable)) org-roam-graph-executable))
(let ((temp-dot (expand-file-name "graph.dot" temporary-file-directory)) (let* ((temp-dot (expand-file-name "graph.dot" temporary-file-directory))
(temp-graph (expand-file-name "graph.svg" temporary-file-directory)) (temp-graph (expand-file-name "graph.svg" temporary-file-directory))
(graph (org-roam-graph--build))) (node-query (or node-query `[:select [file titles]
:from titles
,@(org-roam-graph--expand-matcher 'file t)]))
(graph (org-roam-graph--build node-query)))
(with-temp-file temp-dot (with-temp-file temp-dot
(insert graph)) (insert graph))
(call-process org-roam-graph-executable nil 0 nil temp-dot "-Tsvg" "-o" temp-graph) (call-process org-roam-graph-executable nil 0 nil temp-dot "-Tsvg" "-o" temp-graph)
@ -190,6 +192,18 @@ 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)
"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."
(interactive "P")
(unless (org-roam--org-roam-file-p)
(user-error "Not in an Org-roam file"))
(let* ((file (file-truename (buffer-file-name)))
(files (or (org-roam-db--connected-component file) (list file)))
(query `[:select [file titles]
:from titles
:where (in file [,@files])]))
(org-roam-graph-show prefix query)))
(provide 'org-roam-graph) (provide 'org-roam-graph)