Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mark initializers #801

Merged
merged 36 commits into from
May 28, 2022
Merged

mark initializers #801

merged 36 commits into from
May 28, 2022

Conversation

mbostock
Copy link
Member

@mbostock mbostock commented Mar 10, 2022

This introduces a concept of a mark “initializer” which is allowed to redefine the mark’s (possibly faceted) index and channels, and by extension, the plot’s scales. The mark’s initialize option is a function that is passed the facets and channels returned previously by mark.initialize, and returns an object which may specify new facets and channels. This PR includes an example of implementing hexbins as an initializer. This is a refinement of the previous design of “layouts” #648 #711 #713 #740 #775; I wanted to move away from the term “layout” since it implies position whilst initializers are more generic. But I am open to going back to “layout” or other alternatives.

Building on #799, this also makes a few improvements to internal APIs:

  • mark.initialize now returns a {facets, channels} object rather than {index, channels} (like transforms).
  • channels are now represented as an object e.g. {x: {value}} rather than an array ["x", {value}].

While it is possible to call mark.initialize externally and hence this could be considered a backwards-incompatible change, this method is undocumented so I think it is acceptable to make this change. Also, it is now more convenient for debugging.

TODO:

  • Throw an error if initializers define new positional (x and y) scaled channels? Not going to worry about it.
  • When initializers return new scaled channels, merge with existing scaled channels when reconstructing scales.
  • Add hexagon symbol.
  • Decide on the definition of radius for hexagons.
  • Add hexgrid decoration mark.
  • Add circle and hexagon dot shorthand.
  • Implement the hexbin transform as an initializer (including support for faceting).
  • Implement the filter option for the hexbin transform (to show empty hexbins)? Not now.
  • Implement implicit group by z in the hexbin transform? z hexbins #810
  • Implement sorting of hexbins? z hexbins #810
  • Is radius the right name of the option that controls hexbin size? binWidth? z hexbins #810
  • Inline and optimize the implementation of d3-hexbin z hexbins #810
  • Implement the dodge transform as an initializer. dodge #809
  • Add documentation. document layouts (as "scale-aware transforms") #819
  • Add tests. z hexbins #810
  • Allow composition/chaining of initializers? exploring initializers composition #818

@mbostock mbostock requested a review from Fil March 10, 2022 23:44
@mbostock mbostock force-pushed the mbostock/reinitialize branch 9 times, most recently from 87c8e42 to 7a47351 Compare March 11, 2022 04:26
@Fil
Copy link
Contributor

Fil commented Mar 11, 2022

#803 for the radius of hexagons

@Fil
Copy link
Contributor

Fil commented Mar 11, 2022

#804 tries to implement hexbin as an options transform (adding an initializer)

@mbostock mbostock force-pushed the mbostock/reinitialize branch from 4176c9a to 4a1e110 Compare March 11, 2022 21:00
@mbostock mbostock mentioned this pull request Mar 11, 2022
src/transforms/hexbin.js Outdated Show resolved Hide resolved
@Fil
Copy link
Contributor

Fil commented Mar 14, 2022

Re: the name radius, I scoured the documentation of other libraries quickly and found that (I may have missed some information):

  • matplotlib, pandas, holoviz use gridsize which can be given two numbers (integers?) to set the correct aspect-ratio. The numbers represent the actual number of hexagons in the x and y dimensions.
  • bokeh uses size (in data space) and aspect_scale.
  • ggplot2 uses binwidth (a 2d vector in data space); and defaults to nice ticks in data space.

In that regard, Plot's approach of binning in screen space is rather unique (and imho preferable).

(Note that some of these libs also offer a choice of orientation (pointy-top vs flat-top); we could do arbitrary orientation.)

Overall this doesn't tell us which name to use if we want to move away from radius—only a few names to avoid :)

@Fil Fil mentioned this pull request Mar 14, 2022
@Fil
Copy link
Contributor

Fil commented Mar 15, 2022

Still on the todo-list

  • "filter: null" (not actually a filter, it means we'll have to actively enumerate the centers)

Ready:

This was referenced Mar 18, 2022
@Fil
Copy link
Contributor

Fil commented Mar 21, 2022

Browsed a base of synonyms, here are a few words that could replace layout:

design, layout, encoding/encode, variation/variant, derivation, profile, blueprint, organization, plan, outline, formation, pattern, construction, structure, disposition, makeup, skeleton, anatomy, architecture, stencil, markings, mold, cast, stamp, arrangement/arrange.

In bold a few of the ones that could "work".

@Fil
Copy link
Contributor

Fil commented Mar 21, 2022

For the hexbin radius, another name could be the step (ie distance between neighboring hex centers); however in that case it should be sqrt(3) times the current radius. But it might be easier to explain!

@Fil
Copy link
Contributor

Fil commented Mar 22, 2022

For composition of initializers, see #818

@Fil
Copy link
Contributor

Fil commented Mar 22, 2022

I've added refs to several pull-requests in the original description.

src/plot.js Outdated Show resolved Hide resolved
@Fil Fil mentioned this pull request Mar 24, 2022
@mbostock mbostock mentioned this pull request Apr 14, 2022
@mbostock mbostock force-pushed the mbostock/reinitialize branch 2 times, most recently from b305131 to 886615b Compare May 4, 2022 22:26
src/transforms/basic.js Outdated Show resolved Hide resolved
@mbostock mbostock marked this pull request as ready for review May 28, 2022 05:51
@mbostock
Copy link
Member Author

I have extensively reviewed (and amended) this PR and plan on merging tomorrow. If anyone wishes to make any final words before I merge please speak now! 🙏

@mbostock
Copy link
Member Author

We should probably draw the axes on top? Although the grid lines should still be underneath…

untitled (23)

@Fil
Copy link
Contributor

Fil commented May 28, 2022

draw the axes on top?

This should be a generic issue (in my view the axes should be displayed on top of areas and below lines… which is neither top nor bottom). Also we could use clip: true in this example.

@mbostock
Copy link
Member Author

I’ve reverted the default sort by descending r for the hexbin transform because it feels like it should be handled more appropriately at the dot mark level, or possibly at the generic mark level. And in a sense it is already by the basic sort transform, but that isn’t supported after an initializer, and maybe we want to have default sorting for dots, too.

@mbostock mbostock merged commit 87a0deb into main May 28, 2022
@mbostock mbostock deleted the mbostock/reinitialize branch May 28, 2022 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants