Я использую d3.js с компоновкой силы. Теперь, с помощью динамически изменяющихся data
массива, можно выделить узлы динамически на основе массива. Кроме того, с приведенным ниже кодом я могу динамически отображать имена узлов, которые являются частью массива, в виде текста.
Итак, когда массив имеет, например, 3 записи, то отображаются 3 узла, а также появляются 3 имени узлов. Скажем, их имена "a", "b", "c", поэтому на экране появляются текст "a", "b", "c". Теперь, когда я нажимаю на новый появившийся текст "a", я хочу, чтобы узел, который содержит это имя, был заполнен зеленым. Я пробовал это с помощью функции specialfunction
. Проблема в том, что все узлы заполняются зеленым цветом, когда я нажимаю на текст "a". Может, кто-то из вас, ребята, может помочь? Благодарю.
var texts = svg.selectAll(".texts")
.data(data);
textsExit = texts.exit().remove();
textsEnter = texts.enter()
.append("text")
.attr("class", "texts");
textsUpdate = texts.merge(textsEnter)
.attr("x", 10)
.attr("y", (d, i) => i * 16)
.text(d => d.name)
.on("click", specialfunction);
function specialfunction(d) {
node.style("fill", function(d){ return this.style.fill = 'green';});
};
Прямо сейчас, ваша функция specialFunction
принимает только выбор nodes
и устанавливает стиль всех его элементов на возвращаемое значение...
this.style.fill = 'green';
... который, гадать, что, "green"
.
Вместо этого filter
узлы в соответствии с щелчком:
function specialFunction(d) {
nodes.filter(function(e) {
return e === d
}).style("fill", "forestgreen")
}
В этой простой демонстрации d
- это номер для текста и кругов. Просто измените d
в моей демо на d.name
или любое другое свойство, которое вы хотите. Нажмите текст, и соответствующий круг изменит цвет:
var svg = d3.select("svg");
var data = d3.range(5);
var nodes = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cy", 50)
.attr("cx", function(d) {
return 30 + d * 45
})
.attr("r", 20)
.style("fill", "lightblue")
.attr("stroke", "gray");
var texts = svg.selectAll(null)
.data(data)
.enter()
.append("text")
.attr("y", 88)
.attr("x", function(d) {
return 26 + d * 45
})
.attr("fill", "dimgray")
.attr("cursor", "pointer")
.text(function(d) {
return d
})
.on("click", specialFunction);
function specialFunction(d) {
nodes.filter(function(e) {
return e === d
}).style("fill", "forestgreen")
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
EDIT: отвечая на ваш комментарий, эта еще более простая функция может установить круги в исходный цвет:
function specialFunction(d) {
nodes.style("fill", function(e){
return e === d ? "forestgreen" : "lightblue";
})
}
Вот демо:
var svg = d3.select("svg");
var data = d3.range(5);
var nodes = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cy", 50)
.attr("cx", function(d) {
return 30 + d * 45
})
.attr("r", 20)
.style("fill", "lightblue")
.attr("stroke", "gray");
var texts = svg.selectAll(null)
.data(data)
.enter()
.append("text")
.attr("y", 88)
.attr("x", function(d) {
return 26 + d * 45
})
.attr("fill", "dimgray")
.attr("cursor", "pointer")
.text(function(d) {
return d
})
.on("click", specialFunction);
function specialFunction(d) {
nodes.style("fill", function(e){
return e === d ? "forestgreen" : "lightblue";
})
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
selectAll(null)
? Почему бы не опустить selectAll вообще?