6 Transpile API reference ๐ - experimental ๐งช
Sometimes, data visualization in the browser requires not only plain JSON structures but also some Javascript code.
One way to generate such code from Clojure is through std.lang, a universal transpiler from Clojure to many languages.
The transpile
API of Tableplot provides functions for using this practice in combination with various JS libraries. It is considered experimental at this stage.
6.1 Setup ๐จ
In this tutorial, we use:
- The Tableplot
transpile
API namepace - Tablecloth for dataset processing and column processing
- the datasets defined in the Datasets chapter
- Kindly to annotate the kind of way certain values should be displayed
ns tableplot-book.transpile-reference
(:require [scicloj.tableplot.v1.transpile :as transpile]
(:as tc]
[tablecloth.api :as datasets]
[tableplot-book.datasets :as book-utils]
[tableplot-book.book-utils :as str]
[clojure.string :as kind])) [scicloj.kindly.v4.kind
6.2 Functions โ
6.2.1 js
[& forms]
Transpile the given Clojure forms
to Javascript code using Std.lang.
6.2.1.1 Examples
(kind/code9)
(transpile/js '(var x + x 11)))) '(return (
let x = 9;
+ 11; return x
An adaptation of a Plotly.js example - Animations in Javascript:
(kind/hiccup:div
[:button {:onclick (transpile/js '(randomize))}
["Randomize!"]
:div {:style {:height "auto"}}
[:script
[
(transpile/js
'(var plotly-animaton-element document.currentScript.parentElement)
'(Plotly.newPlot plotly-animaton-element:x [1 2 3]
[{:y [0 0.5 1]
:line {:simplify false}}])
defn randomize []
'(
(Plotly.animate plotly-animaton-element:data [{:y [(Math.random)
{
(Math.random)
(Math.random)]}]:traces [0]
:layout {}}
:transition {:duration 500
{:easing "cut-in-out"}
:frame {:duration 500}})))]]]
:html/deps [:plotly]}) {
6.2.2 div-with-script
[data script kindly-options]
Create a general transpiled data visualization.
Given a data structure data
, a form script
, and a map kindly-options
create a corresponding Hiccup structure.
The structure will be a :div
with a :script
element that has some Javascript code.
The code is transpiled from script
with some variable bindings preceeding it:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options defined by deep-merging kindly-options
into *base-kindly-options*
.
6.2.2.1 Examples
Let us create an Apache Echarts plot.
(transpile/div-with-script;; data
1 2]
[[2 4]
[3 9]
[4 16]]
[;; script
['(var myChart
(echarts.init
document.currentScript.parentElement))list 'myChart.setOption
(:xAxis {}
{:yAxis {}
:series [{:type "scatter"
:data 'data}]})]
;; Kindly options (merged with default)
:html/deps [:echarts]
{:style {:height "300px"
:background "floralwhite"}})
6.2.2.2 A closer look
Let us create a Plotly.js plot with some custom event handling. We will explore the resulting structure a little bit.
def clickable-example
(
(transpile/div-with-script;; data (with symbol bindings)
'x [1 2 3 4]
{'y [3 4 9 16]}
;; script
['(var plotly-animaton-element document.currentScript.parentElement)
'(Plotly.newPlot plotly-animaton-element:data
{:x x
[{:y y
:mode "markers"
:type "scatter"
:marker {:size 20}}]
:layout {:title
"Would you please click the points?"}})
'(. plotly-animaton-element"plotly_click"
(on fn []
("Thanks for clicking."))))]
(alert ;; Kindly options
:html/deps [:plotly]})) {
First, let us see it visualized:
clickable-example
Now, let us check the metadata:
meta clickable-example) (
:kindly{:kind :kind/hiccup,
#:options {:style {:height :auto}, :html/deps [:plotly]}}
Now, let us pretty-print it to see the Hiccup structure.
(kind/pprint clickable-example)
:div
[:script
["(function () {\nlet data = {\"x\":[1,2,3,4],\"y\":[3,4,9,16]};\nlet x = data['x'];\nlet y = data['y'];\nlet plotly_animaton_element = document.currentScript.parentElement;\nPlotly.newPlot(plotly_animaton_element,{\n \"data\":[\n {\n \"x\":x,\n \"y\":y,\n \"mode\":\"markers\",\n \"type\":\"scatter\",\n \"marker\":{\"size\":20}\n }\n ],\n \"layout\":{\"title\":\"Would you please click the points?\"}\n});\nplotly_animaton_element.on(\"plotly_click\",function (){\n alert(\"Thanks for clicking.\");\n});\n})();"]]
Let us focus on the code of the script:
-> clickable-example
(second
second
kind/code)
(function () {let data = {"x":[1,2,3,4],"y":[3,4,9,16]};
let x = data['x'];
let y = data['y'];
let plotly_animaton_element = document.currentScript.parentElement;
Plotly.newPlot(plotly_animaton_element,{"data":[
{"x":x,
"y":y,
"mode":"markers",
"type":"scatter",
"marker":{"size":20}
}
],"layout":{"title":"Would you please click the points?"}
;
})"plotly_click",function (){
plotly_animaton_element.on("Thanks for clicking.");
alert(;
}); })()
6.2.3 echarts
[form]
[data form]
Given a data structure data
and a form form
, create a corresponding Apache Echarts data visualization using div-with-script
.
The script will include the following:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON. - The
form
transpiled to Javascript. - Additional code to visualize it.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options necessart to make the plot work.
If no data
value is passed, it is considered nil
.
6.2.3.1 Examples
(transpile/echarts;; data
1 2]
[[2 4]
[3 9]
[4 16]]
[;; form
:xAxis {}
{:yAxis {}
:series [{:type "scatter"
:data 'data}]})
-> datasets/mtcars
(:wt :mpg :cyl :gear])
(tc/select-columns [
tc/rows:xAxis {:name "weight"}
(transpile/echarts {:yAxis {:name "miles per gallon"}
:visualMap [{:dimension 2
:categories ["4" "6" "8"]
:inRange {:color ["#51689b", "#ce5c5c", "#fbc357"]}
:name "cylinders"}]
:tooltip {:formatter '(fn [obj]
(return+
("<p>weight:" (. obj value [0]) "</p>"
"<p>miles per fallon:" (. obj value [1]) "</p>"
"<p>cylinders:" (. obj value [2]) "</p>"
"<p>gears:" (. obj value [3]) "</p>")))}
:series [{:type "scatter"
:symbolSize '(fn [value]
-> value
(3])
(. [* 5)
(
return)):data 'data}]}))
6.2.4 plotly
[form]
[data form]
Given a data structure data
and a form form
, reate a corrseponding Plotly.js data visualization using div-with-script
.
The script will include the following:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON. - The
form
transpiled to Javascript. - Additional code to visualize it.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options necessart to make the plot work.
If no data
value is passed, it is considered nil
.
6.2.4.1 Examples
(transpile/plotly;; data
:x [1 2 3 4]
{:y [3 4 9 16]}
;; form
:data ['{:x data.x
{:y data.y
:mode "markers"
:type "scatter"}]})
(transpile/plotly;; data with symbol bindings
'x [1 2 3 4]
{'y [3 4 9 16]}
;; form
:data ['{:x x
{:y y
:mode "markers"
:type "scatter"}]})
6.2.5 vega-embed
[form]
[data form]
Given a data structure data
and a form form
, create a corresponding Vega-Embed data visualization using div-with-script
.
The script will include the following:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON. - The
form
transpiled to Javascript. - Additional code to visualize it.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options necessart to make the plot work.
If no data
value is passed, it is considered nil
.
6.2.5.1 Example
(transpile/vega-embed;; data
:x 1 :y 1}
[{:x 2 :y 4}
{:x 3 :y 9}
{:x 4 :y 16}]
{;; form
:data {:values 'data}
{:mark "point"
:encoding {:x {:field "x" :type "quantitative"}
:y {:field "y" :type "quantitative"}}})
6.2.6 highcharts
[form]
[data form]
Given a data structure data
and a form form
, create a corresponding Highcharts data visualization using div-with-script
.
The script will include the following:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON. - The
form
transpiled to Javascript. - Additional code to visualize it.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options necessart to make the plot work.
If no data
value is passed, it is considered nil
.
6.2.6.1 Example
(transpile/highcharts;; data
1 2]
[[2 4]
[3 9]
[4 16]]
[;; form
:title {:text "a scatterplot"}
{:chart {:type "scatter"}
:series [{:data 'data}]})
6.2.7 leaflet
[form]
[data form]
Given a data structure data
and a form form
, create a corresponding Leaflet data visualization using div-with-script
.
The script will include the following:
- A Javscript variable called
data
is bound to thedata
value converted to JSON. - If
data
is a map that has some keys of symbol type, then corresponding Javascript variables named by these symbols are bound to the corresponding values converted to JSON. - The
form
transpiled to Javascript, and is assumed to define a function to process a Leaflet map. - Additional code to visualize it.
The resulting structure is marked by the Kindly standard as kind/hiccup
with Kindly options necessart to make the plot work.
If no data
value is passed, it is considered nil
.
6.2.7.1 Example
(transpile/leaflet;; data with symbol bindings
'center [-37.84 144.95]
{'zoom 11
'provider "OpenStreetMap.Mapnik"
'marker [-37.9 144.8]
'popup "<i style='color:purple'>Have you been here?</i>"}
;; form
fn [m]
'(
(m.setView center zoom)-> (L.tileLayer.provider provider)
(
(. (addTo m)))-> marker
(
L.marker
(. (addTo m))
(. (bindPopup popup)) (. (openPopup)))))
6.3 Danymic vars ๐ง
6.3.1 *base-kindly-options*
Base Kindly options for structures generated by div-with-script
.
transpile/*base-kindly-options*
:style {:height :auto}} {