diff --git a/README.md b/README.md index 9512711e57..5420d6c173 100644 --- a/README.md +++ b/README.md @@ -642,7 +642,7 @@ If the **x** channel is not specified, dots will be horizontally centered in the The **r** option defaults to three pixels and can be specified as either a channel or constant. When the radius is specified as a number, it is interpreted as a constant; otherwise it is interpreted as a channel. Dots with a nonpositive radius are not drawn. The **stroke** defaults to none. The **fill** defaults to currentColor if the stroke is none, and to none otherwise. The **strokeWidth** defaults to 1.5. -Dots are drawn in input order, with the last data drawn on top. If sorting is needed, say to mitigate overplotting by drawing the smallest dots on top, consider a [sort and reverse transform](#transforms). +Dots are drawn in input order, with the last data drawn on top. If sorting is needed, consider a [sort and reverse transform](#transforms). The **sortedMark** option, if set to true, will sort the dots in descending radius order, a common approach to mitigate overplotting by drawing the smallest dots on top. #### Plot.dot(*data*, *options*) diff --git a/src/marks/dot.js b/src/marks/dot.js index 33158bfc10..ab05b17df5 100644 --- a/src/marks/dot.js +++ b/src/marks/dot.js @@ -11,7 +11,7 @@ const defaults = { export class Dot extends Mark { constructor(data, options = {}) { - const {x, y, r} = options; + const {x, y, r, sortedMark = false} = options; const [vr, cr] = maybeNumber(r, 3); super( data, @@ -24,6 +24,7 @@ export class Dot extends Mark { defaults ); this.r = cr; + this.sortedMark = !!sortedMark; } render( I, @@ -33,7 +34,12 @@ export class Dot extends Mark { ) { const {x: X, y: Y, r: R} = channels; let index = filter(I, X, Y); - if (R) index = index.filter(i => positive(R[i])); + if (R) { + index = index.filter(i => positive(R[i])); + if (this.sortedMark) { + index = index.sort((i, j) => R[j] - R[i]); + } + } return create("svg:g") .call(applyIndirectStyles, this) .call(applyTransform, x, y, 0.5, 0.5) diff --git a/test/output/penguinSexMassCulmenSpecies.svg b/test/output/penguinSexMassCulmenSpecies.svg index 7f4a7d24c6..dac9f50dc8 100644 --- a/test/output/penguinSexMassCulmenSpecies.svg +++ b/test/output/penguinSexMassCulmenSpecies.svg @@ -163,49 +163,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - @@ -213,54 +213,55 @@ - - - - + - - - - + + + + + + + + + + + + + - - - - - - - - - - + + + + + - - - - - - - - - + + + + + + + + - + + @@ -268,7 +269,6 @@ - diff --git a/test/plots/penguin-sex-mass-culmen-species.js b/test/plots/penguin-sex-mass-culmen-species.js index 0978ca81e4..5c171d1553 100644 --- a/test/plots/penguin-sex-mass-culmen-species.js +++ b/test/plots/penguin-sex-mass-culmen-species.js @@ -25,7 +25,8 @@ export default async function() { y: "culmen_length_mm", stroke: "species", fill: "species", - fillOpacity: 0.1 + fillOpacity: 0.5, + sortedMark: true })) ] });