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

hexbin as a transform #804

Closed
wants to merge 1 commit into from
Closed

Conversation

Fil
Copy link
Contributor

@Fil Fil commented Mar 11, 2022

am i on the right track?

(I can't see how to access Z )

@Fil Fil requested a review from mbostock March 11, 2022 14:31
@Fil Fil mentioned this pull request Mar 11, 2022
16 tasks
@mbostock
Copy link
Member

I don’t think this approach will work… it’ll lead to the same duplicate computation of channels problem we had in the mbostock/layout branch. I need to think about this more.

@mbostock
Copy link
Member

I think probably the hexbin will need to declare a transform, too, and redefine any channels that are needed by outputs so that they are cached. It can then reference those values in the initializer.

@mbostock
Copy link
Member

To elaborate, I think we’ll need something more like this:

{
  const z = "species";
  const [Z, setZ] = Plot.channel(z);
  return Plot.plot({
    grid: true,
    marks: [
      Plot.dot(penguins, {
        x: "culmen_depth_mm",
        y: "culmen_length_mm",
        z: Z, // optionally make the z channel available to dot (no effect here)
        symbol: "hexagon",
        transform(data, facets) {
          setZ(Plot.valueof(data, z)); // compute the z channel from the data
          return {data, facets};
        },
        initialize([index], {x: {value: X}, y: {value: Y}}, {x, y}) {
          console.log(Z.transform()); // access the previously-computed z values
          const bins = Hexbin().x(i => x(X[i])).y(i => y(Y[i])).radius(20)(index);
          return {
            facets: [d3.range(bins.length)],
            channels: {
              x: {value: bins.map(bin => bin.x)},
              y: {value: bins.map(bin => bin.y)},
              r: {value: bins.map(bin => bin.length), radius: 20, scale: "r"}
            }
          };
        }
      })
    ]
  });
}

To break it down:

  1. The options transform would (optionally) declare the z channel as a “lazy” channel via Plot.channel.
  2. The mark transform would compute the z channel. (This part is composable with other transforms.)
  3. The mark initializer could then access the previously-computed z channel values.

Because the channels are computed in a mark transform, they’ll have access to the (possibly transformed) data, so we won’t need to pass that data separately to the initializer. And because the options transform can declare the channel as an option, it won’t be computed twice.

@Fil
Copy link
Contributor Author

Fil commented Mar 22, 2022

superseded by #810 #819

@Fil Fil closed this Mar 22, 2022
@Fil Fil deleted the fil/reinitialize-hexbin branch March 22, 2022 11:23
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.

2 participants