Skip to content

Commit

Permalink
clip supports band scales (#950)
Browse files Browse the repository at this point in the history
* clip supports band scales

closes #949

Co-authored-by: Mike Bostock <[email protected]>
  • Loading branch information
Fil and mbostock authored Jun 23, 2022
1 parent 6a442e3 commit bc6a831
Show file tree
Hide file tree
Showing 20 changed files with 160 additions and 100 deletions.
9 changes: 4 additions & 5 deletions src/marks/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ export class Area extends Mark {
filter(index) {
return index;
}
render(I, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1} = channels;
const {dx, dy} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, dx, dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales, 0, 0)
.call(g => g.selectAll()
.data(groupIndex(I, [X1, Y1, X2, Y2], this, channels))
.data(groupIndex(index, [X1, Y1, X2, Y2], this, channels))
.enter()
.append("path")
.call(applyDirectStyles, this)
Expand Down
10 changes: 5 additions & 5 deletions src/marks/arrow.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {create} from "d3";
import {radians} from "../math.js";
import {Mark} from "../plot.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, offset} from "../style.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform} from "../style.js";
import {maybeSameValue} from "./link.js";
import {constant} from "../options.js";

Expand Down Expand Up @@ -45,9 +45,9 @@ export class Arrow extends Mark {
this.insetStart = +insetStart;
this.insetEnd = +insetEnd;
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1, SW} = channels;
const {dx, dy, strokeWidth, bend, headAngle, headLength, insetStart, insetEnd} = this;
const {strokeWidth, bend, headAngle, headLength, insetStart, insetEnd} = this;
const sw = SW ? i => SW[i] : constant(strokeWidth === undefined ? 1 : strokeWidth);

// When bending, the offset between the straight line between the two points
Expand All @@ -66,8 +66,8 @@ export class Arrow extends Mark {
const wingScale = headLength / 1.5;

return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down
14 changes: 7 additions & 7 deletions src/marks/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export class AbstractBar extends Mark {
this.ry = impliedString(ry, "auto");
}
render(index, scales, channels, dimensions) {
const {dx, dy, rx, ry} = this;
const {rx, ry} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(this._transform, scales, dx, dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(this._transform, this, scales)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down Expand Up @@ -75,8 +75,8 @@ export class BarX extends AbstractBar {
defaults
);
}
_transform(selection, {x}, dx, dy) {
selection.call(applyTransform, x, null, dx, dy);
_transform(selection, mark, {x}) {
selection.call(applyTransform, mark, {x}, 0, 0);
}
_x({x}, {x1: X1, x2: X2}, {marginLeft}) {
const {insetLeft} = this;
Expand All @@ -102,8 +102,8 @@ export class BarY extends AbstractBar {
defaults
);
}
_transform(selection, {y}, dx, dy) {
selection.call(applyTransform, null, y, dx, dy);
_transform(selection, mark, {y}) {
selection.call(applyTransform, mark, {y}, 0, 0);
}
_y({y}, {y1: Y1, y2: Y2}, {marginTop}) {
const {insetTop} = this;
Expand Down
24 changes: 11 additions & 13 deletions src/marks/delaunay.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {create, group, path, select, Delaunay} from "d3";
import {Curve} from "../curve.js";
import {constant, maybeTuple, maybeZ} from "../options.js";
import {Mark} from "../plot.js";
import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform, offset} from "../style.js";
import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform} from "../style.js";
import {markers, applyMarkers} from "./marker.js";

const delaunayLinkDefaults = {
Expand Down Expand Up @@ -57,9 +57,9 @@ class DelaunayLink extends Mark {
this.curve = Curve(curve, tension);
markers(this, options);
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, z: Z} = channels;
const {dx, dy, curve} = this;
const {curve} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
const xi = X ? i => X[i] : constant(cx);
const yi = Y ? i => Y[i] : constant(cy);
Expand Down Expand Up @@ -114,8 +114,8 @@ class DelaunayLink extends Mark {
}

return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(Z
? g => g.selectAll().data(group(index, i => Z[i]).values()).enter().append("g").each(links)
: g => g.datum(index).each(links))
Expand All @@ -137,9 +137,8 @@ class AbstractDelaunayMark extends Mark {
defaults
);
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, z: Z} = channels;
const {dx, dy} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
const xi = X ? i => X[i] : constant(cx);
const yi = Y ? i => Y[i] : constant(cy);
Expand All @@ -155,8 +154,8 @@ class AbstractDelaunayMark extends Mark {
}

return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(Z
? g => g.selectAll().data(group(index, i => Z[i]).values()).enter().append("g").each(mesh)
: g => g.datum(index).each(mesh))
Expand Down Expand Up @@ -197,9 +196,8 @@ class Voronoi extends Mark {
voronoiDefaults
);
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, z: Z} = channels;
const {dx, dy} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
const xi = X ? i => X[i] : constant(cx);
const yi = Y ? i => Y[i] : constant(cy);
Expand All @@ -218,8 +216,8 @@ class Voronoi extends Mark {
}

return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(Z
? g => g.selectAll().data(group(index, i => Z[i]).values()).enter().append("g").each(cells)
: g => g.datum(index).each(cells))
Expand Down
9 changes: 4 additions & 5 deletions src/marks/dot.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {create, path, symbolCircle} from "d3";
import {positive} from "../defined.js";
import {identity, maybeFrameAnchor, maybeNumberChannel, maybeTuple} from "../options.js";
import {Mark} from "../plot.js";
import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform, offset} from "../style.js";
import {applyChannelStyles, applyDirectStyles, applyFrameAnchor, applyIndirectStyles, applyTransform} from "../style.js";
import {maybeSymbolChannel} from "../symbols.js";
import {sort} from "../transforms/basic.js";
import {maybeIntervalMidX, maybeIntervalMidY} from "../transforms/interval.js";
Expand Down Expand Up @@ -51,14 +51,13 @@ export class Dot extends Mark {
};
}
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, r: R, rotate: A, symbol: S} = channels;
const {dx, dy} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
const circle = this.symbol === symbolCircle;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down
10 changes: 5 additions & 5 deletions src/marks/frame.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {create} from "d3";
import {Mark} from "../plot.js";
import {number} from "../options.js";
import {applyDirectStyles, applyIndirectStyles, applyTransform, offset} from "../style.js";
import {applyDirectStyles, applyIndirectStyles, applyTransform} from "../style.js";

const defaults = {
ariaLabel: "frame",
Expand All @@ -24,13 +24,13 @@ export class Frame extends Mark {
this.insetBottom = number(insetBottom);
this.insetLeft = number(insetLeft);
}
render(I, scales, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {marginTop, marginRight, marginBottom, marginLeft, width, height} = dimensions;
const {insetTop, insetRight, insetBottom, insetLeft, dx, dy} = this;
const {insetTop, insetRight, insetBottom, insetLeft} = this;
return create("svg:rect")
.call(applyIndirectStyles, this, dimensions)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyDirectStyles, this)
.call(applyTransform, null, null, offset + dx, offset + dy)
.call(applyTransform, this, {})
.attr("x", marginLeft + insetLeft)
.attr("y", marginTop + insetTop)
.attr("width", width - marginLeft - marginRight - insetLeft - insetRight)
Expand Down
6 changes: 3 additions & 3 deletions src/marks/hexgrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Hexgrid extends Mark {
this.binWidth = number(binWidth);
}
render(index, scales, channels, dimensions) {
const {dx, dy, binWidth} = this;
const {binWidth} = this;
const {marginTop, marginRight, marginBottom, marginLeft, width, height} = dimensions;
const x0 = marginLeft - ox, x1 = width - marginRight - ox, y0 = marginTop - oy, y1 = height - marginBottom - oy;
const rx = binWidth / 2, ry = rx * sqrt4_3, hy = ry / 2, wx = rx * 2, wy = ry * 1.5;
Expand All @@ -36,10 +36,10 @@ export class Hexgrid extends Mark {
}
}
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyIndirectStyles, this, scales, dimensions)
.call(g => g.append("path")
.call(applyDirectStyles, this)
.call(applyTransform, null, null, offset + dx + ox, offset + dy + oy)
.call(applyTransform, this, {}, offset + ox, offset + oy)
.attr("d", m.join("")))
.node();
}
Expand Down
9 changes: 4 additions & 5 deletions src/marks/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {create} from "d3";
import {positive} from "../defined.js";
import {maybeFrameAnchor, maybeNumberChannel, maybeTuple, string} from "../options.js";
import {Mark} from "../plot.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, applyAttr, offset, impliedString, applyFrameAnchor} from "../style.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, applyAttr, impliedString, applyFrameAnchor} from "../style.js";

const defaults = {
ariaLabel: "image",
Expand Down Expand Up @@ -59,13 +59,12 @@ export class Image extends Mark {
this.crossOrigin = string(crossOrigin);
this.frameAnchor = maybeFrameAnchor(frameAnchor);
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, width: W, height: H, src: S} = channels;
const {dx, dy} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down
11 changes: 5 additions & 6 deletions src/marks/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {create, line as shapeLine} from "d3";
import {Curve} from "../curve.js";
import {Mark} from "../plot.js";
import {indexOf, identity, maybeTuple, maybeZ} from "../options.js";
import {applyDirectStyles, applyIndirectStyles, applyTransform, applyGroupedChannelStyles, offset, groupIndex} from "../style.js";
import {applyDirectStyles, applyIndirectStyles, applyTransform, applyGroupedChannelStyles, groupIndex} from "../style.js";
import {maybeDenseIntervalX, maybeDenseIntervalY} from "../transforms/bin.js";
import {applyGroupedMarkers, markers} from "./marker.js";

Expand Down Expand Up @@ -36,14 +36,13 @@ export class Line extends Mark {
filter(index) {
return index;
}
render(I, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y} = channels;
const {dx, dy} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(groupIndex(I, [X, Y], this, channels))
.data(groupIndex(index, [X, Y], this, channels))
.enter()
.append("path")
.call(applyDirectStyles, this)
Expand Down
12 changes: 6 additions & 6 deletions src/marks/linearRegression.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {create, extent, range, sum, area as shapeArea, namespaces} from "d3";
import {identity, indexOf, isNone, isNoneish, maybeZ} from "../options.js";
import {Mark} from "../plot.js";
import {qt} from "../stats.js";
import {applyDirectStyles, applyGroupedChannelStyles, applyIndirectStyles, applyTransform, groupZ, offset} from "../style.js";
import {applyDirectStyles, applyGroupedChannelStyles, applyIndirectStyles, applyTransform, groupZ} from "../style.js";
import {maybeDenseIntervalX, maybeDenseIntervalY} from "../transforms/bin.js";

const defaults = {
Expand Down Expand Up @@ -35,14 +35,14 @@ class LinearRegression extends Mark {
if (!(0 <= this.ci && this.ci < 1)) throw new Error(`invalid ci; not in [0, 1): ${ci}`);
if (!(this.precision > 0)) throw new Error(`invalid precision: ${precision}`);
}
render(I, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x: X, y: Y, z: Z} = channels;
const {dx, dy, ci} = this;
const {ci} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(Z ? groupZ(I, Z, this.z) : [I])
.data(Z ? groupZ(index, Z, this.z) : [index])
.enter()
.call(enter => enter.append("path")
.attr("fill", "none")
Expand Down
10 changes: 5 additions & 5 deletions src/marks/link.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {create, path} from "d3";
import {Curve} from "../curve.js";
import {Mark} from "../plot.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform, offset} from "../style.js";
import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransform} from "../style.js";
import {markers, applyMarkers} from "./marker.js";

const defaults = {
Expand All @@ -28,12 +28,12 @@ export class Link extends Mark {
this.curve = Curve(curve, tension);
markers(this, options);
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1} = channels;
const {dx, dy, curve} = this;
const {curve} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, x, y, offset + dx, offset + dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, scales)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down
9 changes: 5 additions & 4 deletions src/marks/rect.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ export class Rect extends Mark {
this.rx = impliedString(rx, "auto"); // number or percentage
this.ry = impliedString(ry, "auto");
}
render(index, {x, y}, channels, dimensions) {
render(index, scales, channels, dimensions) {
const {x, y} = scales;
const {x1: X1, y1: Y1, x2: X2, y2: Y2} = channels;
const {marginTop, marginRight, marginBottom, marginLeft, width, height} = dimensions;
const {insetTop, insetRight, insetBottom, insetLeft, dx, dy, rx, ry} = this;
const {insetTop, insetRight, insetBottom, insetLeft, rx, ry} = this;
return create("svg:g")
.call(applyIndirectStyles, this, dimensions)
.call(applyTransform, X1 && X2 ? x : null, Y1 && Y2 ? y : null, dx, dy)
.call(applyIndirectStyles, this, scales, dimensions)
.call(applyTransform, this, {x: X1 && X2 ? x : null, y: Y1 && Y2 ? y : null}, 0, 0)
.call(g => g.selectAll()
.data(index)
.enter()
Expand Down
Loading

0 comments on commit bc6a831

Please sign in to comment.