首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Javascript在文本中查找单词并动态更改颜色

Javascript在文本中查找单词并动态更改颜色
EN

Stack Overflow用户
提问于 2021-07-22 21:25:30
回答 1查看 106关注 0票数 2

我使用下面的代码bl.ocks.org/d3noob/8375092制作了一个d3.js图表

我正在试着改变一个单词的颜色。在单词的每个实例中,我都希望更改颜色。例如,如果你看图表,有A的第一个女儿和A的女儿。我想把文本“女儿”的颜色改为红色。我想把“2级之子: B”的颜色全部改成蓝色。(忽略我的项目的大的高度和宽度-in我的可折叠图表中有50个术语-但在这个问题中只包括了几个)。

我尝试在CSS中更改所有文本的颜色,但它不显示。当我检查一个元素时,颜色将显示为“蓝色”,但文本显示为黑色。我也尝试在HTML语言中使用,但我不知道如何处理变量tree.Data,因为它是用JavaScript编写的。

我是一个编程的初学者。感谢您的帮助!

代码语言:javascript
复制
var treeData = [
  {
    "name": "Top Level",
    "parent": "null",
    "children": [
      {
        "name": "Level 2: A",
        "parent": "Top Level",
        "children": [
          {
            "name": "First Daughter of A",
            "parent": "Level 2: A"
          },
          {
            "name": "Daughter of A",
            "parent": "Level 2: A"
          }
        ]
      },
      {
        "name": "Level 2: B",
        "parent": "Top Level",
        "children": [
          {
            "name": "Son of Level 2: B",
            "parent": "Level 2: B"
          }
         ]
      }
    ]
  }
];


// ************** Generate the tree diagram  *****************
var margin = {top: 20, right: 120, bottom: 20, left: 250},
    width = 2000 - margin.right - margin.left,
    height = 2000 - margin.top - margin.bottom;

var i = 0,
    duration = 750,
    root;

var tree = d3.layout.tree()
    .size([height, width]);

var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.y, d.x]; });

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

root = treeData[0];
root.x0 = height / 2;
root.y0 = 0;

update(root);

d3.select(self.frameElement).style("height", "500px");

function update(source) {

  // Compute the new tree layout.
  var nodes = tree.nodes(root).reverse(),
      links = tree.links(nodes);

  // Normalize for fixed-depth.
  nodes.forEach(function(d) { d.y = d.depth * 180; });

  // Update the nodes…
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });

  // Enter any new nodes at the parent's previous position.
  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .on("click", click);

  nodeEnter.append("circle")
      .attr("r", 1e-6)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeEnter.append("text")
      .attr("x", function(d) { return d.children || d._children ? -13 : 13; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
      .text(function(d) { return d.name; })
      .style("fill-opacity", 1e-6);

  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

  nodeUpdate.select("circle")
      .attr("r", 10)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeUpdate.select("text")
      .style("fill-opacity", 1);

  // Transition exiting nodes to the parent's new position.
  var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
      .remove();

  nodeExit.select("circle")
      .attr("r", 1e-6);

  nodeExit.select("text")
      .style("fill-opacity", 1e-6);

  // Update the links…
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links at the parent's previous position.
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("d", function(d) {
        var o = {x: source.x0, y: source.y0};
        return diagonal({source: o, target: o});
      });

  // Transition links to their new position.
  link.transition()
      .duration(duration)
      .attr("d", diagonal);

  // Transition exiting nodes to the parent's new position.
  link.exit().transition()
      .duration(duration)
      .attr("d", function(d) {
        var o = {x: source.x, y: source.y};
        return diagonal({source: o, target: o});
      })
      .remove();

  // Stash the old positions for transition.
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
}

// Toggle children on click.
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update(d);
}
代码语言:javascript
复制
.node {
  cursor: pointer;
}
.block{
  width:5%;
  height:10%;
}
.top{
  width: 95%;
  margin-left: 5%;
  color: black;
}
.no{
  color:black;
}

.node circle {
  fill: #fff;
  stroke: steelblue;
  stroke-width: 3px;
}

.node text {
  color: Blue;
  font-weight: bold;
  font: 12px sans-serif;
}

.link {
  fill: none;
  stroke: #ccc;
  stroke-width: 2px;
}
代码语言:javascript
复制
<div class="block"></div>
<div class="top">
  <h1>Title</h1>
  <h2>Click nodes to expand each level</h2>
  <h3>Key</h3>
  <div class="no">
    <h4>No capability</h4>
  </div>
  <div class="adhoc">
    <h4>Another heading</h4>
  </div>
  <h4>Another heading4</h4>
  <h4>Heading 4</h4>
  <h4>Final heading 4</h4>
</div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="myChart.js"></script>
<link rel= "stylesheet" href="./myStyle.css">

EN

Stack Overflow用户

发布于 2021-07-23 01:24:28

在SVG中,为了给单个单词着色,需要在文本元素中使用tspan。这意味着搜索文本元素,查找匹配的字符串,并将它们替换为包含匹配单词的新子tspan元素。

