D3如何在折线图中找到最后一个点的高度

时间:2016-04-27 10:32:18

标签: d3.js svg linegraph

我是d3的新手,不知何故能够用动画绘制线图如下:

 var lineData = _.first(data.data, 30); // some array of numbers

            var  xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([0, 30]),
              yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([_.min(lineData), _.max(lineData)]);

            var lineFunc = d3.svg.line()
              .x(function(d) {
                return xRange(lineData.indexOf(d));
              })
              .y(function(d) {
                return yRange(d);
              })
              .interpolate('basis');

            var path = vis.append('path')
              .attr('d', lineFunc(lineData))
              .attr('stroke', color)
              .attr('stroke-width', 3)
              .attr('fill', 'none');

            var totalLength = path.node().getTotalLength();

            path
              .attr("stroke-dasharray", totalLength + " " + totalLength)
              .attr("stroke-dashoffset", totalLength)
              .transition()
              .duration(5000)
              .delay(index * 1000)
              .ease("linear")
              .attr("stroke-dashoffset", 0);

现在我想在每行的末尾添加一些文本(表示每行的名称)。 我可以使用以下代码

来做到这一点
vis.append("text")
          .attr("transform", "translate(" + (WIDTH - 15) + "," + 200 + ")")
          .attr("text-anchor", "start")
          .style("fill", "steelblue")
          .text("Close");

现在我的问题是要追加的文本节点必须位于折线图结束的高度(并替换当前硬编码的y = 200)。我无法实现这一目标,请帮助。

1 个答案:

答案 0 :(得分:2)

根据此示例:http://bl.ocks.org/d3noob/8603837

svg.append("text")
        .attr("transform", "translate(" + (width+3) + "," + y(data[0].close) + ")")
        .attr("dy", ".35em")
        .attr("text-anchor", "start")
        .style("fill", "steelblue")
        .text("Close");

所以在你的情况下,从你的小提琴:

我有路径的边界框来计算X转换(得到路径的终点):

 var translateWidth = document.getElementsByClassName("pathLine")[0].getBBox().width;

对于Y转换,我已经将数组的最后一个值传递给yRange,如下所示:

yRange(lineData[lineData.length - 1])

现在你的文字功能如下:

vis.append("text")
    .attr("transform", function(d) {
      return "translate(" + (translateWidth + 50) + "," + yRange(lineData[lineData.length - 1]) + ")"
    })
    .attr("text-anchor", "start")
    .style("fill", "black")
    .text("abc")

注意我已将path的附加内容更改为vis,因为您无法将文本附加到SVG元素,就像您尝试的那样。

更新了小提琴:https://jsfiddle.net/thatOneGuy/dqch1s13/4/

如果需要,可以使用工作代码:

var vis = d3.select('#visualisation'),
  WIDTH = 1000,
  HEIGHT = 400,
  MARGINS = {
    top: 20,
    right: 20,
    bottom: 20,
    left: 50
  };

var drawLine = function(data, color, index) {
  var lineData = data;
  var xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([0, 30]),
    yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([_.min(lineData), _.max(lineData)]);

  var lineFunc = d3.svg.line()
    .x(function(d) {
      return xRange(lineData.indexOf(d));
    })
    .y(function(d) {
      return yRange(d);
    })
    .interpolate('basis');
  console.log(lineData[lineData.length - 1])
  var path = vis.append('path').attr('class', 'pathLine')
    .attr('d', lineFunc(lineData))
    .attr('stroke', function(d) {
      return color
    })
    .attr('stroke-width', 3)
    .attr('fill', 'none');

  var totalLength = path.node().getTotalLength();

  path
    .attr("stroke-dasharray", totalLength + " " + totalLength)
    .attr("stroke-dashoffset", totalLength)
    .transition()
    .duration(5000)
    .delay(index * 1000)
    .ease("linear")
    .attr("stroke-dashoffset", 0);
  console.log(path)
  var translateWidth = document.getElementsByClassName("pathLine")[0].getBBox().width;

  vis.append("text")
    .attr("transform", function(d) {
      return "translate(" + (translateWidth + 50) + "," + yRange(lineData[lineData.length - 1]) + ")"
    })
    .attr("text-anchor", "start")
    .style("fill", "black")
    .text("abc")
};

drawLine([1, 20, 3, 4, 15, 6, 7, 18, 9, 0, 12, 23, 24, 12, 100], 'red', 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<svg id="visualisation" width="1200" height="400" style="position: absolute;left: 50%;transform: translateX(-50%);"></svg>