diff --git a/src/index.js b/src/index.js
index 406907ba67..25da3f661d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,6 +2,7 @@ export {plot} from "./plot.js";
export {Mark, marks} from "./mark.js";
export {Area, area, areaX, areaY} from "./marks/area.js";
export {Arrow, arrow} from "./marks/arrow.js";
+export {auto} from "./marks/auto.js";
export {axisX, axisY, axisFx, axisFy, gridX, gridY, gridFx, gridFy} from "./marks/axis.js";
export {BarX, BarY, barX, barY} from "./marks/bar.js";
export {boxX, boxY} from "./marks/box.js";
diff --git a/src/marks/auto.js b/src/marks/auto.js
new file mode 100644
index 0000000000..b7f31e3dc1
--- /dev/null
+++ b/src/marks/auto.js
@@ -0,0 +1,274 @@
+import {InternSet} from "d3";
+import {isOrdinal, labelof, valueof, isOptions, isColor} from "../options.js";
+import {area, areaX, areaY} from "./area.js";
+import {dot} from "./dot.js";
+import {line, lineX, lineY} from "./line.js";
+import {ruleX, ruleY} from "./rule.js";
+import {barX, barY} from "./bar.js";
+import {rect, rectX, rectY} from "./rect.js";
+import {cell} from "./cell.js";
+import {frame} from "./frame.js";
+import {bin, binX, binY} from "../transforms/bin.js";
+import {group, groupX, groupY} from "../transforms/group.js";
+import {marks} from "../mark.js";
+import {ascending} from "d3";
+
+export function auto(data, {x, y, color, size, fx, fy, mark} = {}) {
+ // Allow x and y and other dimensions to be specified as shorthand field names
+ // (but note that they can also be specified as a {transform} object such as
+ // Plot.identity).
+ if (!isOptions(x)) x = makeOptions(x);
+ if (!isOptions(y)) y = makeOptions(y);
+ if (!isOptions(color)) color = isColor(color) ? {color} : makeOptions(color);
+ if (!isOptions(size)) size = makeOptions(size);
+
+ // We don’t apply any type inference to the fx and fy channels, if present, so
+ // these are simply passed-through to the underlying mark’s options.
+ if (isOptions(fx)) ({value: fx} = makeOptions(fx));
+ if (isOptions(fy)) ({value: fy} = makeOptions(fy));
+
+ const {value: xValue} = x;
+ const {value: yValue} = y;
+ const {value: sizeValue} = size;
+ const {value: colorValue, color: colorColor} = color;
+
+ // Determine the default reducer, if any.
+ let {reduce: xReduce} = x;
+ let {reduce: yReduce} = y;
+ let {reduce: sizeReduce} = size;
+ let {reduce: colorReduce} = color;
+ if (xReduce === undefined)
+ xReduce = yReduce == null && xValue == null && sizeValue == null && yValue != null ? "count" : null;
+ if (yReduce === undefined)
+ yReduce = xReduce == null && yValue == null && sizeValue == null && xValue != null ? "count" : null;
+
+ let {zero: xZero} = x;
+ let {zero: yZero} = y;
+
+ // TODO The line mark will need z?
+ // TODO Limit and sort for bar charts (e.g. alphabet)?
+ // TODO Look at Plot warnings and see how many we can prevent
+ // TODO Default to something other than turbo for continuous? Like:
+ // scheme: (colorValue && isContinuous(color)) || colorReduce ? "ylgnbu" : undefined
+
+ // To apply heuristics based on the data types (values), realize the columns.
+ // We could maybe look at the data.schema here, but Plot’s behavior depends on
+ // the actual values anyway, so this probably is what we want. By
+ // materializing the columns here, we also ensure that they aren’t re-computed
+ // later in Plot.plot.
+ x = valueof(data, xValue);
+ y = valueof(data, yValue);
+ color = valueof(data, colorValue);
+ size = valueof(data, sizeValue);
+
+ // TODO Shorthand: array of primitives should result in a histogram
+ if (!x && !y) throw new Error("must specify x or y");
+ if (xReduce != null && !y) throw new Error("reducing x requires y");
+ if (yReduce != null && !x) throw new Error("reducing y requires x");
+
+ let z, zReduce;
+
+ // Propagate the x and y labels (field names), if any. This is necessary for
+ // any column we materialize (and hence, we don’t need to do this for fx and
+ // fy, since those columns are not needed for type inference and hence are not
+ // greedily materialized).
+ if (x) x.label = labelof(xValue);
+ if (y) y.label = labelof(yValue);
+ if (color) color.label = labelof(colorValue);
+ if (size) size.label = labelof(sizeValue);
+
+ // Determine the default size reducer, if any.
+ if (
+ sizeReduce === undefined &&
+ sizeValue == null &&
+ colorReduce == null &&
+ xReduce == null &&
+ yReduce == null &&
+ (!x || isOrdinal(x)) &&
+ (!y || isOrdinal(y))
+ ) {
+ sizeReduce = "count";
+ }
+
+ // Determine the default mark type.
+ if (mark === undefined) {
+ mark =
+ sizeValue != null || sizeReduce != null
+ ? "dot"
+ : xReduce != null || yReduce != null || colorReduce != null
+ ? "bar"
+ : x && y
+ ? isContinuous(x) && isContinuous(y) && (isMonotonic(x) || isMonotonic(y))
+ ? "line"
+ : (isContinuous(x) && xZero) || (isContinuous(y) && yZero)
+ ? "bar"
+ : "dot"
+ : x
+ ? "rule"
+ : y
+ ? "rule"
+ : null;
+ }
+
+ let colorMode; // "fill" or "stroke"
+
+ // Determine the mark implementation.
+ if (mark != null) {
+ switch (`${mark}`.toLowerCase()) {
+ case "dot":
+ mark = dot;
+ colorMode = "stroke";
+ break;
+ case "line":
+ mark = x && y ? line : x ? lineX : lineY; // 1d line by index
+ colorMode = "stroke";
+ if (isHighCardinality(color)) z = null; // TODO only if z not set by user
+ break;
+ case "area":
+ mark =
+ x && y
+ ? isContinuous(x) && isMonotonic(x)
+ ? areaY
+ : isContinuous(y) && isMonotonic(y)
+ ? areaX
+ : area // TODO error? how does it work with ordinal?
+ : x
+ ? areaX
+ : areaY; // 1d area by index
+ colorMode = "fill";
+ if (isHighCardinality(color)) z = null; // TODO only if z not set by user
+ break;
+ case "rule":
+ mark = x ? ruleX : ruleY;
+ colorMode = "stroke";
+ break;
+ case "bar":
+ mark =
+ yReduce != null
+ ? isOrdinal(x)
+ ? barY
+ : rectY
+ : xReduce != null
+ ? isOrdinal(y)
+ ? barX
+ : rectX
+ : colorReduce != null
+ ? x && y && isOrdinal(x) && isOrdinal(y)
+ ? cell
+ : x && isOrdinal(x)
+ ? barY
+ : y && isOrdinal(y)
+ ? barX
+ : rect
+ : x && y && isOrdinal(x) && isOrdinal(y)
+ ? cell
+ : y && isOrdinal(y)
+ ? barX
+ : barY;
+ colorMode = "fill";
+ break;
+ default:
+ throw new Error(`invalid mark: ${mark}`);
+ }
+ }
+
+ // Determine the mark options.
+ let options = {x, y, [colorMode]: color ?? colorColor, z, r: size, fx, fy};
+ let transform;
+ let transformOptions = {[colorMode]: colorReduce, z: zReduce, r: sizeReduce};
+ if (xReduce != null && yReduce != null) {
+ throw new Error(`cannot reduce both x and y`); // for now at least
+ } else if (yReduce != null) {
+ transformOptions.y = yReduce;
+ transform = isOrdinal(x) ? groupX : binX;
+ } else if (xReduce != null) {
+ transformOptions.x = xReduce;
+ transform = isOrdinal(y) ? groupY : binY;
+ } else if (colorReduce != null || sizeReduce != null) {
+ if (x && y) {
+ transform = isOrdinal(x) && isOrdinal(y) ? group : isOrdinal(x) ? binY : isOrdinal(y) ? binX : bin;
+ } else if (x) {
+ transform = isOrdinal(x) ? groupX : binX;
+ } else if (y) {
+ transform = isOrdinal(y) ? groupY : binY;
+ }
+ }
+ if (transform) options = transform(transformOptions, options);
+
+ // If zero-ness is not specified, default based on whether the resolved mark
+ // type will include a zero baseline.
+ if (xZero === undefined) xZero = transform !== binX && (mark === barX || mark === areaX || mark === rectX);
+ if (yZero === undefined) yZero = transform !== binY && (mark === barY || mark === areaY || mark === rectY);
+
+ // In the case of filled marks (particularly bars and areas) the frame and
+ // rules should come after the mark; in the case of stroked marks
+ // (particularly dots and lines) they should come before the mark.
+ const frames = fx != null || fy != null ? frame({strokeOpacity: 0.1}) : null;
+ const rules = [xZero ? ruleX([0]) : null, yZero ? ruleY([0]) : null];
+ mark = mark(data, options);
+ return colorMode === "stroke" ? marks(frames, rules, mark) : marks(frames, mark, rules);
+}
+
+function isContinuous(values) {
+ return !isOrdinal(values);
+}
+
+// TODO What about sorted within series?
+function isMonotonic(values) {
+ let previous;
+ let previousOrder;
+ for (const value of values) {
+ if (value == null) continue;
+ if (previous === undefined) {
+ previous = value;
+ continue;
+ }
+ const order = Math.sign(ascending(previous, value));
+ if (!order) continue; // skip zero, NaN
+ if (previousOrder !== undefined && order !== previousOrder) return false;
+ previous = value;
+ previousOrder = order;
+ }
+ return true;
+}
+
+function makeOptions(value) {
+ return isReducer(value) ? {reduce: value} : {value};
+}
+
+// https://github.com/observablehq/plot/blob/818562649280e155136f730fc496e0b3d15ae464/src/transforms/group.js#L236
+function isReducer(reduce) {
+ if (typeof reduce?.reduce === "function") return true;
+ if (/^p\d{2}$/i.test(reduce)) return true;
+ switch (`${reduce}`.toLowerCase()) {
+ case "first":
+ case "last":
+ case "count":
+ case "distinct":
+ case "sum":
+ case "proportion":
+ case "proportion-facet": // TODO remove me?
+ case "deviation":
+ case "min":
+ case "min-index": // TODO remove me?
+ case "max":
+ case "max-index": // TODO remove me?
+ case "mean":
+ case "median":
+ case "variance":
+ case "mode":
+ // These are technically reducers, but I think we’d want to treat them as fields?
+ // case "x":
+ // case "x1":
+ // case "x2":
+ // case "y":
+ // case "y1":
+ // case "y2":
+ return true;
+ }
+ return false;
+}
+
+function isHighCardinality(value) {
+ return value ? new InternSet(value).size > value.length >> 1 : false;
+}
diff --git a/test/output/autoArea.svg b/test/output/autoArea.svg
new file mode 100644
index 0000000000..63fed34fda
--- /dev/null
+++ b/test/output/autoArea.svg
@@ -0,0 +1,63 @@
+
\ No newline at end of file
diff --git a/test/output/autoAreaColor.svg b/test/output/autoAreaColor.svg
new file mode 100644
index 0000000000..37c9fdb8ad
--- /dev/null
+++ b/test/output/autoAreaColor.svg
@@ -0,0 +1,1263 @@
+
\ No newline at end of file
diff --git a/test/output/autoAreaColorColor.svg b/test/output/autoAreaColorColor.svg
new file mode 100644
index 0000000000..1449edd015
--- /dev/null
+++ b/test/output/autoAreaColorColor.svg
@@ -0,0 +1,63 @@
+
\ No newline at end of file
diff --git a/test/output/autoAreaColorName.svg b/test/output/autoAreaColorName.svg
new file mode 100644
index 0000000000..1449edd015
--- /dev/null
+++ b/test/output/autoAreaColorName.svg
@@ -0,0 +1,63 @@
+
\ No newline at end of file
diff --git a/test/output/autoAreaColorValue.svg b/test/output/autoAreaColorValue.svg
new file mode 100644
index 0000000000..37c9fdb8ad
--- /dev/null
+++ b/test/output/autoAreaColorValue.svg
@@ -0,0 +1,1263 @@
+
\ No newline at end of file
diff --git a/test/output/autoAreaStackColor.svg b/test/output/autoAreaStackColor.svg
new file mode 100644
index 0000000000..00d52c1760
--- /dev/null
+++ b/test/output/autoAreaStackColor.svg
@@ -0,0 +1,84 @@
+
\ No newline at end of file
diff --git a/test/output/autoBar.svg b/test/output/autoBar.svg
new file mode 100644
index 0000000000..5b63abcdf7
--- /dev/null
+++ b/test/output/autoBar.svg
@@ -0,0 +1,127 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarColorReducer.svg b/test/output/autoBarColorReducer.svg
new file mode 100644
index 0000000000..1b4910f87d
--- /dev/null
+++ b/test/output/autoBarColorReducer.svg
@@ -0,0 +1,60 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarMean.svg b/test/output/autoBarMean.svg
new file mode 100644
index 0000000000..5e4b404754
--- /dev/null
+++ b/test/output/autoBarMean.svg
@@ -0,0 +1,84 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarStackColor.svg b/test/output/autoBarStackColor.svg
new file mode 100644
index 0000000000..df2f1eb4a6
--- /dev/null
+++ b/test/output/autoBarStackColor.svg
@@ -0,0 +1,65 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarStackColorConstant.svg b/test/output/autoBarStackColorConstant.svg
new file mode 100644
index 0000000000..1fc853443c
--- /dev/null
+++ b/test/output/autoBarStackColorConstant.svg
@@ -0,0 +1,121 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarStackColorField.svg b/test/output/autoBarStackColorField.svg
new file mode 100644
index 0000000000..67cdff8c21
--- /dev/null
+++ b/test/output/autoBarStackColorField.svg
@@ -0,0 +1,176 @@
+
\ No newline at end of file
diff --git a/test/output/autoBarZero.svg b/test/output/autoBarZero.svg
new file mode 100644
index 0000000000..5b63abcdf7
--- /dev/null
+++ b/test/output/autoBarZero.svg
@@ -0,0 +1,127 @@
+
\ No newline at end of file
diff --git a/test/output/autoConnectedScatterplot.svg b/test/output/autoConnectedScatterplot.svg
new file mode 100644
index 0000000000..5e2d20ead6
--- /dev/null
+++ b/test/output/autoConnectedScatterplot.svg
@@ -0,0 +1,67 @@
+
\ No newline at end of file
diff --git a/test/output/autoDot.svg b/test/output/autoDot.svg
new file mode 100644
index 0000000000..13d72dd5cc
--- /dev/null
+++ b/test/output/autoDot.svg
@@ -0,0 +1,398 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotBin.svg b/test/output/autoDotBin.svg
new file mode 100644
index 0000000000..64d3718ce3
--- /dev/null
+++ b/test/output/autoDotBin.svg
@@ -0,0 +1,118 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotColor.svg b/test/output/autoDotColor.svg
new file mode 100644
index 0000000000..d0192b551b
--- /dev/null
+++ b/test/output/autoDotColor.svg
@@ -0,0 +1,464 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotFacet.svg b/test/output/autoDotFacet.svg
new file mode 100644
index 0000000000..898d97b872
--- /dev/null
+++ b/test/output/autoDotFacet.svg
@@ -0,0 +1,445 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotFacet2.svg b/test/output/autoDotFacet2.svg
new file mode 100644
index 0000000000..cb26cf9381
--- /dev/null
+++ b/test/output/autoDotFacet2.svg
@@ -0,0 +1,513 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotGroup.svg b/test/output/autoDotGroup.svg
new file mode 100644
index 0000000000..6d310000bc
--- /dev/null
+++ b/test/output/autoDotGroup.svg
@@ -0,0 +1,49 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotOrdCont.svg b/test/output/autoDotOrdCont.svg
new file mode 100644
index 0000000000..b8d95236c8
--- /dev/null
+++ b/test/output/autoDotOrdCont.svg
@@ -0,0 +1,390 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotOrdinal.svg b/test/output/autoDotOrdinal.svg
new file mode 100644
index 0000000000..005d304738
--- /dev/null
+++ b/test/output/autoDotOrdinal.svg
@@ -0,0 +1,858 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotSize.svg b/test/output/autoDotSize.svg
new file mode 100644
index 0000000000..5f63a8fa47
--- /dev/null
+++ b/test/output/autoDotSize.svg
@@ -0,0 +1,1292 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotSize2.svg b/test/output/autoDotSize2.svg
new file mode 100644
index 0000000000..224c2afc25
--- /dev/null
+++ b/test/output/autoDotSize2.svg
@@ -0,0 +1,400 @@
+
\ No newline at end of file
diff --git a/test/output/autoDotUnsortedDate.svg b/test/output/autoDotUnsortedDate.svg
new file mode 100644
index 0000000000..30d664e7c5
--- /dev/null
+++ b/test/output/autoDotUnsortedDate.svg
@@ -0,0 +1,11280 @@
+
\ No newline at end of file
diff --git a/test/output/autoHeatmap.svg b/test/output/autoHeatmap.svg
new file mode 100644
index 0000000000..a22a2400ae
--- /dev/null
+++ b/test/output/autoHeatmap.svg
@@ -0,0 +1,124 @@
+
\ No newline at end of file
diff --git a/test/output/autoHeatmapOrdCont.svg b/test/output/autoHeatmapOrdCont.svg
new file mode 100644
index 0000000000..af5ec467a0
--- /dev/null
+++ b/test/output/autoHeatmapOrdCont.svg
@@ -0,0 +1,76 @@
+
\ No newline at end of file
diff --git a/test/output/autoHeatmapOrdinal.svg b/test/output/autoHeatmapOrdinal.svg
new file mode 100644
index 0000000000..71b42fc1eb
--- /dev/null
+++ b/test/output/autoHeatmapOrdinal.svg
@@ -0,0 +1,49 @@
+
\ No newline at end of file
diff --git a/test/output/autoHistogram.svg b/test/output/autoHistogram.svg
new file mode 100644
index 0000000000..12fdead10c
--- /dev/null
+++ b/test/output/autoHistogram.svg
@@ -0,0 +1,144 @@
+
\ No newline at end of file
diff --git a/test/output/autoHistogramDate.svg b/test/output/autoHistogramDate.svg
new file mode 100644
index 0000000000..0ed682670c
--- /dev/null
+++ b/test/output/autoHistogramDate.svg
@@ -0,0 +1,124 @@
+
\ No newline at end of file
diff --git a/test/output/autoHistogramGroup.svg b/test/output/autoHistogramGroup.svg
new file mode 100644
index 0000000000..3441715bef
--- /dev/null
+++ b/test/output/autoHistogramGroup.svg
@@ -0,0 +1,62 @@
+
\ No newline at end of file
diff --git a/test/output/autoLine.svg b/test/output/autoLine.svg
new file mode 100644
index 0000000000..0fea073253
--- /dev/null
+++ b/test/output/autoLine.svg
@@ -0,0 +1,68 @@
+
\ No newline at end of file
diff --git a/test/output/autoLineColor.svg b/test/output/autoLineColor.svg
new file mode 100644
index 0000000000..e3267fd3aa
--- /dev/null
+++ b/test/output/autoLineColor.svg
@@ -0,0 +1,1268 @@
+
\ No newline at end of file
diff --git a/test/output/autoLineColorSeries.svg b/test/output/autoLineColorSeries.svg
new file mode 100644
index 0000000000..71625400fc
--- /dev/null
+++ b/test/output/autoLineColorSeries.svg
@@ -0,0 +1,89 @@
+
\ No newline at end of file
diff --git a/test/output/autoLineFacet.svg b/test/output/autoLineFacet.svg
new file mode 100644
index 0000000000..428d706d7c
--- /dev/null
+++ b/test/output/autoLineFacet.svg
@@ -0,0 +1,276 @@
+
\ No newline at end of file
diff --git a/test/output/autoLineHistogram.svg b/test/output/autoLineHistogram.svg
new file mode 100644
index 0000000000..c730559272
--- /dev/null
+++ b/test/output/autoLineHistogram.svg
@@ -0,0 +1,69 @@
+
\ No newline at end of file
diff --git a/test/output/autoNullReduceContinuous.svg b/test/output/autoNullReduceContinuous.svg
new file mode 100644
index 0000000000..7ff04232ad
--- /dev/null
+++ b/test/output/autoNullReduceContinuous.svg
@@ -0,0 +1,377 @@
+
\ No newline at end of file
diff --git a/test/output/autoNullReduceDate.svg b/test/output/autoNullReduceDate.svg
new file mode 100644
index 0000000000..1393fe90e0
--- /dev/null
+++ b/test/output/autoNullReduceDate.svg
@@ -0,0 +1,11583 @@
+
\ No newline at end of file
diff --git a/test/output/autoNullReduceOrdinal.svg b/test/output/autoNullReduceOrdinal.svg
new file mode 100644
index 0000000000..355bbe1f78
--- /dev/null
+++ b/test/output/autoNullReduceOrdinal.svg
@@ -0,0 +1,34 @@
+
\ No newline at end of file
diff --git a/test/output/autoRectColorReducer.svg b/test/output/autoRectColorReducer.svg
new file mode 100644
index 0000000000..4ebba9f114
--- /dev/null
+++ b/test/output/autoRectColorReducer.svg
@@ -0,0 +1,78 @@
+
\ No newline at end of file
diff --git a/test/output/autoRectStackColor.svg b/test/output/autoRectStackColor.svg
new file mode 100644
index 0000000000..8ed4fcf340
--- /dev/null
+++ b/test/output/autoRectStackColor.svg
@@ -0,0 +1,98 @@
+
\ No newline at end of file
diff --git a/test/plots/autoplot.js b/test/plots/autoplot.js
new file mode 100644
index 0000000000..afea90c234
--- /dev/null
+++ b/test/plots/autoplot.js
@@ -0,0 +1,214 @@
+import * as Plot from "@observablehq/plot";
+import * as d3 from "d3";
+
+export async function autoHistogram() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "weight"}).plot();
+}
+
+export async function autoHistogramDate() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "date_of_birth"}).plot();
+}
+
+export async function autoHistogramGroup() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "island"}).plot();
+}
+
+export async function autoNullReduceContinuous() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: {reduce: null}}).plot();
+}
+
+export async function autoNullReduceOrdinal() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "island", y: {reduce: null}}).plot();
+}
+
+export async function autoNullReduceDate() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "date_of_birth", y: {reduce: null}}).plot();
+}
+
+export async function autoLineHistogram() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Volume", mark: "line"}).plot();
+}
+
+export async function autoLine() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close"}).plot();
+}
+
+export async function autoArea() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", mark: "area"}).plot();
+}
+
+export async function autoAreaColor() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", color: "Close", mark: "area"}).plot();
+}
+
+export async function autoAreaColorValue() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", color: {value: "Close"}, mark: "area"}).plot();
+}
+
+export async function autoAreaColorName() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", color: "red", mark: "area"}).plot();
+}
+
+export async function autoAreaColorColor() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", color: {color: "red"}, mark: "area"}).plot();
+}
+
+export async function autoDot() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "body_mass_g"}).plot();
+}
+
+export async function autoDotOrdinal() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "sex", y: "nationality"}).plot();
+}
+
+export async function autoDotOrdCont() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "species"}).plot();
+}
+
+export async function autoBar() {
+ const alphabet = await d3.csv("data/alphabet.csv", d3.autoType);
+ return Plot.auto(alphabet, {x: "frequency", y: "letter", mark: "bar"}).plot();
+}
+
+export async function autoBarZero() {
+ const alphabet = await d3.csv("data/alphabet.csv", d3.autoType);
+ return Plot.auto(alphabet, {x: {value: "frequency", zero: true}, y: "letter"}).plot();
+}
+
+export async function autoConnectedScatterplot() {
+ const driving = await d3.csv("data/driving.csv", d3.autoType);
+ return Plot.auto(driving, {x: "miles", y: "gas", mark: "line"}).plot();
+}
+
+// shouldnt make a line
+export async function autoDotUnsortedDate() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "date_of_birth", y: "height"}).plot();
+}
+
+export async function autoDotSize() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", size: "Volume"}).plot();
+}
+
+export async function autoDotSize2() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm", size: "body_mass_g"}).plot();
+}
+
+export async function autoDotGroup() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "island", y: "species", size: "count"}).plot();
+}
+
+export async function autoDotBin() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "body_mass_g", size: "count"}).plot();
+}
+
+export async function autoDotColor() {
+ const cars = await d3.csv("data/cars.csv", d3.autoType);
+ return Plot.auto(cars, {x: "power (hp)", y: "weight (lb)", color: "0-60 mph (s)"}).plot();
+}
+
+export async function autoHeatmapOrdCont() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "species", color: "count"}).plot();
+}
+
+export async function autoHeatmap() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", y: "body_mass_g", color: "count"}).plot();
+}
+
+export async function autoHeatmapOrdinal() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "island", y: "species", color: "count"}).plot();
+}
+
+export async function autoBarStackColor() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {y: "species", color: "sex"}).plot();
+}
+
+export async function autoBarColorReducer() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {y: "species", color: "count"}).plot();
+}
+
+export async function autoRectStackColor() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", color: "island"}).plot();
+}
+
+export async function autoRectColorReducer() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "culmen_length_mm", color: {value: "island", reduce: "mode"}}).plot();
+}
+
+export async function autoLineColor() {
+ const aapl = await d3.csv("data/aapl.csv", d3.autoType);
+ return Plot.auto(aapl, {x: "Date", y: "Close", color: "Close"}).plot();
+}
+
+export async function autoLineColorSeries() {
+ const industries = await d3.csv("data/bls-industry-unemployment.csv", d3.autoType);
+ return Plot.auto(industries, {x: "date", y: "unemployed", color: "industry"}).plot();
+}
+
+export async function autoAreaStackColor() {
+ const industries = await d3.csv("data/bls-industry-unemployment.csv", d3.autoType);
+ return Plot.auto(industries, {x: "date", y: "unemployed", color: "industry", mark: "area"}).plot();
+}
+
+export async function autoBarStackColorField() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "height", color: {value: "gold"}}).plot();
+}
+
+export async function autoBarStackColorConstant() {
+ const athletes = await d3.csv("data/athletes.csv", d3.autoType);
+ return Plot.auto(athletes, {x: "height", color: "gold"}).plot();
+}
+
+export async function autoBarMean() {
+ const weather = await d3.csv("data/seattle-weather.csv", d3.autoType);
+ return Plot.auto(weather, {x: "date", y: {value: "temp_max", reduce: "mean"}}).plot();
+}
+
+export async function autoLineFacet() {
+ const industries = await d3.csv("data/bls-industry-unemployment.csv", d3.autoType);
+ return Plot.auto(industries, {x: "date", y: "unemployed", fy: "industry"}).plot();
+}
+
+export async function autoDotFacet() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {x: "body_mass_g", y: "culmen_length_mm", fx: "island", color: "sex"}).plot();
+}
+
+export async function autoDotFacet2() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.auto(penguins, {
+ x: "body_mass_g",
+ y: "culmen_length_mm",
+ fx: "island",
+ fy: "species",
+ color: "sex"
+ }).plot();
+}
diff --git a/test/plots/index.js b/test/plots/index.js
index fea350a24f..dafea94656 100644
--- a/test/plots/index.js
+++ b/test/plots/index.js
@@ -280,6 +280,7 @@ export * from "./aapl-bollinger.js";
export * from "./aapl-close.js";
export * from "./aapl-fancy-axis.js";
export * from "./athletes-sample.js";
+export * from "./autoplot.js";
export * from "./axis-labels.js";
export * from "./bin-1m.js";
export * from "./electricity-demand.js";