Skip to content

Instantly share code, notes, and snippets.

@cnuernber
Created October 31, 2019 12:39
Show Gist options
  • Select an option

  • Save cnuernber/25e14a8b3a56c52faa8874afe5954ef8 to your computer and use it in GitHub Desktop.

Select an option

Save cnuernber/25e14a8b3a56c52faa8874afe5954ef8 to your computer and use it in GitHub Desktop.
(ns vegafx.core
(:import [javafx.application Platform]
[javafx.beans.value ChangeListener]
[javafx.concurrent Worker$State]
[javafx.embed.swing JFXPanel]
[javafx.scene Scene]
[javafx.scene.web WebView]
[javafx.stage Stage]
[javafx.embed.swing SwingFXUtils]
[javax.imageio ImageIO])
(:require [clojure.java.io :as io]
[cheshire.core :as cheshire]))
(defonce force-toolkit-init (javafx.embed.swing.JFXPanel.))
(defn run-later*
[f]
(javafx.application.Platform/runLater f))
(defmacro run-later
[& body]
`(run-later* (fn [] ~@body)))
(defn run-now*
[f]
(let [result (promise)]
(run-later
(deliver result (try (f) (catch Throwable e e))))
@result))
(defmacro run-now
[& body]
`(run-now* (fn [] ~@body)))
(defn vega-script
[edn]
(str "vegaEmbed(\"#vis\","
(cheshire/generate-string edn)
",{\"actions\":false})"))
(defn dimensions
[engine id]
{:height (.executeScript engine "document.getElementById('vis').offsetHeight")
:width (.executeScript engine "document.getElementById('vis').offsetWidth")})
(def ^:dynamic *buffer* 20)
(defonce ^:dynamic *web-view* (atom nil))
(defn vega-lite
[edn]
(run-now
(let [web-view (WebView.)
engine (.getEngine web-view)]
(Platform/setImplicitExit false)
(.. engine getLoadWorker stateProperty
(addListener
(reify ChangeListener
(changed [this ob old new]
;; Wait until the page has loaded.
(when (= new Worker$State/SUCCEEDED)
(.executeScript engine (vega-script edn))
(let [{:keys [height width]} (dimensions engine "viz")]
(.setPrefSize web-view
(+ *buffer* width)
(+ *buffer* height))
(doto (Stage.)
(.setScene (Scene. web-view))
(.show))))))))
(reset! *web-view* web-view)
(.loadContent engine (slurp "index.html")))))
(defn take-snapshot
[]
(run-later
(try
(let [web-view @*web-view*
jfx-img (.snapshot web-view
(javafx.scene.SnapshotParameters.)
nil)
buf-img (SwingFXUtils/fromFXImage jfx-img nil)]
(ImageIO/write buf-img "PNG" (java.io.File. "test.png")))
(catch Throwable e
(println e)))))
(comment
(set! *warn-on-reflection* true)
(vega-lite {"$schema" "https://vega.github.io/schema/vega-lite/v2.0.json"
"data" {"values" [{"a" "A","b" 100}
{"a" "B","b" 55}
{"a" "C","b" 43}
{"a" "D","b" 91}
{"a" "E","b" 81}
{"a" "F","b" 53}
{"a" "G","b" 19}
{"a" "H","b" 87}
{"a" "I","b" 52}]}
"mark" "bar"
"encoding" {"x" {"field" "a", "type" "ordinal"}
"y" {"field" "b", "type" "quantitative"}}})
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment