Skip to content

Commit 203bd4c

Browse files
mbostockFil
andauthored
rounded rect (#2099)
* rounded rect * handle collapsed & 1d rects * remove unused test snapshot * ratio-preserving radius reduction * r shorthand; more docs * rounded frame * remove unused applyRoundedRect * rounded bar & cell * cleaner * remove unused import * slightly tidier * docs * negative radii * inset api index * more docs * Update docs/marks/rect.md Co-authored-by: Philippe Rivière <[email protected]> * test corner orientation exhaustively * tiny optimization * more docs * move docs around --------- Co-authored-by: Philippe Rivière <[email protected]>
1 parent 78cff33 commit 203bd4c

35 files changed

+2386
-137
lines changed

docs/data/api.data.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ function getHref(name: string, path: string): string {
4949
case "features/plot":
5050
case "features/projection":
5151
return `${path}s`;
52-
case "features/inset":
53-
return "features/scales";
5452
case "features/options":
5553
return "features/transforms";
5654
case "marks/axis": {
@@ -85,8 +83,8 @@ function getInterfaceName(name: string, path: string): string {
8583
name = name.replace(/([a-z0-9])([A-Z])/, (_, a, b) => `${a} ${b}`); // camel case conversion
8684
name = name.toLowerCase();
8785
if (name === "curve auto") name = "curve";
88-
if (name === "plot facet") name = "plot";
89-
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";
9088
else if (path.startsWith("marks/")) name += " mark";
9189
else if (path.startsWith("transforms/")) name += " transform";
9290
return name;
@@ -105,10 +103,15 @@ export default {
105103
if (Node.isInterfaceDeclaration(declaration)) {
106104
if (isInternalInterface(name)) continue;
107105
for (const property of declaration.getProperties()) {
108-
const path = index.getRelativePathTo(declaration.getSourceFile());
109-
const href = getHref(name, path);
110106
if (property.getJsDocs().some((d) => d.getTags().some((d) => Node.isJSDocDeprecatedTag(d)))) continue;
111-
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+
}
112115
}
113116
} else if (Node.isFunctionDeclaration(declaration)) {
114117
const comment = getDescription(declaration);
@@ -141,7 +144,9 @@ export default {
141144
throw new Error(`anchor not found: ${href}#${name}`);
142145
}
143146
}
144-
for (const {context: {href}} of allOptions) {
147+
for (const {
148+
context: {href}
149+
} of allOptions) {
145150
if (!anchors.has(`/${href}.md`)) {
146151
throw new Error(`file not found: ${href}`);
147152
}

docs/features/facets.md

+1-1
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

docs/features/marks.md

+30-11
Original file line numberDiff line numberDiff line change
@@ -531,17 +531,6 @@ Plot.dot(numbers, {x: {transform: (data) => data}})
531531

532532
The **title**, **href**, and **ariaLabel** options can *only* be specified as channels. When these options are specified as a string, the string refers to the name of a column in the mark’s associated data. If you’d like every instance of a particular mark to have the same value, specify the option as a function that returns the desired value, *e.g.* `() => "Hello, world!"`.
533533

534-
The rectangular marks ([bar](../marks/bar.md), [cell](../marks/cell.md), [frame](../marks/frame.md), and [rect](../marks/rect.md)) support insets and rounded corner constant options:
535-
536-
* **insetTop** - inset the top edge
537-
* **insetRight** - inset the right edge
538-
* **insetBottom** - inset the bottom edge
539-
* **insetLeft** - inset the left edge
540-
* **rx** - the [*x* radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rx) for rounded corners
541-
* **ry** - the [*y* radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/ry) for rounded corners
542-
543-
Insets are specified in pixels. Corner radii are specified in either pixels or percentages (strings). Both default to zero. Insets are typically used to ensure a one-pixel gap between adjacent bars; note that the [bin transform](../transforms/bin.md) provides default insets, and that the [band scale padding](./scales.md#position-scale-options) defaults to 0.1, which also provides separation.
544-
545534
For marks that support the **frameAnchor** option, it may be specified as one of the four sides (*top*, *right*, *bottom*, *left*), one of the four corners (*top-left*, *top-right*, *bottom-right*, *bottom-left*), or the *middle* of the frame.
546535

547536
All marks support the following [transform](./transforms.md) options:
@@ -554,6 +543,36 @@ All marks support the following [transform](./transforms.md) options:
554543

555544
The **sort** option, when not specified as a channel value (such as a field name or an accessor function), can also be used to [impute ordinal scale domains](./scales.md#sort-mark-option).
556545

546+
### Insets
547+
548+
Rect-like marks support insets: a positive inset moves the respective side in (towards the opposing side), whereas a negative inset moves the respective side out (away from the opposing side). Insets are specified in pixels using the following options:
549+
550+
* **inset** - shorthand for all four insets
551+
* **insetTop** - inset the top edge
552+
* **insetRight** - inset the right edge
553+
* **insetBottom** - inset the bottom edge
554+
* **insetLeft** - inset the left edge
555+
556+
Insets default to zero. Insets are commonly used to create a one-pixel gap between adjacent bars in histograms; the [bin transform](../transforms/bin.md) provides default insets. (Note that the [band scale padding](./scales.md#position-scale-options) defaults to 0.1 as an alternative to insets.)
557+
558+
### Rounded corners
559+
560+
Rect-like marks support rounded corners. Each corner (or side) is individually addressable <VersionBadge pr="2099" /> using the following options:
561+
562+
* **r** - the radius for all four corners
563+
* **rx1** - the radius for the **x1**-**y1** and **x1**-**y2** corners
564+
* **rx2** - the radius for the **x2**-**y1** and **x2**-**y2** corners
565+
* **ry1** - the radius for the **x1**-**y1** and **x2**-**y1** corners
566+
* **ry2** - the radius for the **x1**-**y2** and **x2**-**y2** corners
567+
* **rx1y1** - the radius for the **x1**-**y1** corner
568+
* **rx1y2** - the radius for the **x1**-**y2** corner
569+
* **rx2y1** - the radius for the **x2**-**y1** corner
570+
* **rx2y2** - the radius for the **x2**-**y2** corner
571+
* **rx** - the [*x*-radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rx) for elliptical corners
572+
* **ry** - the [*y*-radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/ry) for elliptical corners
573+
574+
Corner radii are specified in either pixels or, for **rx** and **ry**, as percentages (strings) or the keyword *auto*. If the corner radii are too big, they are reduced proportionally.
575+
557576
## marks(...*marks*) <VersionBadge version="0.2.0" /> {#marks}
558577

559578
```js

docs/features/plots.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ The default **width** is 640. On Observable, the width can be set to the [standa
218218
Plot does not adjust margins automatically to make room for long tick labels. If your *y* axis labels are too long, you can increase the **marginLeft** to make more room. Also consider using a different **tickFormat** for short labels (*e.g.*, `s` for SI prefix notation), or a scale **transform** (say to convert units to millions or billions).
219219
:::
220220

221-
The **aspectRatio** option<a id="aspectRatio" class="header-anchor" href="#aspectRatio" aria-label="Permalink to &quot;aspectRatio&quot;"></a> <VersionBadge version="0.6.4" />, if not null, computes a default **height** such that a variation of one unit in the *x* dimension is represented by the corresponding number of pixels as a variation in the *y* dimension of one unit.
221+
The **aspectRatio** option<a id="aspectRatio" href="#aspectRatio" aria-label="Permalink to &quot;aspectRatio&quot;"></a> <VersionBadge version="0.6.4" />, if not null, computes a default **height** such that a variation of one unit in the *x* dimension is represented by the corresponding number of pixels as a variation in the *y* dimension of one unit.
222222

223223
<p>
224224
<label class="label-input">

docs/features/scales.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ Plot.plot({
601601
[Mark transforms](./transforms.md) typically consume values *before* they are passed through scales (_e.g._, when binning). In this case the mark transforms will see the values prior to the scale transform as input, and the scale transform will apply to the *output* of the mark transform.
602602
:::
603603

604-
The **interval** scale option<a id="interval" class="header-anchor" href="#interval" aria-label="Permalink to &quot;interval&quot;"></a> <VersionBadge version="0.5.1" /> sets an ordinal scale’s **domain** to the start of every interval within the extent of the data. In addition, it implicitly sets the **transform** of the scale to *interval*.floor, rounding values down to the start of each interval. For example, below we generate a time-series bar chart; when an **interval** is specified, missing days are visible.
604+
The **interval** scale option<a id="interval" href="#interval" aria-label="Permalink to &quot;interval&quot;"></a> <VersionBadge version="0.5.1" /> sets an ordinal scale’s **domain** to the start of every interval within the extent of the data. In addition, it implicitly sets the **transform** of the scale to *interval*.floor, rounding values down to the start of each interval. For example, below we generate a time-series bar chart; when an **interval** is specified, missing days are visible.
605605

606606
<p>
607607
<label class="label-input">

docs/marks/bar.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ Plot.plot({
213213

214214
## Bar options
215215

216-
For required channels, see [barX](#barX) and [barY](#barY). The bar mark supports the [standard mark options](../features/marks.md), including insets and rounded corners. The **stroke** defaults to *none*. The **fill** defaults to *currentColor* if the stroke is *none*, and to *none* otherwise.
216+
For required channels, see [barX](#barX) and [barY](#barY). The bar mark supports the [standard mark options](../features/marks.md), including [insets](../features/marks.md#insets) and [rounded corners](../features/marks.md#rounded-corners). The **stroke** defaults to *none*. The **fill** defaults to *currentColor* if the stroke is *none*, and to *none* otherwise.
217217

218218
## barX(*data*, *options*) {#barX}
219219

docs/marks/box.md

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ The given *options* are passed through to these underlying marks, with the excep
121121
* **stroke** - the stroke color of the rule, tick, and dot; defaults to *currentColor*
122122
* **strokeOpacity** - the stroke opacity of the rule, tick, and dot; defaults to 1
123123
* **strokeWidth** - the stroke width of the tick; defaults to 1
124+
* **r** - the radius of the dot; defaults to 3
124125

125126
## boxX(*data*, *options*) {#boxX}
126127

docs/marks/cell.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ When an ordinal scale domain has high cardinality, the **ticks** scale option ca
149149

150150
## Cell options
151151

152-
In addition to the [standard mark options](../features/marks.md#mark-options), including insets and rounded corners, the following optional channels are supported:
152+
In addition to the [standard mark options](../features/marks.md#mark-options), including [insets](../features/marks.md#insets) and [rounded corners](../features/marks.md#rounded-corners), the following optional channels are supported:
153153

154154
* **x** - the horizontal position; bound to the *x* scale, which must be *band*
155155
* **y** - the vertical position; bound to the *y* scale, which must be *band*

docs/marks/frame.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Plot.plot({
111111

112112
## Frame options
113113

114-
The frame mark supports the [standard mark options](../features/marks.md#mark-options), and the **rx** and **ry** options to set the [*x* radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/rx) and [*y* radius](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/ry) for rounded corners. It does not accept any data. The default **stroke** is *currentColor*, and the default **fill** is *none*.
114+
The frame mark supports the [standard mark options](../features/marks.md#mark-options), including [insets](../features/marks.md#insets) and [rounded corners](../features/marks.md#rounded-corners). It does not accept any data. The default **stroke** is *currentColor*, and the default **fill** is *none*.
115115

116116
If the **anchor** option is specified as one of *left*, *right*, *top*, or *bottom*, that side is rendered as a single line (and the **fill**, **fillOpacity**, **rx**, and **ry** options are ignored).
117117

0 commit comments

Comments
 (0)