如何在特定点获取d3.js图的值?

时间:2019-05-29 16:08:59

标签: d3.js

我有一组图形(使用angular 7和d3.js v5)。 轴x => date,y值,它是一条曲线(基础)。 我希望能够输入日期并在该特定日期显示该值。我的问题是,我看不到如何检索给定日期的计算值。 可能吗? 我什么都没找到。

我添加一张图片进行说明。 enter image description here

感谢您的帮助:)

2 个答案:

答案 0 :(得分:0)

您正在寻找的被称为等分线,而d3具有内置功能。您可以像这样创建一个bisect函数:

const bisectDate = d3.bisector(d=>d.date).right;

然后将其与给定x位置的倒数一起使用。这是有关bisect方法的d3文档:

https://github.com/d3/d3-array#bisectLeft

和d3文档中的反比例尺:

https://github.com/d3/d3-scale#continuous_invert

还有一个折线图的工作示例,该折线图将鼠标x位置平分以获取给定日期的值:

https://bl.ocks.org/alandunning/cfb7dcd7951826b9eacd54f0647f48d3

答案 1 :(得分:-1)

在一般情况下,没有一个简单的答案可以解决

但是,在您的情况下,由于您使用的是基准曲线,并且数据间隔相等,因此可以使用d3基准插值器https://github.com/d3/d3-interpolate#interpolateBasis

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    body {
      margin: 0;
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
    
    path {
      fill: none;
      stroke: black;
    }
    
    rect {
      fill: white;
    }
  </style>
</head>

<body>
  <script>
    var points = [{
        x: 0,
        y: 0
      },
      {
        x: 5,
        y: 10
      },
      {
        x: 10,
        y: 20
      },
      {
        x: 15,
        y: 15
      },
      {
        x: 20,
        y: 5
      },
      {
        x: 25,
        y: 10
      },
      {
        x: 30,
        y: 12
      },
      {
        x: 35,
        y: 5
      },
      {
        x: 40,
        y: 20
      },
    ];

    var interp = d3.interpolateBasis(points.map(function(p) {
      return p.y;
    }));
    var scaleX = d3.scaleLinear()
      .domain([0, 40])
      .range([0, 200]);
    var scaleY = d3.scaleLinear()
      .domain([-10, 30])
      .range([200, 0]);
    var lineGen = d3.line()
      .x(function(d) {
        return scaleX(d.x);
      })
      .y(function(d) {
        return scaleY(d.y);
      })
      .curve(d3.curveBasis);

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

    svg.append('rect')
      .attr('width', 200)
      .attr('height', 200)
      .on('mousemove', function() {
        var x = d3.event.x;
        var y = interp(x / scaleX(40));
        svg.select('circle')
          .attr('cx', x)
          .attr('cy', scaleY(y));
        svg.select('text')
          .text('x: ' + scaleX.invert(x) + ', y: ' + y);
      })

    svg.append('path')
      .attr('d', lineGen(points));

    svg.append('text')
      .attr('y', 20);

    svg.append('circle')
      .attr('r', 3);
  </script>
</body>