Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ These options determine the overall layout of the plot; all are specified as num
* **margin** - shorthand for the four margins
* **width** - the outer width of the plot (including margins)
* **height** - the outer height of the plot (including margins)
* **aspectRatio** - the desired aspect ratio of data (affecting default **height**)

The default **width** is 640. On Observable, the width can be set to the [standard width](https://github.com/observablehq/stdlib/blob/main/README.md#width) to make responsive plots. The default **height** is chosen automatically based on the plot’s associated scales; for example, if *y* is linear and there is no *fy* scale, it might be 396. The default margins depend on the maximum margins of the plot’s constituent [marks](#mark-options). While most marks default to zero margins (because they are drawn inside the chart area), Plot’s [axis mark](#axis) has non-zero default margins.

The **aspectRatio** option, if not null, computes a default **height** such that a variation of one unit in the *x* dimension is represented by the corresponding number of pixels as a variation in the *y* dimension of one unit. Note: when using facets, set the *fx* and *fy* scales’ **round** option to false if you need an exact aspect ratio.

The **style** option allows custom styles to override Plot’s defaults. It may be specified either as a string of inline styles (*e.g.*, `"color: red;"`, in the same fashion as assigning [*element*.style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style)) or an object of properties (*e.g.*, `{color: "red"}`, in the same fashion as assigning [*element*.style properties](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration)). Note that unitless numbers ([quirky lengths](https://www.w3.org/TR/css-values-4/#deprecated-quirky-length)) such as `{padding: 20}` may not supported by some browsers; you should instead specify a string with units such as `{padding: "20px"}`. By default, the returned plot has a white background, a max-width of 100%, and the system-ui font. Plot’s marks and axes default to [currentColor](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword), meaning that they will inherit the surrounding content’s color. For example, a dark theme:

```js
Expand Down
45 changes: 43 additions & 2 deletions src/dimensions.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {extent} from "d3";
import {projectionAspectRatio} from "./projection.js";
import {isOrdinalScale} from "./scales.js";
import {offset} from "./style.js";
Expand Down Expand Up @@ -87,9 +88,9 @@ export function Dimensions(scales, marks, options = {}) {
}

function autoHeight(
{y, fy, fx},
{x, y, fy, fx},
marks,
{projection},
{projection, aspectRatio},
{width, marginTopDefault, marginRightDefault, marginBottomDefault, marginLeftDefault}
) {
const nfy = fy ? fy.scale.domain().length : 1;
Expand All @@ -104,5 +105,45 @@ function autoHeight(
}

const ny = y ? (isOrdinalScale(y) ? y.scale.domain().length : Math.max(7, 17 / nfy)) : 1;

// If a desired aspect ratio is given, compute a default height to match.
if (aspectRatio != null) {
aspectRatio = +aspectRatio;
if (!(isFinite(aspectRatio) && aspectRatio > 0)) throw new Error(`invalid aspectRatio: ${aspectRatio}`);
const ratio = aspectRatioLength("y", y) / (aspectRatioLength("x", x) * aspectRatio);
const fxb = fx ? fx.scale.bandwidth() : 1;
const fyb = fy ? fy.scale.bandwidth() : 1;
const w = fxb * (width - marginLeftDefault - marginRightDefault) - x.insetLeft - x.insetRight;
return (ratio * w + y.insetTop + y.insetBottom) / fyb + marginTopDefault + marginBottomDefault;
}

return !!(y || fy) * Math.max(1, Math.min(60, ny * nfy)) * 20 + !!fx * 30 + 60;
}

function aspectRatioLength(k, scale) {
if (!scale) throw new Error(`aspectRatio requires ${k} scale`);
const {type, domain} = scale;
let transform;
switch (type) {
case "linear":
case "utc":
case "time":
transform = Number;
break;
case "pow": {
const exponent = scale.scale.exponent();
transform = (x) => Math.pow(x, exponent);
break;
}
case "log":
transform = Math.log;
break;
case "point":
case "band":
return domain.length;
default:
throw new Error(`unsupported ${k} scale for aspectRatio: ${type}`);
}
const [min, max] = extent(domain);
return Math.abs(transform(max) - transform(min));
}
5 changes: 5 additions & 0 deletions test/data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ https://data.giss.nasa.gov/gistemp/
Met Office Hadley Centre
https://www.metoffice.gov.uk/hadobs/hadcrut4/data/current/series_format.html

## libor.csv
CBO
https://www.cbo.gov/topics/budget/accuracy-projections
https://observablehq.com/@tophtucker/examples-of-bitemporal-charts

## metros.csv
The New York Times
https://www.nytimes.com/2019/12/02/upshot/wealth-poverty-divide-american-cities.html
Expand Down
Loading