如何高亮D3词云中的一组词

How to highlight an array of words in D3 word cloud

我想突出显示我想要的一组新词,例如"salmon"和"prey"提供给我的词云,那么我应该怎么做,因为我尝试将 mark.js 或 Javascript 与 CSS 一起使用但无法成功,但现在我认为只有在我在画词云。那么有人可以帮我提供一个函数或者我的代码中的一些更改来突出显示单词数组 (arrayToBeHighlight):

var width = 750, height = 500;
var words = [["whales", 79], ["salmon", 56], ["Chinook", 30], ["book", 70],
["prey", 51]].map(function(d) {
    return {text: d[0], size: d[1]}; 
});

var arrayToBeHighlight = [ ["salmon", 56], ["prey", 51] ];
**OR**
var arrayToBeHighlight = ["salmon", "prey"];

maxSize = d3.max(words, function(d) { return d.size; });
minSize = d3.min(words, function(d) { return d.size; });

var fontScale = d3.scale.linear().domain([minSize, maxSize]).range([10,70]);

var fill = d3.scale.category20();
d3.layout.cloud().size([width, height]).words(words).font("Impact")
.fontSize(function(d) { return fontScale(d.size) })
.on("end", drawCloud).start();

function drawCloud(words) {
d3.select("#wordCloud").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + (width / 2) + "," + (height / 2) +")")
  .selectAll("text")
    .data(words)
  .enter().append("text")
    .style("font-size", function(d) { return d.size + "px"; })
    .style("font-family", "Impact")
    .style("fill", function(d, i) { return fill(i); })
    .attr("text-anchor", "middle")
    .attr("transform", function(d) {
      return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
    })
    .text(function(d) { return d.text; });
}

HTML代码

<div style="margin-left:20px" id="wordCloud"></div>

答案取决于您对 突出显示 的定义以及您希望如何突出显示它们。

一种可能是在画字时将arrayToBeHighlight数组与基准进行比较。例如,将它们变成红色:

.style("fill", function(d, i) { 
    return arrayToBeHighlight.indexOf(d.text) > -1 ? "red" : fill(i); 
})

这是bl.ocks:http://bl.ocks.org/anonymous/d38d1fbb5919c04783934d430fb895c2/b42582053b03b178bb155c2bbaec5242374d051b

mark.js 这样的东西通过在单词周围创建一个跨度并设置背景颜色来模拟荧光笔来工作。这在 SVG 中不起作用,因为 text 元素没有背景颜色。相反,您可以通过在文本元素前插入 rect 来伪造它:

  texts.filter(function(d){
    return arrayToBeHighlight.indexOf(d.text) != -1; 
  })
  .each(function(d){
    var bbox = this.getBBox(),
        trans = d3.select(this).attr('transform');
    g.insert("rect", "text")
      .attr("transform", trans)
      .attr("x", -bbox.width/2)
      .attr("y", bbox.y)
      .attr("width", bbox.width)
      .attr("height", bbox.height)
      .style("fill", "yellow");
  });

运行代码;

<!DOCTYPE html>
<html>

<head>
  <script src="https://d3js.org/d3.v3.min.js"></script>
  <script src="https://rawgit.com/jasondavies/d3-cloud/master/build/d3.layout.cloud.js"></script>
</head>

<body>
  <div style="margin-left:20px" id="wordCloud"></div>
  <script>
    var width = 750,
      height = 500;
    var words = [
      ["whales", 79],
      ["salmon", 56],
      ["Chinook", 30],
      ["book", 70],
      ["prey", 51]
    ].map(function(d) {
      return {
        text: d[0],
        size: d[1]
      };
    });

    var arrayToBeHighlight = ["salmon", "prey"];

    maxSize = d3.max(words, function(d) {
      return d.size;
    });
    minSize = d3.min(words, function(d) {
      return d.size;
    });

    var fontScale = d3.scale.linear().domain([minSize, maxSize]).range([10, 70]);

    var fill = d3.scale.category20();
    d3.layout.cloud().size([width, height]).words(words).font("Impact")
      .fontSize(function(d) {
        return fontScale(d.size)
      })
      .on("end", drawCloud).start();

    function drawCloud(words) {
      var g = d3.select("#wordCloud").append("svg")
        .attr("width", width)
        .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
        
      var texts = g.selectAll("text")
        .data(words)
        .enter().append("text")
        .style("font-size", function(d) {
          return d.size + "px";
        })
        .style("font-family", "Impact")
        .style("fill", function(d, i) {
          return fill(i);
        })
        .attr("text-anchor", "middle")
        .attr("transform", function(d) {
          return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
        })
        .text(function(d) {
          return d.text;
        });
        
      texts.filter(function(d){
        return arrayToBeHighlight.indexOf(d.text) != -1; 
      })
      .each(function(d){
        var bbox = this.getBBox(),
            trans = d3.select(this).attr('transform');
        g.insert("rect", "text")
          .attr("transform", trans)
          .attr("x", -bbox.width/2)
          .attr("y", bbox.y)
          .attr("width", bbox.width)
          .attr("height", bbox.height)
          .style("fill", "yellow");
      });
    }
  </script>
</body>

</html>