|
1 | | -import {isProjection} from "./projection.js"; |
| 1 | +import {hasProjection} from "./projection.js"; |
2 | 2 | import {isOrdinalScale} from "./scales.js"; |
3 | 3 | import {offset} from "./style.js"; |
4 | 4 |
|
5 | | -export function Dimensions( |
6 | | - scales, |
7 | | - geometry, |
8 | | - {x: {axis: xAxis} = {}, y: {axis: yAxis} = {}, fx: {axis: fxAxis} = {}, fy: {axis: fyAxis} = {}}, |
9 | | - { |
10 | | - projection, |
11 | | - width = 640, |
12 | | - height = autoHeight(scales, geometry || isProjection(projection)), |
| 5 | +export function Dimensions(scales, geometry, axes, options = {}) { |
| 6 | + // The default margins depend on the presence and orientation of axes. If the |
| 7 | + // corresponding scale is not present, the axis is necessarily null. |
| 8 | + const {x: {axis: x} = {}, y: {axis: y} = {}, fx: {axis: fx} = {}, fy: {axis: fy} = {}} = axes; |
| 9 | + |
| 10 | + // Compute the default facet margins. When faceting is not present (and hence |
| 11 | + // the fx and fy axis are null), these will all be zero. |
| 12 | + let { |
13 | 13 | facet: { |
14 | 14 | margin: facetMargin, |
15 | | - marginTop: facetMarginTop = facetMargin !== undefined ? facetMargin : fxAxis === "top" ? 30 : 0, |
16 | | - marginRight: facetMarginRight = facetMargin !== undefined ? facetMargin : fyAxis === "right" ? 40 : 0, |
17 | | - marginBottom: facetMarginBottom = facetMargin !== undefined ? facetMargin : fxAxis === "bottom" ? 30 : 0, |
18 | | - marginLeft: facetMarginLeft = facetMargin !== undefined ? facetMargin : fyAxis === "left" ? 40 : 0 |
19 | | - } = {}, |
| 15 | + marginTop: facetMarginTop = facetMargin !== undefined ? facetMargin : fx === "top" ? 30 : 0, |
| 16 | + marginRight: facetMarginRight = facetMargin !== undefined ? facetMargin : fy === "right" ? 40 : 0, |
| 17 | + marginBottom: facetMarginBottom = facetMargin !== undefined ? facetMargin : fx === "bottom" ? 30 : 0, |
| 18 | + marginLeft: facetMarginLeft = facetMargin !== undefined ? facetMargin : fy === "left" ? 40 : 0 |
| 19 | + } = {} |
| 20 | + } = options; |
| 21 | + |
| 22 | + // Coerce the facet margin options to numbers. |
| 23 | + facetMarginTop = +facetMarginTop; |
| 24 | + facetMarginRight = +facetMarginRight; |
| 25 | + facetMarginBottom = +facetMarginBottom; |
| 26 | + facetMarginLeft = +facetMarginLeft; |
| 27 | + |
| 28 | + // Compute the default margins; while not always used, they may be needed to |
| 29 | + // compute the default height of the plot. |
| 30 | + const marginTopDefault = Math.max((x === "top" ? 30 : 0) + facetMarginTop, y || fy ? 20 : 0.5 - offset); |
| 31 | + const marginBottomDefault = Math.max((x === "bottom" ? 30 : 0) + facetMarginBottom, y || fy ? 20 : 0.5 + offset); |
| 32 | + const marginRightDefault = Math.max((y === "right" ? 40 : 0) + facetMarginRight, x || fx ? 20 : 0.5 + offset); |
| 33 | + const marginLeftDefault = Math.max((y === "left" ? 40 : 0) + facetMarginLeft, x || fx ? 20 : 0.5 - offset); |
| 34 | + |
| 35 | + // Compute the actual margins. The order of precedence is: the side-specific |
| 36 | + // margin options, then the global margin option, then the defaults. |
| 37 | + let { |
20 | 38 | margin, |
21 | | - marginTop = margin !== undefined |
22 | | - ? margin |
23 | | - : Math.max((xAxis === "top" ? 30 : 0) + facetMarginTop, yAxis || fyAxis ? 20 : 0.5 - offset), |
24 | | - marginRight = margin !== undefined |
25 | | - ? margin |
26 | | - : Math.max((yAxis === "right" ? 40 : 0) + facetMarginRight, xAxis || fxAxis ? 20 : 0.5 + offset), |
27 | | - marginBottom = margin !== undefined |
28 | | - ? margin |
29 | | - : Math.max((xAxis === "bottom" ? 30 : 0) + facetMarginBottom, yAxis || fyAxis ? 20 : 0.5 + offset), |
30 | | - marginLeft = margin !== undefined |
31 | | - ? margin |
32 | | - : Math.max((yAxis === "left" ? 40 : 0) + facetMarginLeft, xAxis || fxAxis ? 20 : 0.5 - offset) |
33 | | - } = {} |
34 | | -) { |
| 39 | + marginTop = margin !== undefined ? margin : marginTopDefault, |
| 40 | + marginRight = margin !== undefined ? margin : marginRightDefault, |
| 41 | + marginBottom = margin !== undefined ? margin : marginBottomDefault, |
| 42 | + marginLeft = margin !== undefined ? margin : marginLeftDefault |
| 43 | + } = options; |
| 44 | + |
| 45 | + // Coerce the margin options to numbers. |
| 46 | + marginTop = +marginTop; |
| 47 | + marginRight = +marginRight; |
| 48 | + marginBottom = +marginBottom; |
| 49 | + marginLeft = +marginLeft; |
| 50 | + |
| 51 | + // Compute the outer dimensions of the plot. If the top and bottom margins are |
| 52 | + // specified explicitly, adjust the automatic height accordingly. |
| 53 | + let { |
| 54 | + width = 640, |
| 55 | + height = autoHeight(scales, geometry || hasProjection(options)) + |
| 56 | + Math.max(0, marginTop - marginTopDefault + marginBottom - marginBottomDefault) |
| 57 | + } = options; |
| 58 | + |
| 59 | + // Coerce the width and height. |
| 60 | + width = +width; |
| 61 | + height = +height; |
| 62 | + |
35 | 63 | return { |
36 | 64 | width, |
37 | 65 | height, |
|
0 commit comments