Skip to content

Commit 077a968

Browse files
authored
better client-side hydration (#1560)
1 parent ccaa681 commit 077a968

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

docs/components/PlotRender.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ class TextNode {
116116
}
117117
}
118118

119+
// Converts the real DOM to virtual DOM (for client-side hydration).
120+
function toHyperScript(node) {
121+
if (node.nodeType === 3) return node.nodeValue; // TextNode
122+
const props = {};
123+
for (const name of node.getAttributeNames()) props[name] = node.getAttribute(name);
124+
const children = [];
125+
for (let child = node.firstChild; child; child = child.nextSibling) children.push(toHyperScript(child));
126+
return h(node.tagName, props, children);
127+
}
128+
119129
export default {
120130
props: {
121131
options: Object,
@@ -197,6 +207,11 @@ export default {
197207
]
198208
);
199209
}
200-
return Plot[method]({...options, document: new Document()}).toHyperScript();
210+
if (typeof document !== "undefined") {
211+
const plot = Plot[method](options);
212+
const replace = (el) => el.firstChild.replaceWith(plot);
213+
return withDirectives(h("span", [toHyperScript(plot)]), [[{mounted: replace, updated: replace}]]);
214+
}
215+
return h("span", [Plot[method]({...options, document: new Document()}).toHyperScript()]);
201216
}
202217
};

docs/marks/auto.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ onMounted(() => {
1919

2020
The magic ✨ **auto mark** automatically selects a mark type that best represents the given dimensions of the data according to some simple heuristics. The auto mark—which powers [Observable’s chart cell](https://observablehq.com/@observablehq/chart-cell)—is intended to support fast exploratory analysis where the goal is to get a useful plot as quickly as possible. For example, two quantitative dimensions make a scatterplot:
2121

22-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-scatterplot
22+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-scatterplot
2323
```js
2424
Plot.auto(penguins, {x: "body_mass_g", y: "flipper_length_mm"}).plot()
2525
```
@@ -36,7 +36,7 @@ Because its heuristics are likely to evolve, they are not explicitly documented;
3636

3737
A monotonically increasing dimension (here *Date*, as the data is ordered chronologically), paired with a numeric column (*Close*), makes a line chart:
3838

39-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-line-chart
39+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-line-chart
4040
```js
4141
Plot.auto(aapl, {x: "Date", y: "Close"}).plot()
4242
```
@@ -50,7 +50,7 @@ Plot.auto(olympians, {x: "weight"}).plot()
5050
```
5151
:::
5252

53-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-ordinal-histogram
53+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-ordinal-histogram
5454
```js
5555
Plot.auto(penguins, {x: "island"}).plot()
5656
```
@@ -60,7 +60,7 @@ This is easier than deciding whether to use bin and rect, or group and bar: the
6060

6161
If you’d like to explicitly avoid grouping the data, you can opt out of the reducer, and get a one-dimensional plot:
6262

63-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-barcode
63+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-barcode
6464
```js
6565
Plot.auto(penguins, {x: "body_mass_g", y: {reduce: null}}).plot()
6666
```
@@ -92,21 +92,21 @@ Plot.auto(olympians, {x: "weight", y: "sex", color: "count"}).plot()
9292

9393
Similarly, with explicit marks and transforms, changing a vertical histogram to a horizontal histogram involves switching [rectY](./rect.md#recty-data-options) to [rectX](./rect.md#rectx-data-options), [binX](../transforms/bin.md#binx-outputs-options) to [binY](../transforms/bin.md#biny-outputs-options), **x** to **y**, and **y** to **x**. With the auto mark, just specify **y** instead of **x**:
9494

95-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-horizontal-histogram
95+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-horizontal-histogram
9696
```js
9797
Plot.auto(penguins, {y: "island"}).plot()
9898
```
9999
:::
100100

101101
For the sake of seamless switching, the auto mark has just one color channel, which it assigns to either **fill** or **stroke** depending on the mark. We can see that clearly by overriding a line chart with the **mark** option to make an area chart:
102102

103-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-color-channel
103+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-color-channel
104104
```js
105105
Plot.auto(industries, {x: "date", y: "unemployed", color: "industry"}).plot()
106106
```
107107
:::
108108

109-
:::plot defer
109+
:::plot
110110
```js
111111
Plot.auto(industries, {x: "date", y: "unemployed", color: "industry", mark: "area"}).plot()
112112
```
@@ -126,15 +126,15 @@ Plot
126126

127127
You can similarly pass a **zero** option to indicate that zero is meaningful for either **x** or **y**. This adds a corresponding rule to the returned mark.
128128

129-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-zero-option
129+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-zero-option
130130
```js
131131
Plot.auto(industries, {x: "date", y: {value: "unemployed", zero: true}, color: "industry"}).plot()
132132
```
133133
:::
134134

135135
The auto mark has a **size** channel, which (currently) always results in a dot. For now, it’s an alias for the dot’s **r** channel; in the future it will also represent a vector’s **length** channel.
136136

137-
:::plot defer https://observablehq.com/@observablehq/plot-auto-mark-size-channel
137+
:::plot https://observablehq.com/@observablehq/plot-auto-mark-size-channel
138138
```js
139139
Plot.auto(aapl, {x: "Date", y: "Close", size: "Volume"}).plot()
140140
```

0 commit comments

Comments
 (0)