我使用下面的代码bl.ocks.org/d3noob/8375092制作了一个d3.js图表
我正在试着改变一个单词的颜色。在单词的每个实例中,我都希望更改颜色。例如,如果你看图表,有A的第一个女儿和A的女儿。我想把文本“女儿”的颜色改为红色。我想把“2级之子: B”的颜色全部改成蓝色。(忽略我的项目的大的高度和宽度-in我的可折叠图表中有50个术语-但在这个问题中只包括了几个)。
我尝试在CSS中更改所有文本的颜色,但它不显示。当我检查一个元素时,颜色将显示为“蓝色”,但文本显示为黑色。我也尝试在HTML语言中使用,但我不知道如何处理变量tree.Data,因为它是用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);
}.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;
}<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">
发布于 2021-07-23 01:24:28
在SVG中,为了给单个单词着色,需要在文本元素中使用tspan。这意味着搜索文本元素,查找匹配的字符串,并将它们替换为包含匹配单词的新子tspan元素。
文本元素中指定短语/单词的高亮显示(更改颜色)
一种方法可以是:
function highlight(selection,word) {
selection.each(function() {
this.innerHTML = this.textContent.replace(new RegExp(word, "ig"),(w)=>"<tspan>"+w+"</tspan>")
})
}此函数接受(文本)元素的选择,以及要查找的单词。它搜索文本元素的文本内容以查找匹配的字符串,并将匹配的字符串替换为包含匹配字符串的tspan。它在匹配文本时不区分大小写,但保留原始文本中的大小写。
在下面的代码片段中,只需在文本框中键入内容即可动态突出显示文本:
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);
})tspan {
fill: orange;
stroke: orange;
}<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作为连接的数据来创建矩形:
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);
})tspan {
fill: orange;
stroke: orange;
}<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:
let ex = new RegExp(words.join("|"),"gi");
selection.each(function() {
this.innerHTML = this.textContent.replace(ex, "ig"),(w)=>"<tspan>"+w+"</tspan>")
})
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");tspan {
fill: orange;
stroke: orange;
}<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,我们将使用高亮显示函数直接给元素填充,例如:
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();
}
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);<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.0.0/d3.min.js"></script>
<svg width="500" height="250"></svg>
上面的代码应该会产生:

https://stackoverflow.com/questions/68485651
复制相似问题