在d3tip工具提示中嵌入svg形状

时间:2017-06-08 05:47:33

标签: javascript d3.js

我正在使用流行的提示库d3-tip.js,可以找到它的一个示例here。通常,提示包含动态定义的文本,如下所示:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    html = "";
    html += "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
    return html;
  })

但是,假设我有一个这样的传奇:

  var legend = g.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 10)
      .attr("text-anchor", "end")
    .selectAll("g")
    .data(keys.slice().reverse())
    .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

  legend.append("rect")
      .attr("x", width - 19)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", z);

  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9.5)
      .attr("dy", "0.32em")
      .text(function(d) { return d; });

我想以某种方式在d3工具包中添加一个小的svg rect。这样,当您将鼠标悬停在具有不同类别(即分组条形图)的图形上时,除了html文本之外,工具提示将具有匹配颜色的svg矩形。理想情况下,使用现有的图例变量,如上所示。

如果不可能,那就解释一下原因,我也可以接受这个答案。

为了清楚起见,这里是我对视觉效果的粗略概念: enter image description here

1 个答案:

答案 0 :(得分:1)

d3.tip工具提示中创建SVG很容易。实际上,你只需要使用与任何其他D3创建的SVG相同的逻辑:选择容器并将SVG附加到它。

在以下演示中,在var tip中,我将创建一个具有给定ID的空div。在这种情况下,div具有名为mySVGtooltip

的ID
var tool_tip = d3.tip()
    .attr("class", "d3-tip")
    .offset([20, 40])
    .html("<div id='mySVGtooltip'></div>");

之后,只需要在mouseover事件中,按ID选择div并将SVG附加到其中:

var legendSVG = d3.select("#mySVGtooltip")
    .append("svg")
    .attr("width", 160)
    .attr("height", 50);

这是演示,将鼠标悬停在圈子上:

&#13;
&#13;
var svg = d3.select("body")
  .append("svg")
  .attr("width", 300)
  .attr("height", 300);

var tool_tip = d3.tip()
  .attr("class", "d3-tip")
  .offset([20, 40])
  .html("<div id='mySVGtooltip'></div>");

svg.call(tool_tip);

var data = [20, 10, 30, 15, 35];

var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle");

circles.attr("cy", 50)
  .attr("cx", function(d, i) {
    return 30 + 55 * i
  })
  .attr("r", function(d) {
    return d
  })
  .attr("fill", "lightgreen")
  .attr("stroke", "dimgray")
  .on('mouseover', function(d) {
    tool_tip.show();
    var legendSVG = d3.select("#mySVGtooltip")
      .append("svg")
      .attr("width", 160)
      .attr("height", 50);

    var legend = legendSVG.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 10);
      
      legend.append("text")
      .attr("x", 80)
      .attr("text-anchor", "middle")
      .attr("y", 16)
      .attr("font-size", 14)
      .text("Age Group:");

    legend.append("rect")
    	.attr("y", 25)
      .attr("x", 10)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", "goldenrod");

    legend.append("text")
      .attr("x", 35)
      .attr("y", 40)
      .text(function() {
        return d + " years and over";
      });
  })
  .on('mouseout', tool_tip.hide);
&#13;
.d3-tip {
  line-height: 1;
  background: gainsboro;
  border: 1px solid black;
  font-size: 12px;
}

p {
  font-family: Helvetica;
}
&#13;
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>
&#13;
&#13;
&#13;

请注意,在这个非常简单的演示中,我使用d事件传递给匿名函数的数据(mouseover)。我在你的问题中看到你有自己的数据。因此,相应地更改我的演示中的代码。