diff --git a/src/transforms/hexbin.js b/src/transforms/hexbin.js
index b8c235f367..fdbf9c98f1 100644
--- a/src/transforms/hexbin.js
+++ b/src/transforms/hexbin.js
@@ -10,7 +10,6 @@ export function hexbin(outputs = {fill: "count"}, options = {}) {
// TODO group by (implicit) z
// TODO filter e.g. to show empty hexbins?
-// TODO data output with sort and reverse?
// TODO disallow x, x1, x2, y, y1, y2 reducers?
function hexbinn(outputs, {radius = 10, ...options}) {
radius = +radius;
@@ -44,14 +43,15 @@ function hexbinn(outputs, {radius = 10, ...options}) {
}
binFacets.push(binFacet);
}
- return {
- facets: binFacets,
- channels: {
- x: {value: BX},
- y: {value: BY},
- ...Object.fromEntries(outputs.map(({name, output}) => [name, {scale: true, radius: name === "r" ? radius : undefined, value: output.transform()}]))
- }
+ const channels = {
+ x: {value: BX},
+ y: {value: BY},
+ ...Object.fromEntries(outputs.map(({name, output}) => [name, {scale: true, radius: name === "r" ? radius : undefined, value: output.transform()}]))
};
+ if ("r" in channels) {
+ binFacets.forEach(index => index.sort((i, j) => channels.r.value[j] - channels.r.value[i]));
+ }
+ return {facets: binFacets, channels};
}
};
}
diff --git a/test/output/hexbin.svg b/test/output/hexbin.svg
index 3dd2cc8e45..2f2c99539d 100644
--- a/test/output/hexbin.svg
+++ b/test/output/hexbin.svg
@@ -88,120 +88,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -211,71 +245,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/output/hexbinR.html b/test/output/hexbinR.html
new file mode 100644
index 0000000000..72ba66125c
--- /dev/null
+++ b/test/output/hexbinR.html
@@ -0,0 +1,521 @@
+
\ No newline at end of file
diff --git a/test/output/hexbinSymbol.html b/test/output/hexbinSymbol.html
new file mode 100644
index 0000000000..468bc20c88
--- /dev/null
+++ b/test/output/hexbinSymbol.html
@@ -0,0 +1,236 @@
+
+
+
\ No newline at end of file
diff --git a/test/output/hexbinText.svg b/test/output/hexbinText.svg
new file mode 100644
index 0000000000..78faa732ed
--- /dev/null
+++ b/test/output/hexbinText.svg
@@ -0,0 +1,195 @@
+
\ No newline at end of file
diff --git a/test/plots/hexbin-r.js b/test/plots/hexbin-r.js
new file mode 100644
index 0000000000..e63eb72ae5
--- /dev/null
+++ b/test/plots/hexbin-r.js
@@ -0,0 +1,20 @@
+import * as Plot from "@observablehq/plot";
+import * as d3 from "d3";
+
+export default async function() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.plot({
+ width: 820,
+ height: 320,
+ color: {scheme: "reds", nice: true, tickFormat: d => 100 * d, label: "Proportion of each facet (%)", legend: true},
+ facet: {
+ data: penguins,
+ x: "sex",
+ marginRight: 80
+ },
+ marks: [
+ Plot.frame(),
+ Plot.dot(penguins, Plot.hexbin({title: "proportion-facet", r: "count", fill: "proportion-facet"}, {x: "culmen_depth_mm", y: "culmen_length_mm", strokeWidth: 1}))
+ ]
+ });
+}
diff --git a/test/plots/hexbin-symbol.js b/test/plots/hexbin-symbol.js
new file mode 100644
index 0000000000..89a9c941ba
--- /dev/null
+++ b/test/plots/hexbin-symbol.js
@@ -0,0 +1,18 @@
+import * as Plot from "@observablehq/plot";
+import * as d3 from "d3";
+
+export default async function() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.plot({
+ grid: true,
+ marks: [
+ Plot.dot(penguins, Plot.hexbin({r: "count", symbol: "mode"}, {
+ radius: 20,
+ symbol: "sex",
+ x: "culmen_depth_mm",
+ y: "culmen_length_mm"
+ }))
+ ],
+ symbol: {legend: true}
+ });
+}
diff --git a/test/plots/hexbin-text.js b/test/plots/hexbin-text.js
new file mode 100644
index 0000000000..8ab4086588
--- /dev/null
+++ b/test/plots/hexbin-text.js
@@ -0,0 +1,21 @@
+import * as Plot from "@observablehq/plot";
+import * as d3 from "d3";
+
+export default async function() {
+ const penguins = await d3.csv("data/penguins.csv", d3.autoType);
+ return Plot.plot({
+ width: 820,
+ height: 320,
+ facet: {
+ data: penguins,
+ x: "sex",
+ marginRight: 80
+ },
+ inset: 14,
+ marks: [
+ Plot.frame(),
+ Plot.dot(penguins, Plot.hexbin({fillOpacity: "count"}, {x: "culmen_depth_mm", y: "culmen_length_mm", fill: "brown", stroke: "black", strokeWidth: 0.5})),
+ Plot.text(penguins, Plot.hexbin({text: "count"}, {x: "culmen_depth_mm", y: "culmen_length_mm"}))
+ ]
+ });
+}
diff --git a/test/plots/index.js b/test/plots/index.js
index ab58150106..8d87fc7792 100644
--- a/test/plots/index.js
+++ b/test/plots/index.js
@@ -63,6 +63,9 @@ export {default as googleTrendsRidgeline} from "./google-trends-ridgeline.js";
export {default as gridChoropleth} from "./grid-choropleth.js";
export {default as hadcrutWarmingStripes} from "./hadcrut-warming-stripes.js";
export {default as hexbin} from "./hexbin.js";
+export {default as hexbinR} from "./hexbin-r.js";
+export {default as hexbinSymbol} from "./hexbin-symbol.js";
+export {default as hexbinText} from "./hexbin-text.js";
export {default as highCardinalityOrdinal} from "./high-cardinality-ordinal.js";
export {default as identityScale} from "./identity-scale.js";
export {default as industryUnemployment} from "./industry-unemployment.js";