Skip to content

Commit

Permalink
extends Mark
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Nov 16, 2020
1 parent 9273c0d commit b5d866b
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 59 deletions.
13 changes: 1 addition & 12 deletions src/channels.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import {group} from "d3-array";

// TODO Don’t mutate channels in-place?
export function Marks(marks = []) {
for (const mark of marks) {
mark.channels = Object.fromEntries(Array.from(
Object.entries(mark.channels).filter(([, channel]) => channel),
([name, channel]) => [name, Channel(mark.data, channel)]
));
}
return marks;
}

export function Channels(marks) {
return group(
marks.flatMap(m => Object.values(m.channels).filter(({scale}) => scale)),
({scale}) => scale
);
}

function Channel(data, {scale = null, type, value, label}) {
export function Channel(data, {scale = null, type, value, label}) {
if (typeof value === "string") label = value, value = Array.from(data, Field(value));
else if (typeof value === "function") value = Array.from(data, value);
else if (typeof value.length !== "number") value = Array.from(value);
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {plot} from "./plot.js";
export {Mark} from "./mark.js";
export {AreaX, AreaY} from "./marks/area.js";
export {AxisX, AxisY} from "./marks/axis.js";
export {BarX, BarY} from "./marks/bar.js";
Expand Down
19 changes: 11 additions & 8 deletions src/marks/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {area} from "d3-shape";
import {Curve} from "../curve.js";
import {identity, indexOf, zero} from "../channels.js";
import {defined} from "../defined.js";
import {Mark} from "../mark.js";

class Area {
class Area extends Mark {
constructor(
data,
{
Expand All @@ -17,16 +18,18 @@ class Area {
fillOpacity
} = {}
) {
this.data = data;
super(
data,
{
x1: {value: x1, scale: "x"},
y1: {value: y1, scale: "y"},
x2: x2 && {value: x2, scale: "x"},
y2: y2 && {value: y2, scale: "y"}
}
);
this.curve = Curve(curve);
this.fill = fill;
this.fillOpacity = fillOpacity;
this.channels = {
x1: {value: x1, scale: "x"},
y1: {value: y1, scale: "y"},
x2: x2 && {value: x2, scale: "x"},
y2: y2 && {value: y2, scale: "y"}
};
}
render(I, {x: {scale: x}, y: {scale: y}}) {
const {
Expand Down
12 changes: 6 additions & 6 deletions src/marks/bar.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {create} from "d3-selection";
import {identity, indexOf} from "../channels.js";
import {defined} from "../defined.js";
import {Mark} from "../mark.js";

class Bar {
class Bar extends Mark {
constructor(
channels,
data,
channels,
{
fill = "currentColor",
fillOpacity,
Expand All @@ -19,8 +20,7 @@ class Bar {
insetLeft = 0
} = {}
) {
this.data = data;
this.channels = channels;
super(data, channels);
this.fill = fill;
this.fillOpacity = fillOpacity;
this.stroke = stroke;
Expand Down Expand Up @@ -68,12 +68,12 @@ class Bar {
export class BarX extends Bar {
constructor(data, {x = identity, y = indexOf, ...options} = {}) {
super(
data,
{
x: {value: x, scale: "x"},
y: {value: y, scale: "y", type: "band"},
x0: {value: [0], scale: "x"} // ensure the x-domain includes zero
},
data,
options
);
}
Expand All @@ -98,12 +98,12 @@ export class BarX extends Bar {
export class BarY extends Bar {
constructor(data, {x = indexOf, y = identity, ...options} = {}) {
super(
data,
{
x: {value: x, scale: "x", type: "band"},
y: {value: y, scale: "y"},
y0: {value: [0], scale: "y"} // ensure the y-domain includes zero
},
data,
options
);
}
Expand Down
19 changes: 11 additions & 8 deletions src/marks/dot.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {create} from "d3-selection";
import {defined} from "../defined.js";
import {Mark} from "../mark.js";

const first = d => d[0];
const second = d => d[1];

export class DotXY {
export class DotXY extends Mark {
constructor(
data,
{
Expand All @@ -19,18 +20,20 @@ export class DotXY {
mixBlendMode
} = {}
) {
this.data = data;
super(
data,
{
x: {value: x, scale: "x"},
y: {value: y, scale: "y"},
r: {value: r, scale: "r"},
stroke: {value: stroke, scale: "color"}
}
);
this.fill = fill;
this.fillOpacity = fillOpacity;
this.strokeWidth = strokeWidth;
this.strokeOpacity = strokeOpacity;
this.mixBlendMode = mixBlendMode;
this.channels = {
x: {value: x, scale: "x"},
y: {value: y, scale: "y"},
r: {value: r, scale: "r"},
stroke: {value: stroke, scale: "color"}
};
}
render(
I,
Expand Down
17 changes: 10 additions & 7 deletions src/marks/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import {line} from "d3-shape";
import {indexOf, identity} from "../channels.js";
import {Curve} from "../curve.js";
import {defined} from "../defined.js";
import {Mark} from "../mark.js";

class Line {
class Line extends Mark {
constructor(
data,
{
Expand All @@ -25,7 +26,14 @@ class Line {
mixBlendMode
} = {}
) {
this.data = data;
super(
data,
{
x: {value: x, scale: "x"},
y: {value: y, scale: "y"},
z: z && {value: z}
}
);
this.curve = Curve(curve);
this.fill = fill;
this.fillOpacity = fillOpacity;
Expand All @@ -37,11 +45,6 @@ class Line {
this.strokeDasharray = strokeDasharray;
this.strokeOpacity = strokeOpacity;
this.mixBlendMode = mixBlendMode;
this.channels = {
x: {value: x, scale: "x"},
y: {value: y, scale: "y"},
z: z && {value: z}
};
}
render(I, {x: {scale: x}, y: {scale: y}}) {
const {
Expand Down
19 changes: 11 additions & 8 deletions src/marks/rect.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {create} from "d3-selection";
import {zero} from "../channels.js";
import {defined} from "../defined.js";
import {Mark} from "../mark.js";

export class RectXY {
export class RectXY extends Mark {
constructor(
data,
{
Expand All @@ -22,7 +23,15 @@ export class RectXY {
insetLeft = 0
} = {}
) {
this.data = data;
super(
data,
{
x1: {value: x1, scale: "x"},
y1: {value: y1, scale: "y"},
x2: {value: x2, scale: "x"},
y2: {value: y2, scale: "y"}
}
);
this.fill = fill;
this.fillOpacity = fillOpacity;
this.stroke = stroke;
Expand All @@ -33,12 +42,6 @@ export class RectXY {
this.insetRight = insetRight;
this.insetBottom = insetBottom;
this.insetLeft = insetLeft;
this.channels = {
x1: {value: x1, scale: "x"},
y1: {value: y1, scale: "y"},
x2: {value: x2, scale: "x"},
y2: {value: y2, scale: "y"}
};
}
render(I, {x: {scale: x}, y: {scale: y}}) {
const {
Expand Down
17 changes: 9 additions & 8 deletions src/marks/rule.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import {create} from "d3-selection";
import {identity} from "../channels.js";
import {Mark} from "../mark.js";

export class RuleX {
export class RuleX extends Mark {
constructor(
data, {
data,
{
x = identity,
stroke = "currentColor",
strokeWidth,
strokeOpacity
} = {}) {
this.data = data;
} = {}
) {
super(data, {x: {value: x, scale: "x"}});
this.stroke = stroke;
this.strokeWidth = strokeWidth;
this.strokeOpacity = strokeOpacity;
this.channels = {x: {value: x, scale: "x"}};
}
render(I, {x: {scale: x}}, {marginTop, height, marginBottom}) {
const {
Expand All @@ -39,7 +41,7 @@ export class RuleX {
}
}

export class RuleY {
export class RuleY extends Mark {
constructor(
data,
{
Expand All @@ -49,11 +51,10 @@ export class RuleY {
strokeOpacity
} = {}
) {
this.data = data;
super(data, {y: {value: y, scale: "y"}});
this.stroke = stroke;
this.strokeWidth = strokeWidth;
this.strokeOpacity = strokeOpacity;
this.channels = {y: {value: y, scale: "y"}};
}
render(I, {y: {scale: y}}, {width, marginLeft, marginRight}) {
const {
Expand Down
4 changes: 2 additions & 2 deletions src/plot.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {create} from "d3-selection";
import {Axes, autoAxisTicks, autoAxisLabels} from "./axes.js";
import {Channels, Marks, indexOf} from "./channels.js";
import {Channels, indexOf} from "./channels.js";
import {Scales, autoScaleRange} from "./scales.js";

export function plot(options = {}) {
const marks = Marks(options.marks);
const {marks = []} = options;
const channels = Channels(marks);
const scales = Scales(channels, options.scales);
const axes = Axes(scales, options.axes);
Expand Down

0 comments on commit b5d866b

Please sign in to comment.