文本元素中指定短语/单词的高亮显示(更改颜色)

一种方法可以是:

代码语言:javascript
复制
function highlight(selection,word) {
  selection.each(function() {
    this.innerHTML = this.textContent.replace(new RegExp(word, "ig"),(w)=>"<tspan>"+w+"</tspan>")
  })
}

此函数接受(文本)元素的选择,以及要查找的单词。它搜索文本元素的文本内容以查找匹配的字符串,并将匹配的字符串替换为包含匹配字符串的tspan。它在匹配文本时不区分大小写,但保留原始文本中的大小写。

在下面的代码片段中,只需在文本框中键入内容即可动态突出显示文本:

代码语言:javascript
复制
var svg = d3.select("svg");
var data = [
  "You can't direct the wind, but you can adjust your sails",
  "If you chase two rabbits, you will lose them both.",
  "If you speak the truth, have a foot in the stirrup.",
  "One doesn't discover new lands without losing sight of the shore.",
  "The whole is more than the sum of its parts."
]


var textElements = svg.selectAll(null)
  .data(data)
  .join("text")
  .text(d=>d)
  .attr("x",20)
  .attr("y",(d,i) => i* 30 + 30);
  
function highlight(selection,word) {
  selection.each(function() {
    this.innerHTML = this.textContent.replace(new RegExp(word, "ig"),(w)=>"<tspan>"+w+"</tspan>")
  })
}


