Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/marks/area.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ Plot.plot((() => {
```
:::

The **line** option draws a line connecting the points with coordinates **x2** and **y2** (the “top of the area”).

Example TK.

See also the [ridgeline chart](https://observablehq.com/@observablehq/plot-ridgeline) example.

Interpolation is controlled by the [**curve** option](../features/curves.md). The default curve is *linear*, which draws straight line segments between pairs of adjacent points. A *step* curve is nice for emphasizing when the value changes, while *basis* and *catmull–rom* are nice for smoothing.
Expand Down Expand Up @@ -292,6 +296,8 @@ Points along the baseline and topline are connected in input order. Likewise, if

The area mark supports [curve options](../features/curves.md) to control interpolation between points. If any of the **x1**, **y1**, **x2**, or **y2** values are invalid (undefined, null, or NaN), the baseline and topline will be interrupted, resulting in a break that divides the area shape into multiple segments. (See [d3-shape’s *area*.defined](https://d3js.org/d3-shape/area#area_defined) for more.) If an area segment consists of only a single point, it may appear invisible unless rendered with rounded or square line caps. In addition, some curves such as *cardinal-open* only render a visible segment if it contains multiple points.

The **line** option <VersionBadge pr="TK" /> (boolean, defaults to false) indicates whether the mark should draw a line connecting the points with coordinates **x2** and **y2** (the “top of the area”). In that case, the **stroke** attribute defaults to *currentColor* and is applied to the line only, as well as the stroke opacity. The line uses the same **curve** as the area.

## areaY(*data*, *options*) {#areaY}

```js
Expand Down
6 changes: 6 additions & 0 deletions src/marks/area.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export interface AreaOptions extends MarkOptions, StackOptions, CurveOptions {
* **stroke** if a channel.
*/
z?: ChannelValue;

/**
* Whether a line should be drawn connecting the points with coordinates *x2*,
* *y2*; the **stroke** then applies to that line and defaults to *currentColor*.
*/
line?: boolean;
}

/** Options for the areaX mark. */
Expand Down
35 changes: 27 additions & 8 deletions src/marks/area.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {area as shapeArea} from "d3";
import {area as shapeArea, line as shapeLine} from "d3";
import {create} from "../context.js";
import {maybeCurve} from "../curve.js";
import {Mark} from "../mark.js";
Expand All @@ -24,7 +24,7 @@ const defaults = {

export class Area extends Mark {
constructor(data, options = {}) {
const {x1, y1, x2, y2, z, curve, tension} = options;
const {x1, y1, x2, y2, z, curve, tension, line} = options;
super(
data,
{
Expand All @@ -35,10 +35,11 @@ export class Area extends Mark {
z: {value: maybeZ(options), optional: true}
},
options,
defaults
line ? {...defaults, stroke: "currentColor"} : defaults
);
this.z = z;
this.curve = maybeCurve(curve, tension);
this.line = !!line;
}
filter(index) {
return index;
Expand All @@ -48,11 +49,14 @@ export class Area extends Mark {
return create("svg:g", context)
.call(applyIndirectStyles, this, dimensions, context)
.call(applyTransform, this, scales, 0, 0)
.call((g) =>
g
.call((g) => {
g = g
.selectAll()
.data(groupIndex(index, [X1, Y1, X2, Y2], this, channels))
.enter()
.enter();

if (this.line) g = g.append("g");
const area = g
.append("path")
.call(applyDirectStyles, this)
.call(applyGroupedChannelStyles, this, channels)
Expand All @@ -65,8 +69,23 @@ export class Area extends Mark {
.y0((i) => Y1[i])
.x1((i) => X2[i])
.y1((i) => Y2[i])
)
)
);
if (this.line) {
area.attr("stroke", "none");
g.append("path")
.call(applyDirectStyles, this)
.call(applyGroupedChannelStyles, this, channels)
.attr(
"d",
shapeLine()
.curve(this.curve)
.defined((i) => i >= 0)
.x((i) => X2[i])
.y((i) => Y2[i])
)
.attr("fill", "none");
}
})
.node();
}
}
Expand Down
80 changes: 80 additions & 0 deletions test/output/aaplCloseLine.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading