首页 > 解决方案 > 如何在鼠标指针上方显示 SVG 的条形长度(以 px 为单位)

问题描述

我想在鼠标指针上方显示以 px 乘以 2 的条形长度。

我尝试过var txt = svg.append("text"),然后 txt.text(distance);但最终出现错误。

我如何需要编辑以下代码,以便 barlength*2 在 barlength 增加时同时显示在鼠标指针上方?

px 长度 * 2 应显示在鼠标指针上方,并停留在鼠标停止单击的位置,例如:

在此处输入图像描述

到目前为止,代码有效:

function stretch(brush) {
  var xy0, bluebar, stay = false,
    bar = d3.svg.line().x(function(d) {
      return d[0];
    }).y(function(d) {
      return d[1];
    });

  brush.on('mousedown', function() {
    stay = true;
    xy0 = d3.mouse(this);
    bluebar = d3.select('svg').append('path').attr('d', bar([xy0, xy0])).style({
      'stroke': 'lightblue',
      'stroke-width': '50px'
    });

  }).on('mouseup', function() {
    stay = false;
  }).on('mousemove', function() {
    if (stay) {
      Bar = bar([xy0, d3.mouse(this).map(function(x) {
        return x - 1;
      })]);

      bluebar.attr('d', Bar);
    }
  });
}
d3.select('body').append('svg').call(stretch);
<script src="https://d3js.org/d3.v3.min.js"></script>

标签: javascripthtmlsvgd3.js

解决方案


我对您的代码进行了一些更新:

  • 为文本元素添加一个新变量
  • 创建文本元素mousedown但尚未添加文本
  • 更新文本元素位置 on并根据和mousemove之间的距离计算标签文本,然后对标签位置进行微调xy0xy1

细化标签相对于指针的方向以及指针是否在左/右、上/下拖动;您可以使用dxdy属性,我刚刚为示例的目的硬编码了一些合理的东西。

function stretch(brush) {
  var foo; // variable for text element
  var xy0, bluebar, stay = false,
    bar = d3.svg.line().x(function(d) {
      return d[0];
    }).y(function(d) {
      return d[1];
    });

  brush.on('mousedown', function() {
    stay = true;
    xy0 = d3.mouse(this);
    bluebar = d3.select('svg').append('path').attr('d', bar([xy0, xy0])).style({
      'stroke': 'lightblue',
      'stroke-width': '50px'
    });
    // append the element but no actual text
    foo = d3.select('svg')
      .append('text')
      .attr('x', xy0[0])
      .attr('y', xy0[1])
      .text(""); // start with no text

  }).on('mouseup', function() {
    stay = false;
  }).on('mousemove', function() {
    if (stay) {
      // new point
      var xy1 = d3.mouse(this).map(function(x) {
        return x - 1;
      }); 
      // your code to draw the bar
      Bar = bar([xy0, xy1]);
      bluebar.attr('d', Bar);
      
      // formula for distance between two points (for text)
      var dx = Math.abs(xy1[0] - xy0[0]);
      var dy = Math.abs(xy1[1] - xy0[1]);
      var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));

      // move and calculate the text
      foo.attr('x', xy1[0])
        .attr('y', xy1[1])
        .text((d * 2).toFixed(0) + "px");
        
      // orient the label 
      if (xy1[0] >= xy0[0]) {
        foo.attr('dx', '0.35em');
      } else {
        foo.attr('dx', '-2.35em');
      }
      if (xy1[1] < xy0[1]) {
        foo.attr('dy', '0em');
      } else {
        foo.attr('dy', '0.75em');
      }
    }
  });
}
d3.select('body').append('svg').call(stretch);
<script src="https://d3js.org/d3.v3.min.js"></script>


推荐阅读