D3.js:工具提示问题

D3.js: Tool tip Issue

本文关键字:问题 工具提示 js D3      更新时间:2023-09-26

我是D3.js的新手。我在一些圆圈周围工作,并尝试为我的圆圈提供工具提示。当我使用tooltip.html时,我得到的是undefined而不是值。此外,如何将工具提示直接放置在圆圈顶部?

var thedata= [];
d3.tsv('data.tsv', function(data){
data.forEach(function(d){
    thedata.push(d.value);
})
var margin = {top :30, right: 30, bottom: 40, left: 50}
var height = 400,
    width = document.getElementById('chart').clientWidth;
colors = d3.scale.linear()
.domain([0,  thedata.length])
.range(['#6baed6','#31a354'])
var tooltip = d3.select('body').append('div')
        .style('position', 'absolute')
        .style('padding', '0 7px')
        .style('background', 'black')
        .style('opacity', 0)
        .style('border', '2px solid teal')
        .style('border-radius', '2px')
var xScale = d3.scale.ordinal()
        .domain(d3.range(0, thedata.length))
        .rangePoints([0, width],1)
var myChart = d3.select('#chart').append('svg')
    .style('background','#E7E0CB')
    .attr('width', width)
    .attr('height', height)
    .selectAll('circle').data(thedata)
    .enter().append('g')
        .attr('class', 'labe')
    var cir = d3.selectAll('g.labe')
    .append('circle')
    .style('fill', function(d,i) {
            return colors(i);
    })
    .attr('cx',function(d,i){ 
         return xScale(i);
    })
    .attr('cy', function(d, i){
          return (height/2);
    })
    .attr('r', function(d){
      return 35*(d);
    })
    .attr('fill', function(d,i){
      return colors(i);
    })
    .on('mouseover', function(d) {
    tooltip.transition()
            .style('opacity', .85)
    tooltip.html( function (d, i){
        return "<strong style = 'color:white'>Significance:</strong> <span style='color:red'>" + d + "</span>";
    })
            .style('left', (d3.event.pageX + 15) + 'px')
            .style('top',  (d3.event.pageY - 34*d) + 'px')

    tempColor = this.style.fill;
        d3.select(this)
            .style('fill', '#595AB7')
   })
    .on('mouseout', function(d) {
        tooltip.transition()
            .style('opacity', 0)        
            d3.select(this)
            .style('opacity', 1)
            .style('fill', tempColor)
    })
    var text = d3.selectAll('g.labe')
        .append('text')
        .data(data)
        .text(function(d , i){
            return d.domain;
        })
        .attr('fill', palette.darkgray)
        .attr('text-anchor', 'middle')
        .attr("transform", function(d, i) {
             // Set d.x and d.y here so that other elements can use it. d is 
             // expected to be an object here.
             d.x =xScale(i),
             d.y = (3*height / 4+10);
             return "translate(" + d.x + "," + d.y + ")"; 
           });
        var ease = d3.ease('elastic')
});

这是数据.tsv:

value   domain
17142857    Increment
2857143 Timber
115310  Fruits

.html调用中,您不需要额外的function(d,i)包装器:

tooltip.html("<strong style = 'color:white'>Significance:</strong> <span style='color:red'>" + d.value + "</span>")

注意,我也在使用d.value,因为d在这个上下文中是一个对象。

对于你的位置问题,你正在d上做数学运算(同样,这是一个对象)。不确定你在追求什么,但这个:

      .style('left', (d3.event.pageX + 'px'))
      .style('top', (d3.event.pageY - 34) + 'px')

编辑

要放置在圆圈的顶部,请执行与放置圆圈相同的数学运算:

.style('left', xScale(i) + "px")
.style('top', (height / 2) - (0.035 * (+d.value))  + 'px') // circle placement - radius

工作代码:

<!DOCTYPE html>
<html>
<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
  <script>
    var thedata = [{
      "value": "1714",
      "domain": "Increment"
    }, {
      "value": "2857",
      "domain": "Timber"
    }, {
      "value": "1153",
      "domain": "Fruits"
    }];
    var margin = {
      top: 30,
      right: 30,
      bottom: 40,
      left: 50
    }
    var height = 400,
      width = 500;
    colors = d3.scale.linear()
      .domain([0, thedata.length])
      .range(['#6baed6', '#31a354'])
    var tooltip = d3.select('body').append('div')
      .style('position', 'absolute')
      .style('padding', '0 7px')
      .style('background', 'black')
      .style('opacity', 0)
      .style('border', '2px solid teal')
      .style('border-radius', '2px')
    var xScale = d3.scale.ordinal()
      .domain(d3.range(0, thedata.length))
      .rangePoints([0, width], 1)
    var myChart = d3.select('body').append('svg')
      .style('background', '#E7E0CB')
      .attr('width', width)
      .attr('height', height)
      .selectAll('circle').data(thedata)
      .enter().append('g')
      .attr('class', 'labe')
    var cir = d3.selectAll('g.labe')
      .append('circle')
      .style('fill', function(d, i) {
        return colors(i);
      })
      .attr('cx', function(d, i) {
        return xScale(i);
      })
      .attr('cy', function(d, i) {
        return (height / 2);
      })
      .attr('r', function(d) {
        console.log(d.value);
        return 0.035*(+d.value); 
      })
      .attr('fill', function(d, i) {
        return colors(i);
      })
      .on('mouseover', function(d, i) {
        tooltip.transition()
          .style('opacity', .85)
        tooltip.html("<strong style = 'color:white'>Significance:</strong> <span style='color:red'>" + d.value + "</span>")
          .style('left', xScale(i) + "px")
          .style('top', (height / 2) - (0.035 * (+d.value))  + 'px')
        tempColor = this.style.fill;
        d3.select(this)
          .style('fill', '#595AB7')
      })
    .on('mouseout', function(d) {
      tooltip.transition()
        .style('opacity', 0)
      d3.select(this)
        .style('opacity', 1)
        .style('fill', tempColor)
    })
    var text = d3.selectAll('g.labe')
      .append('text')
      .data(thedata)
      .text(function(d, i) {
        return d.domain;
      })
      //.attr('fill', palette.darkgray)
      .attr('text-anchor', 'middle')
      .attr("transform", function(d, i) {
        // Set d.x and d.y here so that other elements can use it. d is 
        // expected to be an object here.
        d.x = xScale(i),
          d.y = (3 * height / 4 + 10);
        return "translate(" + d.x + "," + d.y + ")";
      });
    var ease = d3.ease('elastic')
  </script>
</body>
</html>