1- import { extent } from "d3" ;
1+ import { max , extent } from "d3" ;
22import { projectionAspectRatio } from "./projection.js" ;
33import { isOrdinalScale } from "./scales.js" ;
44import { 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+
620export 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 ;
0 commit comments