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

Add ability to stack area charts #9

Open
SamGRosen opened this issue Jun 29, 2021 · 0 comments
Open

Add ability to stack area charts #9

SamGRosen opened this issue Jun 29, 2021 · 0 comments

Comments

@SamGRosen
Copy link
Member

SamGRosen commented Jun 29, 2021

This is a particularly difficult issue, but if implemented properly, it should give a reasonable ability for tracks to render based on each others data. A stacked area chart looks like this. For this implementation, you can assume each track being stacked has all equal x values. The specification of the visualizations will also need some type of way for tracks to label what order they should be stacked in, and if they should ignore the stacking altogether.

In my opinion, I think the feature can be implemented similar to as follows, avoiding major refactoring and still giving isolated behavior in the code.

In webgl-drawer.js.populateBuffers, the iteration outer loop is over tracks while the inner loop is over marks. There could be an if statement in this method for features such as stacking charts where instead the outer loop is over marks, and the inner loop is over tracks (this would assume each track has the same number of points). Then using the lastMark property in the VertexCalculator the vertices could be calculated. Something similar to this (psuedocode):

populateBuffers(schemaHelper) {
  if (regularRender) {
    /////////// EXISTING CODE
    let currentTrack = schemaHelper.getNextTrack();
    let currentTrackShaderIndex = 0;

    this.semanticZoomer = new SemanticZoomer(schemaHelper);

    while (currentTrack) {
      // Construct calculator in track loop as calculator keeps internal state for each track
      let vertexCalculator = new VertexCalculator(
        schemaHelper.xScale,
        schemaHelper.yScale,
        currentTrack.track // Access actual track schema
      );

      let currentMark = currentTrack.getNextMark();

      while (currentMark) {
        // A lot of the heavy lifting occurs in the track shaders, this class is mostly boilerplate for webgl
        this.trackShaders[currentTrackShaderIndex].addMarkToBuffers(
          currentMark,
          vertexCalculator
        );

        currentMark = currentTrack.getNextMark();
      }

      currentTrack = schemaHelper.getNextTrack();
      currentTrackShaderIndex++;
    }

    this.render();
    /////////// END EXISTING CODE
  } else {
    // collect all tracks
    const allTracks = [];
    const allTrackVertexBuilders = [];
    let currentTrack = schemaHelper.getNextTrack();
    while (currentTrack) {
      allTracks.push(currentTrack);
      allTrackVertexBuilders.push(
        new VertexCalculator(
          schemaHelper.xScale,
          schemaHelper.yScale,
          currentTrack
        )
      );
      currentTrack = schemaHelper.getNextTrack();
    }

    let nextMarks = allTracks.map((track) => track.getNextMark());
    while (nextMarks[0]) {
      for (let i = 0; i < nextMarks.length; i++) {
        // This loop is where it gets difficult as you will also need to consider the VertexShader.addMarkToBuffers method
        // ...
        this.trackShaders[currentTrackShaderIndex].addMarkToBuffers(
          ...,
          ...
        );
      }
      let nextMarks = allTracks.map((track) => track.getNextMark());
    }
    this.render();
  }
}

One way of implementing the core loop above is by combining all of the VertexCalculators into one so they can communicate with each other (a new class like ManyVertexCalculator would probably need to be made).

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

No branches or pull requests

1 participant