如何在D3中的不同行上打印工具提示的内容

How to print content of tooltip on different lines in D3

本文关键字:打印 工具提示 D3      更新时间:2023-09-26

下面是水平堆叠条形图的代码。当我将鼠标悬停在任何栏上时,它会在一行中显示元素的内容。我想添加换行符来分隔数据的每个参数。我尝试寻找这种类型的问题,并发现了带有"tspan"的东西,但这在我的代码中不起作用。请看一看。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="lit" uri="/WEB-INF/......" %>
<!DOCTYPE html>
<meta charset="utf-8">
<head>
  <link rel="stylesheet" media="all" type="text/css" href="<c:url value="/styl........."/>" />
</head>
<body>
<script src="//d3js.org/d3.v3.js"></script>
<script>
var i = 0;
var margins = {
    top: 12,
    left: 48,
    right: 24,
    bottom: 24
},
legendPanel = {
    width: 180
},
width = 1500 - margins.left - margins.right - legendPanel.width,
    height = 900 - margins.top - margins.bottom,
    dataset = ${JSONData},
    series = dataset.map(function (d) {
        return d.name;
    }),
    dataset = dataset.map(function (d) {   
        return d.data.map(function (o) {
            return {
                name: d.name,
                y: +o.count,
                x: o.time
            };
        });
    }),
    stack = d3.layout.stack();
stack(dataset);
var dataset = dataset.map(function (group) {
    return group.map(function (d) {
        return {
            name: d.name,
            x: d.y,
            y: d.x,
            x0: d.y0
        };
    });
}),
    svg = d3.select('body')
        .append('svg')
        .attr('width', width + margins.left + margins.right + legendPanel.width)
        .attr('height', height + margins.top + margins.bottom)
        .append('g')
        .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'),
    xMax = d3.max(dataset, function (group) {
        return d3.max(group, function (d) {
            return d.x + d.x0;
        });
    }),
    xScale = d3.scale.linear()
        .domain([0, xMax])
        .range([0, width]),
    months = dataset[0].map(function (d) {
        return d.y;
    }),
    _ = console.log(months),
    yScale = d3.scale.ordinal()
        .domain(months)
        .rangeRoundBands([0, height], .1),
    xAxis = d3.svg.axis()
        .scale(xScale)
        .orient('bottom'),
    yAxis = d3.svg.axis()
        .scale(yScale)
        .orient('left'),
    colours = d3.scale.category10(),
    groups = svg.selectAll('g')
        .data(dataset)
        .enter()
        .append('g')
        .style('fill', function (d, i) {
        return colours(i);
    }),
    rects = groups.selectAll('rect')
        .data(function (d) {
        return d;
    })
        .enter()
        .append('rect')
        .attr('x', function (d) {
        return xScale(d.x0);
    })
        .attr('y', function (d, i) {
        return yScale(d.y);
    })
        .attr('height', function (d) {
        return yScale.rangeBand();
    })
        .attr('width', function (d) {
        return xScale(d.x);
    })
        .on('mouseover', function (d) {
        var xPos = parseFloat(d3.select(this).attr('x')) / 2 + width/2;
        var yPos = parseFloat(d3.select(this).attr('y')) + yScale.rangeBand() / 2;
        d3.select('#tooltip')
            .style('left', xPos + 'px')
            .style('top', yPos + 'px')
            .select('#value')
            .text("Count: " + d.x + "Time: " + d.y + "String1"+
"'nString2");
            //.text(d.x+","+d.y+","+d.name);        
        d3.select('#tooltip').classed('hidden', false);
    })
        .on('mouseout', function () {
        d3.select('#tooltip').classed('hidden', true);
    })
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(xAxis);
svg.append('g')
    .attr('class', 'axis')
    .call(yAxis);
svg.append('rect')
    .attr('fill', 'yellow')
    .attr('width', 160)
    .attr('height', 30 * dataset.length)
    .attr('x', width + margins.left)
    .attr('y', 0);
series.forEach(function (s, i) {
    svg.append('text')
        .attr('fill', 'black')
        .attr('x', width + margins.left + 8)
        .attr('y', i * 24 + 24)
        .text(s);
    svg.append('rect')
        .attr('fill', colours(i))
        .attr('width', 60)
        .attr('height', 20)
        .attr('x', width + margins.left + 90)
        .attr('y', i * 24 + 6);
});
</script>
<div id="tooltip" class="hidden">
    <p><span id="value">100</span>
    </p>
</div>
</body>
</html>

