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 @@ +
+ + + + + 0 + + + 5 + + + 10 + + + 15 + + + 20 + Proportion of each facet (%) + + + + + + 35 + + + 40 + + + 45 + + + 50 + + + 55 + ↑ culmen_length_mm + + + + FEMALE + + + MALE + + + + sex + + + + 14 + + + 16 + + + 18 + + + 20 + + + + + 14 + + + 16 + + + 18 + + + 20 + + + + + 14 + + + 16 + + + 18 + + + 20 + culmen_depth_mm → + + + + + + 0.067 + + + 0.055 + + + 0.048 + + + 0.048 + + + 0.042 + + + 0.042 + + + 0.042 + + + 0.036 + + + 0.036 + + + 0.03 + + + 0.03 + + + 0.03 + + + 0.03 + + + 0.024 + + + 0.024 + + + 0.024 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + + + + + + 0.083 + + + 0.065 + + + 0.048 + + + 0.042 + + + 0.042 + + + 0.03 + + + 0.03 + + + 0.03 + + + 0.03 + + + 0.024 + + + 0.024 + + + 0.024 + + + 0.024 + + + 0.024 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.018 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.012 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + 0.006 + + + + + + + + 0.182 + + + 0.091 + + + 0.091 + + + 0.091 + + + 0.091 + + + 0.091 + + + 0.091 + + + 0.091 + + + +
\ 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 @@ +
+
+ + + FEMALE + + MALE +
+ + + + + 34 + + + + 36 + + + + 38 + + + + 40 + + + + 42 + + + + 44 + + + + 46 + + + + 48 + + + + 50 + + + + 52 + + + + 54 + + + + 56 + + + + 58 + ↑ culmen_length_mm + + + + + 14 + + + + 15 + + + + 16 + + + + 17 + + + + 18 + + + + 19 + + + + 20 + + + + 21 + culmen_depth_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ 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 @@ + + + + + 35 + + + 40 + + + 45 + + + 50 + + + 55 + ↑ culmen_length_mm + + + + FEMALE + + + MALE + + + + sex + + + + 15 + + + 20 + + + + + 15 + + + 20 + + + + + 15 + + + 20 + culmen_depth_mm → + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 729103256610131211311412281224113111611124149142111 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 18212131514179311224111293442123113171034964311112221121 + + + + + + + + + + + + + + 11211111 + + \ 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";