Skip to content

Instantly share code, notes, and snippets.

@respatialized
Last active April 9, 2025 18:39
Show Gist options
  • Save respatialized/e2e791e6dc5f1addb98c5b121e955ab7 to your computer and use it in GitHub Desktop.
Save respatialized/e2e791e6dc5f1addb98c5b121e955ab7 to your computer and use it in GitHub Desktop.
clerk leaflet-vega example
(ns viewers.leaflet
(:require [nextjournal.clerk.render.hooks :as hooks]))
(defn geojson
"Render function to take a GeoJSON-like Clojure map and create a js/Leaflet basemap from that layer."
[value]
(when value
(when-let [L (hooks/use-promise (js/import "https://esm.sh/[email protected]"))]
(let
[map-div-id (str (gensym))
m (atom nil)
attribution
"&copy; <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>"]
[:div
{:id map-div-id
:ref
(fn [el]
(when (and el (nil? @m))
(let
[tile-layer
(.tileLayer
L
#_"https://tile.openstreetmap.org/{z}/{x}/{y}.png"
"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
#_"https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}.png"
(clj->js {:attribution attribution}))
gjl (.geoJson L (clj->js value) (clj->js {}))]
(reset! m (.map L map-div-id #_{:renderer (.canvas js/L)}))
(.setView @m (clj->js [-73.949984 40.680000]) 13)
(.addTo tile-layer @m)
(.addTo gjl @m))))
:style {:height "700px"}}]))))
(defn vega-lite
[vl-spec]
(when vl-spec
(when-let [imports
(hooks/use-promise
(js/import
"https://esm.sh/[email protected][email protected]"))]
(let
[map-div-id (str (gensym))
m (atom nil)
attribution
"&copy; <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>"]
(js/console.log (.getOwnPropertyNames js/Object js/L))
[:div
{:id map-div-id
:ref
(fn [el]
(when el
(let
[vega-layer (.vega js/L (clj->js vl-spec) (clj->js {}))
tile-layer
(.tileLayer
js/L
#_"https://tile.openstreetmap.org/{z}/{x}/{y}.png"
"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png"
#_"https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}.png"
(clj->js {:attribution attribution}))]
(reset! m (.map js/L map-div-id {:renderer (.canvas js/L)}))
(.setView @m (clj->js [40.690214 -73.986964]) 13)
(.addTo tile-layer @m)
(.addTo vega-layer @m))))
:style {:height "500px"}}]))))
(ns leaflet-notebook
(:require [nextjournal.clerk :as clerk]))
^{::clerk/visibility {:code :hide :result :hide}}
(alter-var-root
#'nextjournal.clerk.view/include-css+js
(fn [include-fn]
(fn [state]
(concat (include-fn state)
(list (hiccup.page/include-css
"https://unpkg.com/[email protected]/dist/leaflet.css"))))))
^{::clerk/visibility {:result :hide}}
(def sample-geojson
{"features" [{:geometry {:coordinates [[[-73.949484 40.680000]
[-73.949984 40.680000]
[-73.949984 40.681000]
[-73.949484 40.680000]]]
:type "Polygon"}
"properties" {"key" "value"}
:type "Feature"}]
"type" "FeatureCollection"})
^{::clerk/visibility {:result :hide}}
(def vega-lite-us-unemployment
{"$schema" "https//vega.github.io/schema/vega-lite/v5.json"
"width" 500
"height" 300
"data" {"url" "https//vega.github.io/vega-lite/data/us-10m.json"
"format" {"type" "topojson" "feature" "counties"}}
"transform" [{"lookup" "id"
"from" {"data" {"url" "data/unemployment.tsv"}
"key" "id"
"fields" ["rate"]}}]
"mark" "geoshape"
"encoding" {"color" {"field" "rate" "type" "quantitative"}}})
(clerk/with-viewer {:render-fn 'viewers.leaflet/geojson
:require-cljs true
:transform-fn clerk/mark-presented}
sample-geojson)
^{::clerk/cache false}
(clerk/with-viewer {:render-fn 'viewers.leaflet/vega-lite
:require-cljs true
:transform-fn clerk/mark-presented}
vega-lite-us-unemployment)
(comment
(clerk/serve! {})
(clerk/show! *ns*))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment