generated from hrbrmstr/vite-webr-lit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
110 lines (109 loc) · 17.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!DOCTYPE html>
<!-- This file was auto-generated by exmd at 2023-04-02T08:38:46.857Z. Do NOT edit by hand! -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🧪 Experimenting With Observable Shorthand Plots, WebR, and Lit+Vite</title><meta property="og:title" content="🧪 Experimenting With Observable Shorthand Plots, WebR, and Lit+Vite">
<meta property="twitter:title" content="🧪 Experimenting With Observable Shorthand Plots, WebR, and Lit+Vite">
<meta name="description" content="Using data from R to drive a whole lotta plottin'">
<meta property="og:description" content="Using data from R to drive a whole lotta plottin'">
<meta property="twitter:description" content="Using data from R to drive a whole lotta plottin'">
<meta property="og:site" content="https://rud.is/w/webr-lit-plot">
<meta property="og:site_name" content="WebR Exeriments">
<meta property="og:image:url" content="https://rud.is/w/webr-lit-plot">
<meta property="og:image:width" content="1932">
<meta property="og:image:height" content="1170">
<meta property="og:image:alt" content="example">
<meta property="twitter:site_name" content="@hrbrmstr">
<meta property="twitter:domain" content="rud.is">
<meta property="twitter:card" content="summary_large_image">
<meta property="article:published_time" content="2023-04-02T08:38:46.858Z">
<link rel='apple-touch-icon' sizes='180x180' href='./favicon/apple-touch-icon.png'/>
<link rel='icon' type='image/png' sizes='32x32' href='./favicon/favicon-32x32.png'/>
<link rel='icon' type='image/png' sizes='16x16' href='./favicon/favicon-16x16.png'/>
<link rel='manifest' href='./favicon/site.webmanifest'/>
<link href='./src/index.css' rel='stylesheet'/>
<link href='./src/components.css' rel='stylesheet'/>
<script type='module' src='./src/main.js'></script>
</head>
<body>
<h1>🧪 Experimenting With Observable Shorthand Plots, WebR, and Lit+Vite</h1>
<p><status-message id="webr-status" text="WebR Loading…"></status-message></p>
<h2>Letting R Data Drive Many Observable Plots</h2>
<p>Experiment parameters:</p>
<ul>
<li>Webr</li>
<li>R template tag function</li>
<li>Observable Plot (shorhand version)</li>
<li>Lit (web components)</li>
<li>Vite (for building)</li>
<li>hrbrmstr's lame CSS skills</li>
</ul>
<p>Some data, courtesy of a sad little R function that mangles the data from the the Observable Plot example:</p>
<p><double-display id="r-doublres"></double-display></p>
<p><ojs-shorthand-plot chartTitle="CellX Mark" id="cellX"></ojs-shorthand-plot></p>
<p><a href="https://observablehq.com/collection/@observablehq/plot">Observable Plot</a> specifications can be just as involved and complex as the most bespoke {ggplot2} plots in R. Observable Plot still has a bunch of catching up to do to {ggplot2}, but it's absolutely getting there.</p>
<p>Like {ggplot2}, Plot has sensible defaults for pretty much everything. And, like {ggplot2}, you can give a geom (<code>mark</code> in Observable/Vega land) some data, and it'll do it's thing.</p>
<p>Plot also has a <a href="https://observablehq.com/@observablehq/plot-shorthand">shorthand</a> mode for a fair number of marks, which is the subject of today's experiment. We're riffing from that notebook, so you might want to look at it before continuing, or have it up while continuing.</p>
<p>The data above is just random data generated by R every second-ish. We're also letting R generate some dates for us that are used in the last two plots on this page. We make a <em>sort of</em> <code>data.frame</code> with it as such:</p>
<pre class="shiki " style="background-color: #0b0e14" tabindex="0"><code><span class="line"><span style="color: #FF8F40">const</span><span style="color: #BFBDB6"> rDates </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> </span><span style="color: #FF8F40">await</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">R</span><span style="color: #AAD94C">`</span></span>
<span class="line"><span style="color: #AAD94C">seq.Date(as.Date("2018-01-02"), as.Date("2018-02-28"), "1 day") |> </span></span>
<span class="line"><span style="color: #AAD94C"> as.character()</span></span>
<span class="line"><span style="color: #AAD94C">`</span></span>
<span class="line"><span style="color: #FF8F40">const</span><span style="color: #BFBDB6"> dateArray </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> rDates</span><span style="color: #F29668">.</span><span style="color: #FFB454">map</span><span style="color: #BFBDB6">(</span><span style="color: #D2A6FF">d</span><span style="color: #BFBDB6"> </span><span style="color: #FF8F40">=></span><span style="color: #BFBDB6"> </span><span style="color: #F29668">new</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">Date</span><span style="color: #BFBDB6">(d))</span></span>
<span class="line"><span style="color: #BFBDB6">…</span></span>
<span class="line"><span style="color: #FF8F40">const</span><span style="color: #BFBDB6"> timeSeries </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> numbers</span><span style="color: #F29668">.</span><span style="color: #FFB454">map</span><span style="color: #BFBDB6">((</span><span style="color: #D2A6FF">d</span><span style="color: #BFBDB6B3">,</span><span style="color: #BFBDB6"> </span><span style="color: #D2A6FF">i</span><span style="color: #BFBDB6">) </span><span style="color: #FF8F40">=></span><span style="color: #BFBDB6"> {</span></span>
<span class="line"><span style="color: #BFBDB6"> </span><span style="color: #FF8F40">return</span><span style="color: #BFBDB6"> [ dateArray[i]</span><span style="color: #BFBDB6B3">,</span><span style="color: #BFBDB6"> d ]</span></span>
<span class="line"><span style="color: #BFBDB6">})</span></span>
<span class="line"></span></code></pre>
<p><em>(If you can't tell, I'm still far more comfortable in R than in JavaScript and will likely always be.)</em></p>
<p>It looks like what you see <a href="https://observablehq.com/@observablehq/plot-shorthand?collection=@observablehq/plot#timeSeries">in this cell</a>.</p>
<p>If you "view source" on the HTML page, all you're going to see (apart from the color commentary and source code) is this (whitespace removed and one component moved for brevity/clarity):</p>
<pre class="shiki " style="background-color: #0b0e14" tabindex="0"><code><span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"BoxX Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"boxX"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"LineY Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"lineY"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"AreaY Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"areaY"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"RectY Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"rectY"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"DotX Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"dotX"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"Line Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"line"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"><span style="color: #39BAE680"><</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">chartTitle</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"Dot Mark"</span><span style="color: #BFBDB6"> </span><span style="color: #FFB454">id</span><span style="color: #BFBDB6B3">=</span><span style="color: #AAD94C">"dot"</span><span style="color: #39BAE680">></</span><span style="color: #39BAE6">ojs-shorthand-plot</span><span style="color: #39BAE680">></span></span>
<span class="line"></span></code></pre>
<p>[Lit] Web Components keep HTML source pretty tidy.</p>
<p>We started off with a <a href="https://observablehq.com/@observablehq/plot-cell"><code>CellX</code></a> mark because it's colorful and I wanted a chart right up front.</p>
<p>We fed it that array of 40 doubles, and you should have immediately noticed that the values were encoded as the cell <em>fill</em> color. The default quantitative color scheme in Plot is called <em>turbo</em>; higher values are reddish, and lower values blueish. In this simple example we're not changing that, mostly to show you get good defaults out of the box.</p>
<p>I don't need to repeat the hard work of the Observable folks, so the various <code>mark</code> encoding explanations in their notebook will suffice, save for the fact that I'm using random numbers and they used a static data set.</p>
<p>If you look in <code>main.js</code>, you'll see how short the calls to Plot are:</p>
<pre class="shiki " style="background-color: #0b0e14" tabindex="0"><code><span class="line"><span style="color: #BFBDB6">cellXchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">cellX</span><span style="color: #BFBDB6">(numbers)</span></span>
<span class="line"><span style="color: #BFBDB6">boxXchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">boxX</span><span style="color: #BFBDB6">(numbers)</span></span>
<span class="line"><span style="color: #BFBDB6">lineYchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">lineY</span><span style="color: #BFBDB6">(numbers)</span></span>
<span class="line"><span style="color: #BFBDB6">areaYchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">areaY</span><span style="color: #BFBDB6">(numbers</span><span style="color: #BFBDB6B3">,</span><span style="color: #BFBDB6"> {})</span></span>
<span class="line"><span style="color: #BFBDB6">rectYchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">rectY</span><span style="color: #BFBDB6">(numbers)</span></span>
<span class="line"><span style="color: #BFBDB6">dotXchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">dotX</span><span style="color: #BFBDB6">(numbers)</span></span>
<span class="line"></span></code></pre>
<p>Sure, I tweaked the colors a bit, but that's also not verbose:</p>
<pre class="shiki " style="background-color: #0b0e14" tabindex="0"><code><span class="line"><span style="color: #BFBDB6">boxXchart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">style </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> { backgroundColor</span><span style="color: #BFBDB6B3">:</span><span style="color: #BFBDB6"> background</span><span style="color: #BFBDB6B3">,</span><span style="color: #BFBDB6"> color</span><span style="color: #BFBDB6B3">:</span><span style="color: #BFBDB6"> </span><span style="color: #AAD94C">"#3a579a"</span><span style="color: #BFBDB6"> }</span></span>
<span class="line"></span></code></pre>
<p>I'll blather a bit further when you get to the two-dimensional charts.</p>
<p><ojs-shorthand-plot chartTitle="BoxX Mark" id="boxX"></ojs-shorthand-plot></p>
<p><ojs-shorthand-plot chartTitle="LineY Mark" id="lineY"></ojs-shorthand-plot></p>
<p><ojs-shorthand-plot chartTitle="AreaY Mark" id="areaY"></ojs-shorthand-plot></p>
<p><ojs-shorthand-plot chartTitle="RectY Mark" id="rectY"></ojs-shorthand-plot></p>
<p><ojs-shorthand-plot chartTitle="DotX Mark" id="dotX"></ojs-shorthand-plot></p>
<p>That <code>timeSeries</code> variable is fed into the Line and Dot mark plots. It's also really short:</p>
<pre class="shiki " style="background-color: #0b0e14" tabindex="0"><code><span class="line"><span style="color: #BFBDB6">lineChart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">line</span><span style="color: #BFBDB6">(timeSeries)</span></span>
<span class="line"><span style="color: #BFBDB6">dotChart</span><span style="color: #F29668">.</span><span style="color: #BFBDB6">chart </span><span style="color: #F29668">=</span><span style="color: #BFBDB6"> Plot</span><span style="color: #F29668">.</span><span style="color: #FFB454">dot</span><span style="color: #BFBDB6">(timeSeries)</span></span>
<span class="line"></span></code></pre>
<p><ojs-shorthand-plot chartTitle="Line Mark" id="line"></ojs-shorthand-plot></p>
<p><ojs-shorthand-plot chartTitle="Dot Mark" id="dot"></ojs-shorthand-plot></p>
<p>Notice how it handles the date scale on the X axis. You can <a href="https://observablehq.com/@observablehq/plot-shorthand#cell-478">read more about that</a> in the original notebook.</p>
<h2>FIN</h2>
<p>Each plot is reusing the <code>ojs-shorthand-plot</code> component defined in the semantically named <code>obs-shorthand-plot.js</code> file and they all use the same data randomly generated by WebR every second.</p>
<p>Note that we call the actual <code>.plot({…})</code> method in the component so it handles the rendering.</p>
<p>The component is really misnamed since you can use any OBS Plot in it, but I or you should do far more tweaking of it to ensure it will work for most cases.</p>
<p>Even if we get speedier {ggplot2} load times, I think it'd be good for R folks to take Observable Plot for a spin in JS-land, and consider leaning <em>heavily</em> on it for displaying most fundamental charts.</p>
<p>Oh, and these "static" web pages <a href="https://pagespeed.web.dev/analysis/https-rud-is-w-webr-lit-plot/4zg2reow30?form_factor=desktop">seem to do pretty well where Lighthouse is concerned</a>.</p>
<p>You can find the source <a href="https://github.com/hrbrmstr/webr-lit-plot">on GitHub</a>.</p>
<p style="text-align: center">Brought to you by @hrbrmstr</p>
<!-- extra body bits -->
</body>
</html>