diff --git a/src/axis.js b/src/axis.js index dd8a9f1f416..7fff6cedeb4 100644 --- a/src/axis.js +++ b/src/axis.js @@ -3,9 +3,8 @@ import {boolean, take, number, string, keyword, maybeKeyword, constant, isTempor import {formatIsoDate} from "./format.js"; import {radians} from "./math.js"; import {applyAttr, impliedString} from "./style.js"; -import {Decoration} from "./decoration.js"; -export class AxisX extends Decoration { +export class AxisX { constructor({ name = "x", axis, @@ -23,7 +22,6 @@ export class AxisX extends Decoration { ariaLabel, ariaDescription } = {}) { - super(); this.name = name; this.axis = keyword(axis, "axis", ["top", "bottom"]); this.ticks = ticks; @@ -99,7 +97,7 @@ export class AxisX extends Decoration { } } -export class AxisY extends Decoration { +export class AxisY { constructor({ name = "y", axis, @@ -117,7 +115,6 @@ export class AxisY extends Decoration { ariaLabel, ariaDescription } = {}) { - super(); this.name = name; this.axis = keyword(axis, "axis", ["left", "right"]); this.ticks = ticks; diff --git a/src/decoration.js b/src/decoration.js deleted file mode 100644 index 0a5dd9e72e9..00000000000 --- a/src/decoration.js +++ /dev/null @@ -1,13 +0,0 @@ -import {defined} from "./defined.js"; - -export class Decoration { - filter(index, channels, values) { - for (const [name, {filter = defined}] of channels) { - if (name !== undefined && filter !== null) { - const value = values[name]; - index = index.filter(i => filter(value[i])); - } - } - return index; - } -} diff --git a/src/marks/area.js b/src/marks/area.js index 495003bdd23..531995626a5 100644 --- a/src/marks/area.js +++ b/src/marks/area.js @@ -7,6 +7,7 @@ import {maybeIdentityX, maybeIdentityY} from "../transforms/identity.js"; import {maybeStackX, maybeStackY} from "../transforms/stack.js"; const defaults = { + filter: null, ariaLabel: "area", strokeWidth: 1, strokeMiterlimit: 1 @@ -29,9 +30,6 @@ export class Area extends Mark { ); this.curve = Curve(curve, tension); } - filter(I) { - return I; - } render(I, {x, y}, channels, dimensions) { const {x1: X1, y1: Y1, x2: X2 = X1, y2: Y2 = Y1} = channels; const {dx, dy} = this; diff --git a/src/marks/line.js b/src/marks/line.js index c34cd0f2e81..b70fc7bfc2e 100644 --- a/src/marks/line.js +++ b/src/marks/line.js @@ -6,6 +6,7 @@ import {applyDirectStyles, applyIndirectStyles, applyTransform, applyGroupedChan import {applyGroupedMarkers, markers} from "./marker.js"; const defaults = { + filter: null, ariaLabel: "line", fill: "none", stroke: "currentColor", @@ -29,9 +30,6 @@ export class Line extends Mark { this.curve = Curve(curve, tension); markers(this, options); } - filter(I) { - return I; - } render(I, {x, y}, channels, dimensions) { const {x: X, y: Y} = channels; const {dx, dy} = this; diff --git a/src/plot.js b/src/plot.js index be52405b8ab..6fedfef07e9 100644 --- a/src/plot.js +++ b/src/plot.js @@ -1,7 +1,7 @@ import {create, cross, difference, groups, InternMap, select} from "d3"; import {Axes, autoAxisTicks, autoScaleLabels} from "./axes.js"; import {Channel, channelSort} from "./channel.js"; -import {Decoration} from "./decoration.js"; +import {defined} from "./defined.js"; import {Dimensions} from "./dimensions.js"; import {Legends, exposeLegends} from "./legends.js"; import {arrayify, isOptions, keyword, range, first, second, where} from "./options.js"; @@ -99,7 +99,8 @@ export function plot(options = {}) { for (const mark of marks) { const channels = markChannels.get(mark) ?? []; const values = applyScales(channels, scales); - const index = mark.filter(markIndex.get(mark), channels, values); + let index = markIndex.get(mark); + if (mark.filter != null) index = mark.filter(index, channels, values); const node = mark.render(index, scales, values, dimensions, axes); if (node != null) svg.appendChild(node); } @@ -136,15 +137,25 @@ export function plot(options = {}) { return figure; } -export class Mark extends Decoration { +function defaultFilter(index, channels, values) { + for (const [name, {filter = defined}] of channels) { + if (name !== undefined && filter !== null) { + const value = values[name]; + index = index.filter(i => filter(value[i])); + } + } + return index; +} + +export class Mark { constructor(data, channels = [], options = {}, defaults) { - super(); const {facet = "auto", sort, dx, dy, clip} = options; const names = new Set(); this.data = data; this.sort = isOptions(sort) ? sort : null; this.facet = facet == null || facet === false ? null : keyword(facet === true ? "include" : facet, "facet", ["auto", "include", "exclude"]); const {transform} = basic(options); + this.filter = defaults?.filter === undefined ? defaultFilter : defaults.filter; this.transform = transform; if (defaults !== undefined) channels = styles(this, options, channels, defaults); this.channels = channels.filter(channel => { @@ -321,7 +332,8 @@ class Facet extends Mark { for (let i = 0; i < marks.length; ++i) { const mark = marks[i]; const values = marksValues[i]; - const index = mark.filter(marksFacetIndex[i], marksChannels[i], values); + let index = marksFacetIndex[i]; + if (mark.filter != null) mark.filter(index, marksChannels[i], values); const node = mark.render(index, scales, values, subdimensions); if (node != null) this.appendChild(node); }