Skip to content

Commit

Permalink
lift side effect up to index.js (#2069)
Browse files Browse the repository at this point in the history
* add index.js to sideEffects

* lift side effect up

* side effect, not side-effect

* Update src/index.js

Co-authored-by: Philippe Rivière <[email protected]>

---------

Co-authored-by: Philippe Rivière <[email protected]>
  • Loading branch information
mbostock and Fil authored Jun 3, 2024
1 parent 373d4f5 commit af2c3bb
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 11 deletions.
2 changes: 1 addition & 1 deletion docs/features/transforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ The **transform** function is passed three arguments, *data*, *facets*, and *opt

If the **transform** option is specified, it supersedes any basic transforms (*i.e.*, the **filter**, **sort** and **reverse** options are ignored). However, the **transform** option is rarely used directly; instead one of Plot’s built-in transforms are used, and these transforms automatically compose with the basic **filter**, **sort** and **reverse** transforms.

While transform functions often produce new *data* or *facets*, they may return the passed-in *data* and *facets* as-is, and often have a side-effect of constructing derived channels. For example, the count of elements in a [groupX transform](../transforms/group.md) might be returned as a new *y* channel. In this case, the transform is typically expressed as an options transform: a function that takes a mark *options* object and returns a new, transformed options object, where the returned options object implements the **transform** option. Transform functions should not mutate the input *data* or *facets*. Likewise options transforms should not mutate the input *options* object.
While transform functions often produce new *data* or *facets*, they may return the passed-in *data* and *facets* as-is, and often have a side effect of constructing derived channels. For example, the count of elements in a [groupX transform](../transforms/group.md) might be returned as a new *y* channel. In this case, the transform is typically expressed as an options transform: a function that takes a mark *options* object and returns a new, transformed options object, where the returned options object implements the **transform** option. Transform functions should not mutate the input *data* or *facets*. Likewise options transforms should not mutate the input *options* object.

When implementing a custom transform for generic usage, keep in mind that it needs to be compatible with Plot’s [faceting system](./facets.md), which partitions the original dataset into discrete subsets.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@observablehq/plot": "./src/index.js"
},
"sideEffects": [
"./src/plot.js"
"./src/index.js"
],
"devDependencies": {
"@observablehq/runtime": "^5.7.3",
Expand Down
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import {Mark} from "./mark.js";
import {plot} from "./plot.js";

// Note: this side effect avoids a circular dependency.
Mark.prototype.plot = function ({marks = [], ...options} = {}) {
return plot({...options, marks: [...marks, this]});
};

export {plot} from "./plot.js";
export {Mark, marks} from "./mark.js";
export {Area, area, areaX, areaY} from "./marks/area.js";
Expand Down
2 changes: 1 addition & 1 deletion src/mark.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class Mark {
}

export function marks(...marks) {
marks.plot = Mark.prototype.plot; // Note: depends on side-effect in plot!
marks.plot = Mark.prototype.plot;
return marks;
}

Expand Down
7 changes: 0 additions & 7 deletions src/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,13 +368,6 @@ function createFigcaption(document, caption) {
return e;
}

function plotThis({marks = [], ...options} = {}) {
return plot({...options, marks: [...marks, this]});
}

// Note: This side-effect avoids a circular dependency.
Mark.prototype.plot = plotThis;

function flatMarks(marks) {
return marks
.flat(Infinity)
Expand Down
2 changes: 1 addition & 1 deletion src/transforms/basic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {ScaleFunctions} from "../scales.js";
* the data, *facets*, and the plot’s *options*. The transform function returns
* new mark data and facets; the returned **data** defaults to the passed
* *data*, and the returned **facets** defaults to the passed *facets*. The mark
* is the *this* context. Transform functions can also trigger side-effects, say
* is the *this* context. Transform functions can also trigger side effects, say
* to populate lazily-derived columns; see also Plot.column.
*/
export type TransformFunction = (
Expand Down

0 comments on commit af2c3bb

Please sign in to comment.