您的"工具提示"只是一个 HTML span ; 所以你需要做的就是使用.html和换行符的<br>

d3.select('#tooltip')
  .style('left', xPos + 'px')
  .style('top', yPos + 'px')
  .select('#value')
  .html("Count: " + d.x + "Time: " + d.y + " String1" + "<br>String2");

如果您一直在创建 svg text 元素,则需要向其附加多个tspan元素。


完整代码:

<html>
<head>
</head>
<body>
  <script src="//d3js.org/d3.v3.js"></script>
  <script>
    var i = 0;
    var margins = {
        top: 12,
        left: 48,
        right: 24,
        bottom: 24
      },
      legendPanel = {
        width: 180
      },
      width = 1500 - margins.left - margins.right - legendPanel.width,
      height = 900 - margins.top - margins.bottom,
      dataset = [{data:[{
        count: Math.random(),
        time: "One"
      },{
        count: Math.random(),
        time: "Two"
      },{
        count: Math.random(),
        time: "Three"
      }]}];
      series = dataset.map(function(d) {
        return d.name;
      }),
      dataset = dataset.map(function(d) {
        return d.data.map(function(o) {
          return {
            name: d.name,
            y: +o.count,
            x: o.time
          };
        });
      }),
      stack = d3.layout.stack();
    stack(dataset);
    var dataset = dataset.map(function(group) {
        return group.map(function(d) {
          return {
            name: d.name,
            x: d.y,
            y: d.x,
            x0: d.y0
          };
        });
      }),
      svg = d3.select('body')
      .append('svg')
      .attr('width', width + margins.left + margins.right + legendPanel.width)
      .attr('height', height + margins.top + margins.bottom)
      .append('g')
      .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'),
      xMax = d3.max(dataset, function(group) {
        return d3.max(group, function(d) {
          return d.x + d.x0;
        });
      }),
      xScale = d3.scale.linear()
      .domain([0, xMax])
      .range([0, width]),
      months = dataset[0].map(function(d) {
        return d.y;
      }),
      _ = console.log(months),
      yScale = d3.scale.ordinal()
      .domain(months)
      .rangeRoundBands([0, height], .1),
      xAxis = d3.svg.axis()
      .scale(xScale)
      .orient('bottom'),
      yAxis = d3.svg.axis()
      .scale(yScale)
      .orient('left'),
      colours = d3.scale.category10(),
      groups = svg.selectAll('g')
      .data(dataset)
      .enter()
      .append('g')
      .style('fill', function(d, i) {
        return colours(i);
      }),
      rects = groups.selectAll('rect')
      .data(function(d) {
        return d;
      })
      .enter()
      .append('rect')
      .attr('x', function(d) {
        return xScale(d.x0);
      })
      .attr('y', function(d, i) {
        return yScale(d.y);
      })
      .attr('height', function(d) {
        return yScale.rangeBand();
      })
      .attr('width', function(d) {
        return xScale(d.x);
      })
      .on('mouseover', function(d) {
        var xPos = parseFloat(d3.select(this).attr('x')) / 2 + width / 2;
        var yPos = parseFloat(d3.select(this).attr('y')) + yScale.rangeBand() / 2;
        d3.select('#tooltip')
          .style('left', xPos + 'px')
          .style('top', yPos + 'px')
          .select('#value')
          .html("Count: " + d.x + "Time: " + d.y + " String1" + "<br>String2");
        d3.select('#tooltip').classed('hidden', false);
      })
      .on('mouseout', function() {
        d3.select('#tooltip').classed('hidden', true);
      })
    svg.append('g')
      .attr('class', 'axis')
      .attr('transform', 'translate(0,' + height + ')')
      .call(xAxis);
    svg.append('g')
      .attr('class', 'axis')
      .call(yAxis);
    svg.append('rect')
      .attr('fill', 'yellow')
      .attr('width', 160)
      .attr('height', 30 * dataset.length)
      .attr('x', width + margins.left)
      .attr('y', 0);
    series.forEach(function(s, i) {
      svg.append('text')
        .attr('fill', 'black')
        .attr('x', width + margins.left + 8)
        .attr('y', i * 24 + 24)
        .text(s);
      svg.append('rect')
        .attr('fill', colours(i))
        .attr('width', 60)
        .attr('height', 20)
        .attr('x', width + margins.left + 90)
        .attr('y', i * 24 + 6);
    });
  </script>
  <div id="tooltip" class="hidden">
    <p>
      <span id="value">100</span>
    </p>
  </div>
</body>
</html>