FacetY · Salebarn/plot@fa7b2e1 · GitHub
Skip to content

Commit fa7b2e1

Browse files
committed
FacetY
1 parent 4c78931 commit fa7b2e1

5 files changed

Lines changed: 76 additions & 20 deletions

File tree

src/index.js

Lines changed: 1 addition & 0 deletions

src/marks/facet.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {group} from "d3-array";
2+
import {create} from "d3-selection";
3+
import {Mark, indexOf} from "../mark.js";
4+
import {Channels} from "../plot.js";
5+
import {Scales, autoScaleRange} from "../scales.js";
6+
7+
export class FacetY extends Mark {
8+
constructor(
9+
data,
10+
{
11+
x,
12+
y
13+
} = {},
14+
options = {}
15+
) {
16+
super(
17+
data,
18+
{
19+
x: {value: x, scale: "x"},
20+
y: {value: y, scale: "y", type: "band"}
21+
}
22+
);
23+
this.options = options;
24+
}
25+
render(I, {y: {scale: y}, ...scales}, dimensions) {
26+
const {data, options, channels: {y: {value: Y}}} = this;
27+
const {marks: submarks = []} = options;
28+
const subchannels = Channels(submarks);
29+
const subscales = {...Scales(subchannels, options.scales), ...scales};
30+
const subdimensions = {...dimensions, marginTop: 0, marginBottom: 0, height: y.bandwidth()};
31+
32+
autoScaleRange(subscales, subdimensions);
33+
34+
return create("svg:g")
35+
.call(g => g.selectAll()
36+
.data(group(I, i => Y[i]))
37+
.join("g")
38+
.attr("transform", ([key]) => `translate(0,${y(key)})`)
39+
.each(function([, I]) {
40+
for (const mark of submarks) {
41+
const index = mark.data === data ? I
42+
: mark.data === undefined ? undefined
43+
: Array.from(mark.data, indexOf);
44+
const node = mark.render(index, subscales, subdimensions);
45+
if (node != null) this.appendChild(node);
46+
}
47+
}))
48+
.node();
49+
}
50+
}

src/plot.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ export function plot(options = {}) {
2828
for (const mark of marks) {
2929
const index = mark.data === undefined ? undefined : Array.from(mark.data, indexOf);
3030
const node = mark.render(index, scales, dimensions);
31-
if (node !== null) svg.append(() => node);
31+
if (node != null) svg.append(() => node);
3232
}
3333

3434
return svg.node();
3535
}
3636

37-
function Dimensions({y}, {x: xAxis, y: yAxis}, {
37+
export function Dimensions({y}, {x: xAxis, y: yAxis}, {
3838
width = 640,
3939
height = y ? 396 : 60,
4040
marginTop = !yAxis ? 0 : xAxis && xAxis.anchor === "top" ? 30 : 20,
@@ -45,7 +45,7 @@ function Dimensions({y}, {x: xAxis, y: yAxis}, {
4545
return {width, height, marginTop, marginRight, marginBottom, marginLeft};
4646
}
4747

48-
function Channels(marks) {
48+
export function Channels(marks) {
4949
return group(
5050
marks.flatMap(m => Object.values(m.channels).filter(({scale}) => scale)),
5151
({scale}) => scale

src/scales.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ export function autoScaleRange(scales, dimensions) {
1717
}
1818
if (scales.y && scales.y.range === undefined) {
1919
const {height, marginTop, marginBottom} = dimensions;
20-
scales.y.scale.range([height - marginBottom, marginTop]);
20+
const range = [height - marginBottom, marginTop];
21+
if (scales.y.type === "ordinal") range.reverse();
22+
scales.y.scale.range(range);
2123
}
2224
}
2325

test/facet.html

Lines changed: 19 additions & 16 deletions

0 commit comments

Comments
 (0)