2017-10-14 16 views
0

Je veux fort un nouveau tableau de mots comme « saumon » & « proie » que je veux donner à mon nuage de mots, comment dois-je faire parce que j'ai essayé d'utiliser mark.js ou Javascript avec CSS mais je n'ai pas réussi, mais maintenant je pense que c'est seulement possible ici quand je dessine le nuage de mots. Alors quelqu'un peut me aider à me fournir une fonction ou peut-être quelques changements dans mon code pour mettre en évidence le tableau (arrayToBeHighlight) des mots:Comment mettre en évidence un tableau de mots dans les nuages ​​D3 mot

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; }); 
} 

Code HTML

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

Répondre

0

Des choses comme mark.js travail en créant un espace autour du mot et en définissant une couleur de fond pour imiter un surligneur. Cela ne fonctionne pas en SVG car les éléments text n'ont pas de couleur d'arrière-plan. Au lieu de cela, vous pouvez simuler en insérant un rect avant l'élément texte:

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"); 
    }); 

Exécution de code;

<!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>

+0

Impressionnant! Merci beaucoup. C'est exactement ce dont j'avais besoin :) – Coder

+0

Vous ne pourriez pas utiliser mark.js avec un élément personnalisé 'rect'? – dude

0

La réponse dépend de votre définition de mettre en évidence et comment vous voulez les mettre en évidence.

Une possibilité consiste à comparer la matrice arrayToBeHighlight avec la référence lors de la peinture des mots. Par exemple, en les transformant en rouge:

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

Voici les bl.ocks: http://bl.ocks.org/anonymous/d38d1fbb5919c04783934d430fb895c2/b42582053b03b178bb155c2bbaec5242374d051b