Как манипулировать узлами на основе динамически меняющегося текста? (Вход / выход / обновление)

1

Я использую 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';});

             };
Теги:
d3.js
arrays
force-layout

1 ответ

2
Лучший ответ

Прямо сейчас, ваша функция 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>
  • 0
    Еще раз спасибо всемогущий Герардо! В вашем случае круги остаются зелеными, когда я нажимаю на другую вторую цифру. Есть ли вероятность, что круг вернется к исходному цвету, когда нажмете на новое число?
  • 0
    Кроме того, чем selectAll(null) ? Почему бы не опустить selectAll вообще?
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню