Skip to content

Commit d076ff2

Browse files
authored
Merge branch 'main' into fil/render-api-docs
2 parents a1c43ca + 12ecfa7 commit d076ff2

File tree

254 files changed

+21973
-3397
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

254 files changed

+21973
-3397
lines changed

.github/ISSUE_TEMPLATE/bug.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: Bug
3+
about: Something isn’t working
4+
labels: "bug"
5+
---

.github/ISSUE_TEMPLATE/enhancement.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
name: Enhancement
3+
about: New feature or request
4+
labels: "enhancement"
5+
---

CHANGELOG-2023.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ Plot.bollingerY(aapl, {x: "Date", y: "Close", n: 20, k: 2}).plot()
233233

234234
The [arrow mark](https://observablehq.com/plot/marks/arrow) supports a new **sweep** option to control the bend orientation. Below, we set this option to *-y* to draw arrows bulging right, independent of the relative vertical positions of its source and target.
235235

236-
[<img src="./img/arc-diagram.png" width="521" alt="Detail of an arc diagram connecting characters in Les Misérables that appear in the same chapters.">](https://observablehq.com/@observablehq/plot-arc-diagram?intent=fork)
236+
[<img src="./img/arc-diagram.png" width="521" alt="Detail of an arc diagram connecting characters in Les Misérables that appear in the same chapters.">](https://observablehq.com/@observablehq/plot-arc-diagram)
237237

238238
```js
239239
Plot.plot({

CHANGELOG.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,117 @@
22

33
Year: **Current (2024)** · [2023](./CHANGELOG-2023.md) · [2022](./CHANGELOG-2022.md) · [2021](./CHANGELOG-2021.md)
44

5+
## 0.6.16
6+
7+
[Released August 6, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.16)
8+
9+
The new [waffle mark](https://observablehq.com/plot/marks/waffle) 🧇 displays a quantity (or quantitative extent) for a given category; unlike a [bar](https://observablehq.com/plot/marks/bar), a waffle is subdivided into cells that allow easier counting, making waffles useful for reading and comparing exact quantities. Plot’s waffle mark is highly configurable: it supports stacking, positive and negative values, rounded corners, partial cells for fractional counts, automatic row or column size determination (with optional override), and more!
10+
11+
[<img src="./img/waffle.png" width="708" alt="a waffle chart of Olympic athletes by weight">](https://observablehq.com/plot/marks/waffle)
12+
13+
```js
14+
Plot.plot({
15+
fx: {interval: 10},
16+
color: {legend: true},
17+
marks: [Plot.waffleY(olympians, Plot.groupZ({y: "count"}, {fill: "sex", sort: "sex", fx: "weight", unit: 10}))]
18+
})
19+
```
20+
21+
22+
All marks now support GeoJSON data and GeoJSON property shorthand, making it easier to work with GeoJSON. For example, below the data `counties` is a GeoJSON FeatureCollection, and `unemployment` refers to a property on each feature; the **fill** option is thus shorthand for `(d) => d.properties.unemployment`. The [geo mark](https://observablehq.com/plot/marks/geo) now also supports the **tip** option (via an implicit [centroid transform](https://observablehq.com/plot/transforms/centroid)), making it easier to use Plot’s [interactive tooltips](https://observablehq.com/plot/interactions/pointer).
23+
24+
[<img src="./img/geo-tip.png" width="708" alt="a choropleth map of unemployment by U.S. county">](https://observablehq.com/plot/marks/geo)
25+
26+
```js
27+
Plot.plot({
28+
projection: "albers-usa",
29+
color: {
30+
type: "quantile",
31+
n: 9,
32+
scheme: "blues",
33+
label: "Unemployment (%)",
34+
legend: true
35+
},
36+
marks: [
37+
Plot.geo(counties, {
38+
fill: "unemployment",
39+
title: (d) => `${d.properties.name} ${d.properties.unemployment}%`,
40+
tip: true
41+
})
42+
]
43+
})
44+
```
45+
46+
All marks now also support column name channel shorthand when using Apache Arrow tables as data, and we’ve added detection of Arrow date-type columns. (Arrow represents temporal data using BigInt rather than Date.)
47+
48+
```js
49+
Plot.dot(gistemp, {x: "Date", y: "Anomaly"}).plot() // gistemp is an Arrow Table!
50+
```
51+
52+
The rect-like marks ([rect](https://observablehq.com/plot/marks/rect), [bar](https://observablehq.com/plot/marks/bar), [cell](https://observablehq.com/plot/marks/cell), and [frame](https://observablehq.com/plot/marks/frame)) now support individual rounding options for each side (**rx1**, **ry1**, *etc.*) and corner (**rx1y1**, **rx2y1**, *etc.*). This allows you to round just the top side of rects. You can even use a negative corner radius on the bottom side for seamless stacking, as in the histogram of Olympic athletes below.
53+
54+
[<img src="./img/rect-rounded.png" width="708" alt="a histogram of Olympic athletes by weight">](https://observablehq.com/plot/marks/rect)
55+
56+
```js
57+
Plot.plot({
58+
color: {legend: true},
59+
marks: [
60+
Plot.rectY(olympians, Plot.binX({y: "count"}, {x: "weight", fill: "sex", ry2: 4, ry1: -4, clip: "frame"})),
61+
Plot.ruleY([0])
62+
]
63+
})
64+
```
65+
66+
Plot now respects the projection **domain** when determining the default plot height. Previously, the map below would use a default square aspect ratio for the *conic-conformal* projection regardless of the specified **domain**, but now the map is perfectly sized to fit North Carolina. (Plot also now chooses a smarter default plot height when the ordinal *y* scale domain is empty.)
67+
68+
<img src="./img/geo-nc.png" width="659" alt="an unlabeled map showing the outline and counties of North Carolina">
69+
70+
```js
71+
Plot.plot({
72+
projection: {.
73+
type: "conic-conformal",
74+
parallels: [34 + 20 / 60, 36 + 10 / 60],
75+
rotate: [79, 0],
76+
domain: state
77+
},
78+
marks: [
79+
Plot.geo(counties, {strokeOpacity: 0.2}),
80+
Plot.geo(state)
81+
]
82+
})
83+
```
84+
85+
The [marker options](https://observablehq.com/plot/features/markers) now render as intended on marks with varying aesthetics, such as the spiraling arrows of varying thickness and color below.
86+
87+
<img src="./img/group-marker.png" width="659" alt="several spiraling lines emanate from the center of the image, with rainbow color and increasing thickness, each capped with a pointed arrow at the end">
88+
89+
```js
90+
Plot.plot({
91+
inset: 40,
92+
axis: null,
93+
marks: [
94+
Plot.line(d3.range(400), {
95+
x: (i) => i * Math.sin(i / 100 + ((i % 5) * 2 * Math.PI) / 5),
96+
y: (i) => i * Math.cos(i / 100 + ((i % 5) * 2 * Math.PI) / 5),
97+
z: (i) => i % 5,
98+
stroke: (i) => -i,
99+
strokeWidth: (i) => i ** 1.1 / 100,
100+
markerEnd: "arrow"
101+
})
102+
]
103+
})
104+
```
105+
106+
This release includes a few more new features, bug fixes, and improvements:
107+
108+
The new **className** [mark option](https://observablehq.com/plot/features/marks#mark-options) specifies an optional `class` attribute for rendered marks, allowing styling of marks via external stylesheets or easier selection via JavaScript; thanks, @RLesser! Plot now reuses `clipPath` elements, when possible, when the **clip** mark option is set to *frame* or *projection*.
109+
110+
The [difference mark](https://observablehq.com/plot/marks/difference) now supports a horizontal orientation via [differenceX](https://observablehq.com/plot/marks/difference#differenceX), and the [shift transform](https://observablehq.com/plot/transforms/shift) now likewise supports [shiftY](https://observablehq.com/plot/transforms/shift#shiftY). The [Voronoi mark](https://observablehq.com/plot/marks/delaunay) is now compatible with the pointer transform: only the pointed Voronoi cell is rendered; the Voronoi mark now also renders as intended with non-exclusive facets (as when using the *exclude* facet mode). The [tip mark](https://observablehq.com/plot/marks/tip) no longer displays channels containing literal color values by default.
111+
112+
## 0.6.15
113+
114+
[Released June 11, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.15)
115+
5116
## 0.6.14
6117

7118
[Released March 12, 2024.](https://github.com/observablehq/plot/releases/tag/v0.6.14)

docs/.vitepress/config.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import plot from "./markdown-it-plot.js";
88
export default defineConfig({
99
title: "Observable Plot",
1010
description: "The JavaScript library for exploratory data visualization",
11+
appearance: "force-auto",
1112
base: "/plot/",
1213
cleanUrls: true,
1314
vite: {
@@ -24,6 +25,9 @@ export default defineConfig({
2425
}
2526
},
2627
head: [
28+
["link", {rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: ""}],
29+
["link", {rel: "preload", as: "style", href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap"}],
30+
["link", {rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap"}],
2731
["link", {rel: "apple-touch-icon", href: "https://static.observablehq.com/favicon-512.0667824687f99c942a02e06e2db1a060911da0bf3606671676a255b1cf97b4fe.png"}],
2832
["link", {rel: "icon", type: "image/png", href: "https://static.observablehq.com/favicon-512.0667824687f99c942a02e06e2db1a060911da0bf3606671676a255b1cf97b4fe.png", sizes: "512x512"}],
2933
["script", {async: "", src: "https://www.googletagmanager.com/gtag/js?id=G-9B88TP6PKQ"}],
@@ -68,6 +72,7 @@ export default defineConfig({
6872
{text: "Legends", link: "/features/legends"},
6973
{text: "Curves", link: "/features/curves"},
7074
{text: "Formats", link: "/features/formats"},
75+
{text: "Intervals", link: "/features/intervals"},
7176
{text: "Markers", link: "/features/markers"},
7277
{text: "Shorthand", link: "/features/shorthand"},
7378
{text: "Accessibility", link: "/features/accessibility"}
@@ -105,7 +110,8 @@ export default defineConfig({
105110
{text: "Tick", link: "/marks/tick"},
106111
{text: "Tip", link: "/marks/tip"},
107112
{text: "Tree", link: "/marks/tree"},
108-
{text: "Vector", link: "/marks/vector"}
113+
{text: "Vector", link: "/marks/vector"},
114+
{text: "Waffle", link: "/marks/waffle"}
109115
]
110116
},
111117
{

docs/.vitepress/markdown-it-plot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default function plot(md) {
2626
directives.includes("hidden")
2727
? `<div style="display: none;">\n`
2828
: href
29-
? `<a class="plot-fork no-icon" href="${md.utils.escapeHtml(href)}?intent=fork" target="_blank" title="Open on Observable">Fork</a>`
29+
? `<a class="plot-fork no-icon" href="${md.utils.escapeHtml(href)}" target="_blank" title="Open on Observable">Fork</a>`
3030
: ""
3131
}`;
3232
if (/^Plot\.plot\(/.test(content)) {

docs/.vitepress/theme/CustomFooter.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
<li class="mb2"><a target="_blank" href="https://observablehq.com/plot">Plot</a></li>
2626
<li class="mb2"><a target="_blank" href="https://observablehq.com/data-integrations">Integrations</a></li>
2727
<li class="mb2"><a target="_blank" href="https://observablehq.com/pricing">Pricing</a></li>
28-
<li class="mb2"><a target="_blank" href="https://observablehq.com/enterprise">Enterprise</a></li>
2928
</ul>
3029
</div>
3130
</div>

docs/.vitepress/theme/ExamplesGrid.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ onUnmounted(() => {
4949
<template>
5050
<div :class="$style.examples" ref="container" :style="`transform: translate(${60 - x * 10}vw, 33%);`">
5151
<div v-for="(d, i) in sample" :style="`--delay: ${((i % xn) / xn + (d3.randomLcg(1 / i)()) - 0.4) * 1}s;`">
52-
<a :href="`https://observablehq.com/${d.path}${d.path.includes('?') ? '&' : '?'}intent=fork`" :title="[d.title, d.author].filter(Boolean).join('\n')" target="_blank" :style="`--x: ${(i % xn) - xn / 2 + (Math.floor(i / xn) % 2) * 0.5}; --y: ${Math.floor(i / xn) - yn / 2};`">
52+
<a :href="`https://observablehq.com/${d.path}`" :title="[d.title, d.author].filter(Boolean).join('\n')" target="_blank" :style="`--x: ${(i % xn) - xn / 2 + (Math.floor(i / xn) % 2) * 0.5}; --y: ${Math.floor(i / xn) - yn / 2};`">
5353
<img :src="`https://static.observableusercontent.com/thumbnail/${d.thumbnail}.jpg`" width="640" height="400" />
5454
</a>
5555
</div>

docs/.vitepress/theme/ObservablePromo.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ h1 {
6262
opacity: 0.7;
6363
}
6464
65-
a.button {
65+
.promo a.button {
6666
display: inline-block;
6767
border: 1px solid transparent;
6868
text-align: center;

docs/.vitepress/theme/custom.css

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,45 @@
11
:root {
2-
--vp-c-purple-1: #7135be;
3-
--vp-c-purple-2: #7f42cd;
4-
--vp-c-purple-3: #9555e2;
5-
--vp-c-purple-soft: rgba(155, 91, 233, 0.14);
2+
--vp-c-red: #f43f5e;
3+
--vp-c-green: #10b981;
4+
--vp-c-blue: #0092ff;
5+
--vp-c-purple: #a463f2;
6+
--theme-phosphate: #148576;
7+
--theme-phosphate-2: #1da492;
8+
--theme-phosphate-3: #26c1ad;
9+
--theme-phosphate-soft: #d7fbf7;
10+
--vp-c-brand-1: var(--theme-phosphate); /* link and brand color */
11+
--vp-c-brand-2: var(--theme-phosphate-2);
12+
--vp-c-brand-3: var(--theme-phosphate-3);
13+
--hero-brand-contrast: rgb(243, 139, 233); /* home page alt color */
14+
--vp-c-brand-soft: var(--theme-phosphate-soft);
15+
--mono-heading: "Spline Sans Mono", monospace;
16+
--vp-font-family-mono: var(--mono-heading);
17+
--vp-font-family-base: Inter, -apple-system, BlinkMacSystemFont, "avenir next", avenir, helvetica, "helvetica neue", ubuntu, roboto, noto, "segoe ui", arial, sans-serif;
18+
--vp-code-color: inherit;
19+
--vp-code-font-size: 14px;
20+
--vp-code-line-height: 1.5;
621
}
722

823
.dark {
9-
--vp-c-purple-1: #db96ff;
10-
--vp-c-purple-2: #9a5ae8;
11-
--vp-c-purple-3: #884ad6;
12-
--vp-c-purple-soft: rgba(155, 91, 233, 0.16);
24+
--theme-phosphate: #37d5be;
25+
--theme-phosphate-2: #28b39e;
26+
--theme-phosphate-3: #1b9583;
27+
--hero-brand-contrast: rgb(183, 41, 169);
28+
--theme-phosphate-soft: #033a32;
29+
--vp-c-text-1: #f5f5f5;
1330
}
1431

15-
:root {
16-
--vp-c-red: #f43f5e;
17-
--vp-c-green: #10b981;
18-
--vp-c-blue: #0092ff;
19-
--vp-c-purple: #a463f2;
20-
--vp-c-brand-1: var(--vp-c-purple-1);
21-
--vp-c-brand-2: var(--vp-c-purple-2);
22-
--vp-c-brand-3: var(--vp-c-purple-3);
23-
--vp-c-brand-soft: var(--vp-c-purple-soft);
24-
--vp-font-family-base: -apple-system, BlinkMacSystemFont, "avenir next", avenir, helvetica, "helvetica neue", ubuntu, roboto, noto, "segoe ui", arial, sans-serif;
32+
.vp-doc h1 {
33+
font-family: var(--mono-heading);
34+
font-weight: 500;
35+
}
36+
37+
.vp-doc p {
38+
line-height: 1.5;
39+
}
40+
41+
.vp-doc a {
42+
color: var(--vp-c-text-1);
2543
}
2644

2745
.vp-doc figcaption {

docs/.vitepress/theme/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export default {
1717
}
1818
};
1919

20-
async function enableAnalytics(router) {
20+
function enableAnalytics(router) {
2121
if (typeof location === "undefined" || location.origin !== "https://observablehq.com") return;
22-
const {pageLoad, routeChanged} = await import("https://events.observablehq.com/client.js");
23-
let pageLoaded;
24-
watch(router.route, () => {
22+
let pageLoaded = false;
23+
watch(router.route, async () => {
24+
const {pageLoad, routeChanged} = await import("https://events.observablehq.com/client.js");
2525
if (pageLoaded) {
2626
routeChanged();
2727
} else {

docs/community.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ And of course, follow us on [Observable](https://observablehq.com/@observablehq?
1414

1515
## Getting help
1616

17-
We recommend asking for help on the [Observable forum](https://talk.observablehq.com/c/help/6). Or if you prefer chat, join the [Observable community Slack](https://observablehq.com/slack/join).
17+
We recommend asking for help on [GitHub discussions](https://github.com/observablehq/plot/discussions).
1818

1919
We encourage you to share your work, no matter how messy, on [Observable](https://observablehq.com). Sharing live code is the easiest way to let people see what you see, and to debug your problem. Strive for a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) — it helps people hone in on your problem more quickly.
2020

@@ -35,7 +35,9 @@ We’d love for you to join the community! Here are some ways to participate:
3535

3636
* Upvote 👍 or comment on [GitHub issues](https://github.com/observablehq/plot/issues). We’d love your input on what to build next. If your desired feature isn’t already there, or if you’ve found a bug, file an issue and tell us about it.
3737

38-
* Answer questions or participate in discussions on the [Observable forum](https://talk.observablehq.com/) and the [Observable community Slack](https://observablehq.com/slack/join). You’ll help others, and might learn something yourself, too.
38+
* Answer questions or participate in discussions on [GitHub](https://github.com/observablehq/plot/discussions). You’ll help others, and might learn something yourself, too.
39+
40+
* Join the [Observable community Slack](https://observablehq.com/slack/join) to meet others using Plot.
3941

4042
* Open a pull request! Read our [guide to contributing](https://github.com/observablehq/plot/blob/main/CONTRIBUTING.md).
4143

docs/components/PlotRender.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ class Element {
9090
child.parentNode = this;
9191
return child;
9292
}
93+
cloneNode(deep) {
94+
const clone = new Element(this.ownerDocument, this.tagName);
95+
clone.attributes = {...this.attributes};
96+
if (deep) clone.children = this.children.map((child) => child.cloneNode(deep));
97+
return clone;
98+
}
9399
querySelector() {
94100
return null;
95101
}

docs/data/api.data.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ function getHref(name: string, path: string): string {
4343
switch (path) {
4444
case "features/curve":
4545
case "features/format":
46+
case "features/interval":
4647
case "features/mark":
4748
case "features/marker":
4849
case "features/plot":
4950
case "features/projection":
5051
return `${path}s`;
51-
case "features/inset":
52-
return "features/scales";
5352
case "features/options":
5453
return "features/transforms";
5554
case "marks/axis": {
@@ -84,8 +83,8 @@ function getInterfaceName(name: string, path: string): string {
8483
name = name.replace(/([a-z0-9])([A-Z])/, (_, a, b) => `${a} ${b}`); // camel case conversion
8584
name = name.toLowerCase();
8685
if (name === "curve auto") name = "curve";
87-
if (name === "plot facet") name = "plot";
88-
if (name === "bollinger window") name = "bollinger map method";
86+
else if (name === "plot facet") name = "plot";
87+
else if (name === "bollinger window") name = "bollinger map method";
8988
else if (path.startsWith("marks/")) name += " mark";
9089
else if (path.startsWith("transforms/")) name += " transform";
9190
return name;
@@ -104,10 +103,15 @@ export default {
104103
if (Node.isInterfaceDeclaration(declaration)) {
105104
if (isInternalInterface(name)) continue;
106105
for (const property of declaration.getProperties()) {
107-
const path = index.getRelativePathTo(declaration.getSourceFile());
108-
const href = getHref(name, path);
109106
if (property.getJsDocs().some((d) => d.getTags().some((d) => Node.isJSDocDeprecatedTag(d)))) continue;
110-
allOptions.push({name: property.getName(), context: {name: getInterfaceName(name, path), href}});
107+
if (name === "InsetOptions") {
108+
allOptions.push({name: property.getName(), context: {name: "mark", href: "features/marks"}});
109+
allOptions.push({name: property.getName(), context: {name: "scale", href: "features/scales"}});
110+
} else {
111+
const path = index.getRelativePathTo(declaration.getSourceFile());
112+
const href = getHref(name, path);
113+
allOptions.push({name: property.getName(), context: {name: getInterfaceName(name, path), href}});
114+
}
111115
}
112116
} else if (Node.isFunctionDeclaration(declaration)) {
113117
const comment = getDescription(declaration);
@@ -140,7 +144,9 @@ export default {
140144
throw new Error(`anchor not found: ${href}#${name}`);
141145
}
142146
}
143-
for (const {context: {href}} of allOptions) {
147+
for (const {
148+
context: {href}
149+
} of allOptions) {
144150
if (!anchors.has(`/${href}.md`)) {
145151
throw new Error(`file not found: ${href}`);
146152
}

docs/features/facets.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ Faceting can be explicitly enabled or disabled on a mark with the **facet** opti
246246

247247
When mark-level faceting is used, the default *auto* setting is equivalent to *include*: the mark will be faceted if either the **fx** or **fy** channel option (or both) is specified. The null or false option will disable faceting, while *exclude* draws the subset of the mark’s data *not* in the current facet. When a mark uses *super* faceting, it is not allowed to use position scales (*x*, *y*, *fx*, or *fy*); *super* faceting is intended for decorations, such as labels and legends.
248248

249-
The **facetAnchor** option<a id="facetAnchor" class="header-anchor" href="#facetAnchor" aria-label="Permalink to &quot;facetAnchor&quot;"></a> <VersionBadge version="0.6.3" /> controls the placement of the mark with respect to the facets. Based on the value, the mark will be displayed on:
249+
The **facetAnchor** option<a id="facetAnchor" href="#facetAnchor" aria-label="Permalink to &quot;facetAnchor&quot;"></a> <VersionBadge version="0.6.3" /> controls the placement of the mark with respect to the facets. Based on the value, the mark will be displayed on:
250250

251251
* null - non-empty facets
252252
* *top*, *right*, *bottom*, or *left* - the given side

0 commit comments

Comments
 (0)