Display Query Results in Charts

Hi all,

Is there a way to query for properties and display them in charts? Are there any plug-ins that can provide that? I found some, but none is really what i am looking for.
This would be huge to visualize and keep track of my book list or any sort of bucket list. There is aToDo Plugin that shows your progress on a progress bar and that is nice, but it is limited to the ToDo / Doing / Done mechanism.

Type:: book
Status:: read / unread / summarized
Etc.

Would love to get something like i could get from excel:

Thanks!

2 Likes

While not a plugin, it’s possible to use Advanced Queries to get the data you want, then present them as HTML inside Logseq using the query’s :view. A basic bar chart can be rendered this way, and has the advantage of working on mobile too.

The query gets the counts of all blocks that share a given “status” property (change the (get ?props :status) to match your chosen property name).

You might also want to limit the query more in your graph, say, just to books if any other blocks have that property.

#+BEGIN_QUERY
{:title "Plot"
 :query
 [:find ?status (count ?block)
  :keys status count
  :where
  [?block :block/properties ?props]
  [(get ?props :status) ?status]]
 :view
 (fn [status-counts]
   (let [biggest (reduce max (map :count status-counts))]
[:div
 {:style
  {:display "flex"
   :flex-direction "column"
   :gap "4px" :padding "4px 4px 4px 0"
   :background-color "#333"
   :color "#eee"
   :font-size "80%"}}
 (map
  (fn [{status :status, number :count}]
    [:div
     {:style
      {:width (str (* (/ number biggest) 100) "%")
       :height "20px"
       :padding "2px"
       :white-space "nowrap"
       :border-radius "0 4px 4px 0"
       :box-shadow "1px 1px 2px #111"
       :background "#555"
       :background-clip "padding-box"}} (str number " " status)]) status-counts)]))}
#+END_QUERY
7 Likes
  • Very nice!
  • Could also move the styling into file custom.css:
    div.query-chart {
      background-color: #333;
      color: #eee;
      display: flex;
      flex-direction: column;
      font-size: 80%;
      gap: 4px;
      padding: 4px 4px 4px 0px;
    }
    div.query-chart div {
      background: padding-box #555;
      border-radius: 0px 4px 4px 0px;
      box-shadow: 1px 1px 2px #111;
      height: 20px;
      padding: 2px;
      white-space: nowrap;
      width: 100%;
    }
    
  • then simplify the query like this:
    #+BEGIN_QUERY
    {:title "Plot"
     :query
     [:find ?status (count ?block)
      :keys status count
      :where
      [?block :block/properties ?props]
      [(get ?props :status) ?status]]
     :view
     (fn [status-counts]
       (let [biggest (reduce max (map :count status-counts))]
        [:div {:class "query-chart"}
         (map
          (fn [{status :status, number :count}]
            [:div {:style {:width (str (* (/ number biggest) 100) "%")}}
            (str number " " status)]) status-counts)]))}
    #+END_QUERY
    
2 Likes

@iant Thanks so much for your solution I love it!
@mentaloid Thanks for your addition to separate code and formatting

I’ve tweaked the css for myself. And put the view in the config.edn for ease of use.
I’m really happy with the result!

#+BEGIN_QUERY 
{:title [:h4 "Aantal projecten per status"]
 :query [:find ?status (count ?p)
  :keys status count
  :where
   [?p :block/properties ?prop]
   [(get ?prop :status) ?status]
   [(get ?prop :type) ?type]
   [(= ?type "project")]
 ]
 :result-transform (fn [result] (sort-by :status result) )
 :view :bar-chart
}
#+END_QUERY

EDIT: now to figure out why all numbers are counted twice :sweat:
nvm. it counts pages and blocks now.

1 Like

Just wanted to let you know that i really appreciate the answers. I just haven´t had the time yet to try it myself. I will update my reply here as soon as i can add anything of value :slight_smile: Thanks!