Skip to content

Commit 1debd94

Browse files
committed
auto margins
alternative to #1714 closes #1451
1 parent ef19698 commit 1debd94

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
@@ -67,9 +67,9 @@ export class Mark {
6767
this.dx = +dx;
6868
this.dy = +dy;
6969
this.marginTop = +marginTop;
70-
this.marginRight = +marginRight;
70+
this.marginRight = marginRight === "auto" ? "auto" : +marginRight;
7171
this.marginBottom = +marginBottom;
72-
this.marginLeft = +marginLeft;
72+
this.marginLeft = marginLeft === "auto" ? "auto" : +marginLeft;
7373
this.clip = maybeClip(clip);
7474
this.tip = maybeTip(tip);
7575
this.className = className ? maybeClassName(className) : null;

src/marks/axis.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ function axisKy(
8282
x,
8383
margin,
8484
marginTop = margin === undefined ? 20 : margin,
85-
marginRight = margin === undefined ? (anchor === "right" ? 40 : 0) : margin,
85+
marginRight = margin === undefined ? (anchor === "right" ? "auto" : 0) : margin,
8686
marginBottom = margin === undefined ? 20 : margin,
87-
marginLeft = margin === undefined ? (anchor === "left" ? 40 : 0) : margin,
87+
marginLeft = margin === undefined ? (anchor === "left" ? "auto" : 0) : margin,
8888
label,
8989
labelAnchor,
9090
labelArrow,

0 commit comments

Comments
 (0)