Skip to content

Commit

Permalink
Plot.link creates svg:path elements instead of svg:line (observablehq…
Browse files Browse the repository at this point in the history
…#350)

* Plot.link creates svg:path elements instead of svg:line

Allows {curve: "bump-x"}

* copy fill/stroke option handling from Plot.line

a consequence visually is that the default strokeWidth is 1.5 (can be changed back to 1, but 1.5 is consistent with Plot.line)

* use path directly

* Update src/marks/link.js

Co-authored-by: Mike Bostock <[email protected]>

* fix tests

Co-authored-by: Mike Bostock <[email protected]>
  • Loading branch information
Fil and mbostock authored May 1, 2021
1 parent 0a4ac0d commit 4c9646b
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 204 deletions.
29 changes: 23 additions & 6 deletions src/marks/link.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {create} from "d3";
import {create, path} from "d3";
import {filter} from "../defined.js";
import {Mark, maybeColor, maybeNumber, title} from "../mark.js";
import {Curve} from "../curve.js";
import {Style, applyDirectStyles, applyIndirectStyles, applyTransform, applyAttr} from "../style.js";

export class Link extends Mark {
Expand All @@ -12,11 +13,16 @@ export class Link extends Mark {
x2,
y2,
title,
fill,
fillOpacity,
stroke,
strokeOpacity,
curve,
...options
} = {}
) {
const [vfill, cfill] = maybeColor(fill, "none");
const [vfillOpacity, cfillOpacity] = maybeNumber(fillOpacity);
const [vstroke, cstroke] = maybeColor(stroke, "currentColor");
const [vstrokeOpacity, cstrokeOpacity] = maybeNumber(strokeOpacity);
super(
Expand All @@ -27,13 +33,19 @@ export class Link extends Mark {
{name: "x2", value: x2, scale: "x"},
{name: "y2", value: y2, scale: "y"},
{name: "title", value: title, optional: true},
{name: "fill", value: vfill, scale: "color", optional: true},
{name: "fillOpacity", value: vfillOpacity, scale: "opacity", optional: true},
{name: "stroke", value: vstroke, scale: "color", optional: true},
{name: "strokeOpacity", value: vstrokeOpacity, scale: "opacity", optional: true}
],
options
);
this.curve = Curve(curve);
Style(this, {
fill: cfill,
fillOpacity: cfillOpacity,
stroke: cstroke,
strokeMiterlimit: cstroke === "none" ? undefined : 1,
strokeOpacity: cstrokeOpacity,
...options
});
Expand All @@ -49,12 +61,17 @@ export class Link extends Mark {
.call(applyTransform, x, y, 0.5, 0.5)
.call(g => g.selectAll()
.data(index)
.join("line")
.join("path")
.call(applyDirectStyles, this)
.attr("x1", i => X1[i])
.attr("y1", i => Y1[i])
.attr("x2", i => X2[i])
.attr("y2", i => Y2[i])
.attr("d", i => {
const p = path();
const c = this.curve(p);
c.lineStart();
c.point(X1[i], Y1[i]);
c.point(X2[i], Y2[i]);
c.lineEnd();
return p + "";
})
.call(applyAttr, "stroke", S && (i => S[i]))
.call(applyAttr, "stroke-opacity", SO && (i => SO[i]))
.call(title(L)))
Expand Down
4 changes: 2 additions & 2 deletions test/marks/link-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ tape("link(data, options) has the expected defaults", test => {
test.deepEqual(link.channels.map(c => c.name), ["x1", "y1", "x2", "y2"]);
test.deepEqual(link.channels.map(c => c.value.label), ["0", "1", "2", "3"]);
test.deepEqual(link.channels.map(c => c.scale), ["x", "y", "x", "y"]);
test.strictEqual(link.fill, undefined);
test.strictEqual(link.fill, "none");
test.strictEqual(link.fillOpacity, undefined);
test.strictEqual(link.stroke, "currentColor");
test.strictEqual(link.strokeWidth, undefined);
test.strictEqual(link.strokeOpacity, undefined);
test.strictEqual(link.strokeLinejoin, undefined);
test.strictEqual(link.strokeLinecap, undefined);
test.strictEqual(link.strokeMiterlimit, undefined);
test.strictEqual(link.strokeMiterlimit, 1);
test.strictEqual(link.strokeDasharray, undefined);
test.strictEqual(link.mixBlendMode, undefined);
});
Expand Down
Loading

0 comments on commit 4c9646b

Please sign in to comment.