d3.select("#text").on("keyup", function() {
  textElements.call(highlight, this.value);
   //alternatively:  highlight(textElements,this.value);
})
代码语言:javascript
复制
tspan {
  fill: orange;
  stroke: orange;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<div><input type="text" id="text"/></div>
<svg width="500" height="250"></svg>

使用矩形突出显示

我们也可以更花哨一点,使用高亮笔画,这需要添加矩形,要做到这一点,我们可以使用tspan作为连接的数据来创建矩形:

代码语言:javascript
复制
var svg = d3.select("svg");
var data = [
  "You can't direct the wind, but you can adjust your sails",
  "If you chase two rabbits, you will lose them both.",
  "If you speak the truth, have a foot in the stirrup.",
  "One doesn't discover new lands without losing sight of the shore.",
  "The whole is more than the sum of its parts.",
]


var textElements = svg.selectAll(null)
  .data(data)
  .join("text")
  .text(d=>d)
  .attr("x",20)
  .attr("y",(d,i) => i* 30 + 30);
  
function highlight(selection,word,rectContainer) {
  selection.each(function() {
    this.innerHTML = this.textContent.replace(new RegExp(word, "ig"),(w)=>"<tspan>"+w+"</tspan>")
  })
  // join, color, positoin the rectangles:
  rectContainer.selectAll(".highlight")
    .data(selection.selectAll("tspan").nodes())
    .join("rect")
    .attr("class","highlight")
    .datum(d=>d.getBBox())
    .attr("x", d=>d.x)
    .attr("y", d=>d.y)
    .attr("width", d=>d.width)
    .attr("height", d=>d.height)
    .attr("fill","yellow")
    .lower();

}


d3.select("#text").on("keyup", function() {
  textElements.call(highlight, this.value, svg);
   //alternatively:  highlight(textElements,this.value);
})
代码语言:javascript
复制
tspan {
  fill: orange;
  stroke: orange;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<div><input type="text" id="text"/></div>
<svg width="500" height="250"></svg>

使用一种突出显示样式突出显示多个短语/单词

如果我们想用相同的颜色突出显示多个短语,我们可以修改regex:

代码语言:javascript
复制
  let ex = new RegExp(words.join("|"),"gi");
  selection.each(function() {
    this.innerHTML = this.textContent.replace(ex, "ig"),(w)=>"<tspan>"+w+"</tspan>")
  })

代码语言:javascript
复制
var svg = d3.select("svg");
var data = [
  "You can't direct the wind, but you can adjust your sails",
  "If you chase two rabbits, you will lose them both.",
  "If you speak the truth, have a foot in the stirrup.",
  "One doesn't discover new lands without losing sight of the shore.",
  "The whole is more than the sum of its parts.",
]


var textElements = svg.selectAll(null)
  .data(data)
  .join("text")
  .text(d=>d)
  .attr("x",20)
  .attr("y",(d,i) => i* 30 + 30);
  
function highlight(selection,words,rectContainer) {
      let ex = new RegExp(words.join("|"),"gi");
      selection.each(function() {
        this.innerHTML = this.textContent.replace(ex,(w)=>"<tspan>"+w+"</tspan>")
      })
  // join, color, positoin the rectangles:
  rectContainer.selectAll(".highlight")
    .data(selection.selectAll("tspan").nodes())
    .join("rect")
    .attr("class","highlight")
    .datum(d=>d.getBBox())
    .attr("x", d=>d.x)
    .attr("y", d=>d.y)
    .attr("width", d=>d.width)
    .attr("height", d=>d.height)
    .attr("fill","yellow")
    .lower();

}



d3.selectAll("input").on("keyup", function() {
  var words = d3.selectAll("input").nodes().map(function(n) { return n.value; });
  textElements.call(highlight, words, svg);
})

d3.select("input").dispatch("keyup");
代码语言:javascript
复制
tspan {
  fill: orange;
  stroke: orange;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<div><input type="text" value="you" id="text1"/></div>
<div><input type="text" value="two" id="text2"/></div>
<svg width="500" height="250"></svg>

为每个突出显示具有不同风格的多个短语/单词

当处理不同短语的多个tspan和矩形时,挑战会稍微困难一些。为此,我们需要修改highlight函数以匹配多个字符串,为了实现灵活性,我们还将避免硬编码的类。这需要比以前更好的数据管理,因此对突出显示函数进行了一些更改以适应这一点。

为了完成这个任务,我们将遍历所提供的单词列表,并根据指定的矩形填充和文本填充颜色数组为它们分配颜色。我们将添加tspan,并使用tspan的内容和tspan的bbox作为数据向前传递到用于添加矩形的连接。

对于rect和text,我们将使用高亮显示函数直接给元素填充,例如:

代码语言:javascript
复制
function highlight(selection,words,rectContainer) {
  // create a pool of colors available:
  let textColors = ["crimson","steelblue"];
  let rectColors = ["yellow","#ccc","orange","#eee"];

  // assign colors to words:
  let colors = {}
  words.forEach((w,i)=>{
    colors[w.toLowerCase()] = {
      text: textColors[i%textColors.length],
      rect: rectColors[i%rectColors.length]
    }
  })
  // create a regex experssion:
  let ex = new RegExp(words.join("|"),"gi");
  
  // Create the tspans: 
  selection.each(function() {
    this.innerHTML = this.textContent.replace(ex,(w)=>"<tspan>"+w+"</tspan>")
  })
  
  // Select the tspans, bind data to them, color them:
  let tspans = selection.selectAll("tspan")
    .datum((d,i,n)=>{     
        return {word:n[i].textContent.toLowerCase()}
     })
    .attr("fill", d=>colors[d.word].text)
    .each((d,i,n)=>{ d.bbox = n[i].getBBox() })

  // Conduct a join of rectangles, color them, place them:
  rectContainer.selectAll(".highlight")
    .data(tspans.data())
    .join("rect")
    .attr("class","highlight")
    .attr("x", d=>d.bbox.x)
    .attr("y", d=>d.bbox.y)
    .attr("width", d=>d.bbox.width)
    .attr("height", d=>d.bbox.height)
    .attr("fill", d=>colors[d.word].rect)
    .lower();

}

代码语言:javascript
复制
var svg = d3.select("svg");
var data = [
  "You can't direct the wind, but you can adjust your sails",
  "If you chase two rabbits, you will lose them both.",
  "If you speak the truth, have a foot in the stirrup.",
  "One doesn't discover new lands without losing sight of the shore.",
  "The whole is more than the sum of its parts."
]


var textElements = svg.selectAll(null)
  .data(data)
  .join("text")
  .text(d=>d)
  .attr("x",20)
  .attr("y",(d,i) => i* 30 + 30);
  
  

function highlight(selection,words,rectContainer) {
  // create a pool of colors available:
  let textColors = ["crimson","steelblue"];
  let rectColors = ["yellow","#ccc","orange","#eee"];

  // assign colors to words:
  let colors = {}
  words.forEach((w,i)=>{
    colors[w.toLowerCase()] = {
      text: textColors[i%textColors.length],
      rect: rectColors[i%rectColors.length]
    }
  })
  // create a regex experssion:
  let ex = new RegExp(words.join("|"),"gi");
  
  // Create the tspans: 
  selection.each(function() {
    this.innerHTML = this.textContent.replace(ex,(w)=>"<tspan>"+w+"</tspan>")
  })
  
  // Select the tspans:
  let tspans = selection.selectAll("tspan")
    .datum((d,i,n)=>{     
        return {word:n[i].textContent.toLowerCase()}
     })
    .attr("fill", d=>colors[d.word].text)
    .each((d,i,n)=>{ d.bbox = n[i].getBBox() })

  // Conduct a join of rectangles:
  rectContainer.selectAll(".highlight")
    .data(tspans.data())
    .join("rect")
    .attr("class","highlight")
    .attr("x", d=>d.bbox.x)
    .attr("y", d=>d.bbox.y)
    .attr("width", d=>d.bbox.width)
    .attr("height", d=>d.bbox.height)
    .attr("fill", d=>colors[d.word].rect)
    .lower();

}


// cycle through some words:
let wordlist = [
  ["you","the","can"],
  ["stirrup","chase","discover","whole"],
  ["if"]
]

let i = 0;
highlight(textElements,wordlist[i++%3],svg)
setInterval(function(){  
     highlight(textElements,wordlist[i++%3],svg) }, 
     1000);
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<svg width="500" height="250"></svg>

上面的代码应该会产生:

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68485651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档