Skip to content

Commit a961e0a

Browse files
committed
auto margins
alternative to #1714 closes #1451
1 parent 57cddf4 commit a961e0a

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

src/dimensions.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
import {extent} from "d3";
1+
import {max, extent} from "d3";
22
import {projectionAspectRatio} from "./projection.js";
33
import {isOrdinalScale} from "./scales.js";
44
import {offset} from "./style.js";
55

6+
// A heuristic to determine the default margin. Ordinal scales usually reclaim
7+
// more space. We can also gauge the “type of contents” (domain, ticks?) and
8+
// decide whether it’s small, medium or large. We don’t want it to match the
9+
// contents exactly because it shouldn’t wobble when the scale changes a little.
10+
function autoMarginH({type, domain, ticks} = {}) {
11+
if (type === "point" || type === "band") return sizeHeuristicH(ticks ?? domain);
12+
return sizeHeuristicH((ticks ?? domain ?? []).map(String));
13+
}
14+
15+
function sizeHeuristicH(values = []) {
16+
const l = max(values, (d) => d.length); // TODO text metrics approximation?
17+
return l >= 10 ? 120 : l >= 4 ? 80 : 40;
18+
}
19+
620
export function createDimensions(scales, marks, options = {}) {
721
// Compute the default margins: the maximum of the marks’ margins. While not
822
// always used, they may be needed to compute the default height of the plot.
@@ -11,7 +25,9 @@ export function createDimensions(scales, marks, options = {}) {
1125
marginBottomDefault = 0.5 + offset,
1226
marginLeftDefault = 0.5 - offset;
1327

14-
for (const {marginTop, marginRight, marginBottom, marginLeft} of marks) {
28+
for (let {marginTop, marginRight, marginBottom, marginLeft} of marks) {
29+
if (marginLeft === "auto") marginLeft = autoMarginH(scales.y);
30+
if (marginRight === "auto") marginRight = autoMarginH(scales.y);
1531
if (marginTop > marginTopDefault) marginTopDefault = marginTop;
1632
if (marginRight > marginRightDefault) marginRightDefault = marginRight;
1733
if (marginBottom > marginBottomDefault) marginBottomDefault = marginBottom;

src/mark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ export class Mark {
6666
this.dx = +dx;
6767
this.dy = +dy;
6868
this.marginTop = +marginTop;
69-
this.marginRight = +marginRight;
69+
this.marginRight = marginRight === "auto" ? "auto" : +marginRight;
7070
this.marginBottom = +marginBottom;
71-
this.marginLeft = +marginLeft;
71+
this.marginLeft = marginLeft === "auto" ? "auto" : +marginLeft;
7272
this.clip = maybeClip(clip);
7373
this.tip = maybeTip(tip);
7474
// Super-faceting currently disallow position channels; in the future, we

src/marks/axis.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ function axisKy(
8181
x,
8282
margin,
8383
marginTop = margin === undefined ? 20 : margin,
84-
marginRight = margin === undefined ? (anchor === "right" ? 40 : 0) : margin,
84+
marginRight = margin === undefined ? (anchor === "right" ? "auto" : 0) : margin,
8585
marginBottom = margin === undefined ? 20 : margin,
86-
marginLeft = margin === undefined ? (anchor === "left" ? 40 : 0) : margin,
86+
marginLeft = margin === undefined ? (anchor === "left" ? "auto" : 0) : margin,
8787
label,
8888
labelAnchor,
8989
labelArrow,

0 commit comments

Comments
 (0)