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

curveHorizontal, curveVertical? #113

Open
jeffsf opened this issue Jan 25, 2018 · 3 comments
Open

curveHorizontal, curveVertical? #113

jeffsf opened this issue Jan 25, 2018 · 3 comments

Comments

@jeffsf
Copy link

jeffsf commented Jan 25, 2018

In working with discrete-time and discrete-level data, I find that the risers in the data can end up being visually deceptive, especially where there is a single-level change involved. Use of a collection of "dots" appears to be much slower to render than the path used by d3.line, to the point of making scrolling and zooming even on a desktop browser rough, and nearly impossible on a phone.

From a presentation standpoint, the dot is "fine" -- it is just the performance problems, especially as mobile monitoring of the time series is a primary use case.

With d3.curveStep:
image

With drawing a dot:
image

At least for me, the visual impression of how many samples are at the median vs. high/low over a segment of time is very different between the two representations.

(Using d3.line has similar challenges with the near-vertical connectors as d3.curveStep has with the risers.)

On a desktop, the dataset-size limit is around 1000-1500 dots before the re-draw times introduce so much lag as to make scroll/zoom frustrating. (There are three other d3.line data sets as well on the graph, but it is the dots that dramatically slow the re-draw time)

@jeffsf
Copy link
Author

jeffsf commented Jan 25, 2018

Creating a "custom" line type based on step.js resulted in the kind of display I was looking for (after adjusting line width and adding line caps) and a very significant improvement in draw time (from 50-100 ms down to 15-20 ms)

I'm not sure if/how you would want to incorporate this, as well as for anyone that finds this through search, the overridden point: I'm using is

  point: function(x, y) {
    x = +x, y = +y;
    switch (this._point) {
      case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
      case 1: this._point = 2; // proceed
      default: {
        if (this._t <= 0) {
          this._context.moveTo(this._x, y);
          this._context.lineTo(x, y);
        } else {
          var x1 = this._x * (1 - this._t) + x * this._t;
          this._context.lineTo(x1, this._y);
          this._context.moveTo(x1, y);
        }
        break;
      }
    }
    this._x = x, this._y = y;
  }

(only two changes; replacing lineTo with moveTo)

image

@mbostock mbostock changed the title Step without "risers" curveHorizontal, curveVertical? Nov 16, 2019
@mbostock
Copy link
Member

I propose we call this “curveHorizontal”, and include a curveVertical for the vertically-oriented equivalent.

@Fil
Copy link
Member

Fil commented Jul 1, 2020

About the "collection of dots" there is also the curvePoints proposal #154

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants