{"id":15873814,"url":"https://github.com/phronmophobic/treemap-clj","last_synced_at":"2025-10-27T10:44:49.960Z","repository":{"id":49385681,"uuid":"280949895","full_name":"phronmophobic/treemap-clj","owner":"phronmophobic","description":"An alternative to pprint for generically visualizing heterogeneous, hierarchical data","archived":false,"fork":false,"pushed_at":"2022-10-10T03:50:34.000Z","size":471,"stargazers_count":69,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-27T05:02:34.194Z","etag":null,"topics":["clojure","data-visualization","membrane","treemap"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phronmophobic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-19T21:01:43.000Z","updated_at":"2025-02-03T00:21:29.000Z","dependencies_parsed_at":"2022-08-25T06:50:55.665Z","dependency_job_id":null,"html_url":"https://github.com/phronmophobic/treemap-clj","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phronmophobic%2Ftreemap-clj","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phronmophobic%2Ftreemap-clj/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phronmophobic%2Ftreemap-clj/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phronmophobic%2Ftreemap-clj/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phronmophobic","download_url":"https://codeload.github.com/phronmophobic/treemap-clj/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243550472,"owners_count":20309285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","data-visualization","membrane","treemap"],"created_at":"2024-10-06T01:07:01.410Z","updated_at":"2025-10-27T10:44:44.927Z","avatar_url":"https://github.com/phronmophobic.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# treemap-clj\n\nAn alternative to pprint for generically visualizing heterogeneous, hierarchical data\n\nBuilt with [membrane](https://github.com/phronmophobic/membrane).\n\n## Web Demo\n\nTry it! https://blog.phronemophobic.com/treemap/treemap-demo.html\n\n## Rationale\n\nTreemaps are an underutilized visualization that are capable of generically summarizing data of many shapes and sizes. To date, they've mostly been used for displaying the files consuming all of your disk space, but with a few tweaks, treemaps can be a flexible tool for exploring and navigating messy data blobs.\n\nFor more background, check out [treemaps are awesome!](https://blog.phronemophobic.com/treemap/treemaps-are-awesome.html)\n\n## Example Output\n\nExample outputs for various sizes. Example [data](https://raw.githubusercontent.com/t-mon/selffinding-chronicles/cb24e067579ba755c26ef642b24f9d2a8d3b45b9/gamedata/savegames/test-savegame.json). \n\n![Example output](https://blog.phronemophobic.com/treemap/images/sizes-example.gif)\n\n## Installation\n\nLeiningen dependency:\n\n```\n[com.phronemophobic/treemap-clj \"0.2.6\"]\n```\n\ndeps.edn dependency:\n\n```\ncom.phronemophobic/treemap-clj {:mvn/version \"0.2.6\"}\n```\n\n\n## Usage\n\n\nCreating a treemap can be broken down into 3 steps:\n\n1. layout\n2. render\n3. draw\n\n![API](/doc/api.png?raw=true)\n\n\n### Save a treemap as an image\n\n```clojure\n(def obj {:a (range 5)\n          :b (range 5)\n          :c (range 5)})\n\n;; layout the treemap rectangles\n(require '[treemap-clj.core :as treemap])\n\n(def tm (treemap/treemap obj\n                         (treemap/make-rect 300 300)))\n;; or\n\n(def tm (treemap/keyed-treemap obj\n                               (treemap/make-rect 300 300)))\n\n\n;; render the treemap\n(require '[treemap-clj.view :as tview])\n\n;; render your desired layers\n(def tm-rendered [(tview/render-depth tm)\n                  ;; (tview/render-background-types tm)\n                  ;; (tview/render-keys tm)\n                  (tview/render-hierarchy-lines tm)\n                  (tview/render-value-labels tm)\n                  ])\n\n;; save rendered treemap to image\n(require 'membrane.java2d)\n\n(membrane.java2d/save-to-image! \"treemap.png\" tm-rendered)\n\n;; or draw to a buffered image\n;; (membrane.java2d/draw-to-image tm-rendered)\n```\n\n### Run the built in treemap explorer\n\nCurrently only available on Mac OSX and Ubuntu\n\nFrom the command line: `lein run -m treemap-clj.treem \u003cedn or json file\u003e`\n\nNote: you must have `data.json` (eg. `[org.clojure/data.json \"1.0.0\"]`) as a dependency to read json files.\n\nFrom the repl:\n\n```clojure\n(require '[treemap-clj.treem :as treem])\n\n(def my-obj {:a 1})\n(treem/app my-obj)\n```\n\n### Rendering your own treemap layers\n\nThe layout and rendering steps are intentionally broken up in order to make it easy to use treemaps in different contexts.\n\nTreemaps are layed out using `treemap-clj.core/treemap` or `treemap-clj.core/keyed-treemap`. Both functions return a single `treemap-clj.core/Rect`.\n\n\n\n```clojure\n\u003e (treemap-clj.core/treemap {:a 1} (treemap-clj.core/make-rect 100 100))\n {:x 0,\n  :y 0,\n  :w 85,\n  :h 85,\n  :obj {:a 1},\n  :children\n  ({:x 0,\n    :y 0,\n    :w 70N,\n    :h 70N,\n    :obj [:a 1],\n    :children\n    ({:x 0, :y 0, :w 60N, :h 25N, :obj :a, :children nil}\n     {:x 0, :y 35N, :w 60N, :h 25N, :obj 1, :children nil})})}\n```\n\nEach rectangle has enough info to draw a rectangle (keys `x`, `y`, `w`, `h`) as well as the object it represents `:obj`.\n\nThe `:children` are offset by all of their parents' `x` and `y` coodinates.\n\nRendering a layer is as simple as treewalking. `treemap-clj` uses [membrane](https://github.com/phronmophobic/membrane) for graphics, but you can use whichever graphics library you desire.\n\n#### Render example using loop/recur\n\n```clojure\n(require '[membrane.ui :as ui])\n(def black [0 0 0])\n(defn render-dots [rect]\n  (loop [to-visit (seq [[0 0 rect]])\n         view []]\n    (if to-visit\n      (let [[ox oy rect] (first to-visit)]\n        (if-let [children (:children rect)]\n          (let [ox (+ ox (:x rect))\n                oy (+ oy (:y rect))]\n            (recur (into (map #(vector ox oy %) children)\n                         (next to-visit))\n                   view))\n          (recur (next to-visit)\n                 (conj view\n                       (ui/translate (+ ox (:x rect)) (+ oy (:y rect))\n                                     (ui/filled-rectangle black 2 2 )\n                                      )))))\n      view)))\n```\n\n#### Render example using clojure.zip\n\n`clojure.zip` makes treewalking very straightforward. This produces the same result as above.\n\n```clojure\n(require '[membrane.ui :as ui])\n(require '[clojure.zip :as z])\n(def black [0 0 0])\n(defn render-dots-zip [tm]\n  (let [zip (z/zipper :children :children\n                      (fn [rect children]\n                        (ui/translate (:x rect)\n                                      (:y rect)\n                                      (vec children)))\n                      tm)\n        rect-\u003edot (fn [rect]\n                    (ui/translate\n                     (:x rect) (:y rect)\n                     (ui/filled-rectangle black 2 2 )))]\n    (loop [zip zip]\n      (if (z/end? zip)\n        (z/root zip)\n        (let [zip (if (z/branch? zip)\n                    zip\n                    (z/edit zip rect-\u003edot))]\n          (recur (z/next zip)))))\n    )) \n```\n\n\n## Fixing the mac osx dock icon appearing\n\nOn macosx, `keyed-treemap` may cause an annoying java dock icon to appear. There are 2 ways to prevent this:\n\n1. add `-Dapple.awt.UIElement=true` to your jvm options\n2. Use the following snippet before calling `keyed-treemap`\n```clojure\n(let [ui-element (System/getProperty \"apple.awt.UIElement\")]\n  (when (nil? ui-element)\n    (System/setProperty \"apple.awt.UIElement\" \"true\")))\n```\n\n## Further Reading\n\n[Visualizing business information using generalized treemaps](https://pure.tue.nl/ws/files/47041749/631721-1.pdf)\n\n[Visualizing Business Data with Generalized Treemaps](https://ieeexplore.ieee.org/document/4015431)\n\n[Computing Voronoi Treemaps](https://www.uni-konstanz.de/mmsp/pubsys/publishedFiles/NoBr12a.pdf)\n\n[Fast Dynamic Voronoi Treemaps](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/isvd.pdf)\n\n\n## License\n\nCopyright © 2020 Adrian Smith\n\nThis program and the accompanying materials are made available under the\nterms of the Eclipse Public License 2.0 which is available at\nhttp://www.eclipse.org/legal/epl-2.0.\n\nThis Source Code may also be made available under the following Secondary\nLicenses when the conditions for such availability set forth in the Eclipse\nPublic License, v. 2.0 are satisfied: GNU General Public License as published by\nthe Free Software Foundation, either version 2 of the License, or (at your\noption) any later version, with the GNU Classpath Exception which is available\nat https://www.gnu.org/software/classpath/license.html.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphronmophobic%2Ftreemap-clj","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphronmophobic%2Ftreemap-clj","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphronmophobic%2Ftreemap-clj/lists"}