d3 / d3-shape

Graphical primitives for visualization, such as lines and areas.
https://d3js.org/d3-shape
ISC License
2.47k stars 305 forks source link

curveBump? #152

Closed mbostock closed 3 years ago

mbostock commented 4 years ago

As in for bump charts. Like d3.linkHorizontal, but as a curve. Maybe d3.curveLinkHorizontal is a better name? Or d3.curveSankeyHorizontal? Here’s an implementation that works for lines:

function curveBump(context) {
  let _point, _x, _y;
  return {
    lineStart() {
      _point = 0;
    },
    lineEnd() {
      _point = NaN;
    },
    point(x, y) {
      if (++_point === 1) context.moveTo(x, y);
      else _x = (_x + x) / 2, context.bezierCurveTo(_x, _y, _x, y, x, y);
      _x = x, _y = y;
    }
  }
}
mbostock commented 3 years ago

This works for area, too:


function curveBump(context) {
  let line, point, x0, y0;
  return {
    areaStart() {
      line = 0;
    },
    areaEnd() {
      line = NaN;
    },
    lineStart() {
      point = 0;
    },
    lineEnd() {
      if (line || (line !== 0 && point === 1)) context.closePath();
      line = 1 - line;
    },
    point(x, y) {
      x = +x, y = +y;
      switch (point) {
        case 0: {
          point = 1;
          if (line) context.lineTo(x, y);
          else context.moveTo(x, y);
          break;
        }
        case 1: point = 2; // proceed
        default: {
          x0 = (x0 + x) / 2;
          context.bezierCurveTo(x0, y0, x0, y, x, y);
          break;
        }
      }
      x0 = x, y0 = y;
    }
  }
}