d3.js自定义曲线步进 [英] d3.js custom curve step round

查看:84
本文介绍了d3.js自定义曲线步进的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有x和y轴的d3.js .v4图形,需要您的帮助.

I'm working on d3.js .v4 graph with x and y axis and I need your help.

说明:

xAxis是线性缩放的,并且像上面的图像一样具有路径.

xAxis is linear scaled with path on it like this image.

我被困在这里,无法找到解决方案来制作类似于此图像的路径路径为圆角

I'm stuck here and can't find solution to make path like on this image path with rounded corner

这是我的行函数代码

    // the path generator for the line chart
line = d3.line()
  .x(function(d, i) {
    return xScale(i);
  })
  .y(function(d, i) {
    return yScale(d);
  })
  .curve(d3.curveStep);

我尝试使用基数,单调和catmull,但是无法归档所需的路径.

I tried with cardinal, monotone and catmull buth can't archive desired path.

是否可以在d3.curveStep上圆角?

Is it possible to round corners on d3.curveStep?

推荐答案

我终于找到了可以重提这个问题的时间.这是实现自定义曲线的绝佳机会.我基本上将源代码偷到了 d3.curveStepBefore 并进行修改以符合您的要求.

I finally found sometime to comeback to this question. This is a great opportunity to implement a custom curve. I essentially stole the source code to d3.curveStepBefore and modified to fit your requirements.

function Step(context, t) {
  this._context = context;
  this._t = t;
}

Step.prototype = {
  areaStart: function() {
    this._line = 0;
  },
  areaEnd: function() {
    this._line = NaN;
  },
  lineStart: function() {
    this._x = this._y = NaN;
    this._point = 0;
  },
  lineEnd: function() {
    if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
    if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
  },
  point: function(x, y) {
    x = +x, y = +y;
    switch (this._point) {
      case 0:
      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:
        {
          var xN, yN, mYb, mYa;
          if (this._t <= 0) {
            xN = Math.abs(x - this._x) * 0.25;
            yN = Math.abs(y - this._y) * 0.25;
            mYb = (this._y < y) ? this._y + yN : this._y - yN;
            mYa = (this._y > y) ? y + yN : y - yN;

            this._context.quadraticCurveTo(this._x, this._y, this._x, mYb);
            this._context.lineTo(this._x, mYa);
            this._context.quadraticCurveTo(this._x, y, this._x + xN, y);
            this._context.lineTo(x - xN, y);

          } else {
            var x1 = this._x * (1 - this._t) + x * this._t;

            xN = Math.abs(x - x1) * 0.25;
            yN = Math.abs(y - this._y) * 0.25;
            mYb = (this._y < y) ? this._y + yN : this._y - yN;
            mYa = (this._y > y) ? y + yN : y - yN;

            this._context.quadraticCurveTo(x1, this._y, x1, mYb);
            this._context.lineTo(x1, mYa);
            this._context.quadraticCurveTo(x1, y, x1 + xN, y);
            this._context.lineTo(x - xN, y);
          }
          break;
        }
    }
    this._x = x, this._y = y;
  }
};

stepRound = function(context) {
  return new Step(context, 0.5);
};

stepRoundBefore = function(context) {
  return new Step(context, 0);
};

stepRoundAfter = function(context) {
  return new Step(context, 1);
};

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>

<body>
  <script>
    document.addEventListener("DOMContentLoaded", function(event) {

      var width = 500,
        height = 500,
        N = 10;

      var svg = d3.select('body')
        .append('svg')
        .attr('width', width)
        .attr('height', height);

      var points = [];
      for (var i = 0; i < N; i++) {
        points.push({
          x: (width / N) * i + (width / N / 2),
          y: Math.random() * height
        });
      }

      var line1 = d3.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .curve(stepRound);

      var line2 = d3.line()
        .x(function(d) {
          return d.x;
        })
        .y(function(d) {
          return d.y;
        })
        .curve(d3.curveStep);

      svg.append('path')
        .datum(points)
        .attr('d', line1)
        .attr('fill', 'none')
        .attr('stroke', 'orange')
        .attr('stroke-width', '3px');

      svg.append('path')
        .datum(points)
        .attr('d', line2)
        .attr('fill', 'none')
        .attr('stroke', 'steelblue')
        .attr('stroke-width', '1px');

    });
  </script>
</body>

</html>

这篇关于d3.js自定义曲线步进的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