Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

top-level clip option #1792

Merged
merged 1 commit into from
Aug 6, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions docs/features/plots.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ Unitless numbers ([quirky lengths](https://www.w3.org/TR/css-values-4/#deprecate

The generated SVG element has a class name which applies a default stylesheet. Use the top-level **className** option to specify that class name.

The **clip** option <VersionBadge pr="1792" /> determines the default clipping behavior if the [mark **clip** option](./marks.md#mark-options) is not specified; set it to true to enable clipping. This option does not affect [axis](../marks/axis.md), [grid](../marks/grid.md), and [frame](../marks/frame.md) marks, whose **clip** option defaults to false.

The **document** option specifies the [document](https://developer.mozilla.org/en-US/docs/Web/API/Document) used to create plot elements. It defaults to window.document, but can be changed to another document, say when using a virtual DOM implementation for server-side rendering in Node.

## plot(*options*) {#plot}
Expand Down
4 changes: 4 additions & 0 deletions src/context.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {GeoStreamWrapper} from "d3";
import type {MarkOptions} from "./mark.js";

/** Additional rendering context provided to marks and initializers. */
export interface Context {
Expand All @@ -16,4 +17,7 @@ export interface Context {

/** The current projection, if any. */
projection?: GeoStreamWrapper;

/** The default clip for all marks. */
clip?: MarkOptions["clip"];
}
5 changes: 3 additions & 2 deletions src/context.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {creator, select} from "d3";
import {maybeClip} from "./style.js";

export function createContext(options = {}) {
const {document = typeof window !== "undefined" ? window.document : undefined} = options;
return {document};
const {document = typeof window !== "undefined" ? window.document : undefined, clip} = options;
return {document, clip: maybeClip(clip)};
}

export function create(name, {document}) {
Expand Down
2 changes: 1 addition & 1 deletion src/mark.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Mark {
marginRight = margin,
marginBottom = margin,
marginLeft = margin,
clip,
clip = defaults?.clip,
channels: extraChannels,
tip,
render
Expand Down
1 change: 1 addition & 0 deletions src/marks/axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ function axisMark(mark, k, ariaLabel, data, options, initialize) {
channels = {};
}
m.ariaLabel = ariaLabel;
if (m.clip === undefined) m.clip = false; // don’t clip axes by default
return m;
}

Expand Down
6 changes: 4 additions & 2 deletions src/marks/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import {applyChannelStyles, applyDirectStyles, applyIndirectStyles, applyTransfo
const defaults = {
ariaLabel: "frame",
fill: "none",
stroke: "currentColor"
stroke: "currentColor",
clip: false
};

const lineDefaults = {
ariaLabel: "frame",
fill: null,
stroke: "currentColor",
strokeLinecap: "square"
strokeLinecap: "square",
clip: false
};

export class Frame extends Mark {
Expand Down
5 changes: 4 additions & 1 deletion src/plot.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {ChannelValue} from "./channel.js";
import type {LegendOptions} from "./legends.js";
import type {Data, Markish} from "./mark.js";
import type {Data, MarkOptions, Markish} from "./mark.js";
import type {ProjectionFactory, ProjectionImplementation, ProjectionName, ProjectionOptions} from "./projection.js";
import type {Scale, ScaleDefaults, ScaleName, ScaleOptions} from "./scales.js";

Expand Down Expand Up @@ -146,6 +146,9 @@ export interface PlotOptions extends ScaleDefaults {
*/
document?: Document;

/** The default clip for all marks. */
clip?: MarkOptions["clip"];

// scale, axis, and legend definitions

/**
Expand Down
19 changes: 6 additions & 13 deletions src/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,8 @@ import {geoPath, group, namespaces} from "d3";
import {create} from "./context.js";
import {defined, nonempty} from "./defined.js";
import {formatDefault} from "./format.js";
import {
string,
number,
maybeColorChannel,
maybeNumberChannel,
maybeKeyword,
isNoneish,
isNone,
isRound,
keyof
} from "./options.js";
import {isNone, isNoneish, isRound, maybeColorChannel, maybeNumberChannel} from "./options.js";
import {keyof, keyword, number, string} from "./options.js";
import {warn} from "./warnings.js";

export const offset = (typeof window !== "undefined" ? window.devicePixelRatio > 1 : typeof it === "undefined") ? 0 : 0.5; // prettier-ignore
Expand Down Expand Up @@ -311,13 +302,15 @@ export function* groupIndex(I, position, mark, channels) {
export function maybeClip(clip) {
if (clip === true) clip = "frame";
else if (clip === false) clip = null;
return maybeKeyword(clip, "clip", ["frame", "sphere"]);
else if (clip != null) clip = keyword(clip, "clip", ["frame", "sphere"]);
return clip;
}

// Note: may mutate selection.node!
function applyClip(selection, mark, dimensions, context) {
let clipUrl;
switch (mark.clip) {
const {clip = context.clip} = mark;
switch (clip) {
case "frame": {
const {width, height, marginLeft, marginRight, marginTop, marginBottom} = dimensions;
const id = getClipId();
Expand Down
11 changes: 2 additions & 9 deletions test/plots/band-clip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,8 @@ import * as d3 from "d3";
export async function bandClip() {
return Plot.plot({
y: {type: "band"},
marks: [
Plot.frame(),
Plot.text(["A", "B", "C"], {
x: (d) => d,
y: (d) => d,
clip: true,
fontSize: 50
})
]
clip: true,
marks: [Plot.frame(), Plot.text(["A", "B", "C"], {x: (d) => d, y: (d) => d, fontSize: 50})]
});
}

Expand Down