Проблемы с отображением всплывающих подсказок в динамической столбчатой диаграмме стека d3

#javascript #d3.js

#javascript #d3.js

Вопрос:

У меня есть динамическая гистограмма стека d3. Вы можете увидеть это здесь.

Диаграмма отлично работает без всплывающих подсказок. Я хочу добавить всплывающие подсказки на каждую из стопок баров, которые будут показывать соответствующие значения.

Код был,

  var rect = layer.selectAll("rect")
                .data(function (d) {
                    return d;
                });
 

И чтобы добавить всплывающие подсказки, я изменил их на

 var rect = layer.selectAll("rect")
.data(function (d) {
    return d;
})
  .on("mouseover", function() { tooltip.style("display", null); })
  .on("mouseout", function() { tooltip.style("display", "none"); })
  .on("mousemove", function(d) {
    var xPosition = d3.mouse(this)[0] - 15;
    var yPosition = d3.mouse(this)[1] - 25;
    tooltip.attr("transform", "translate("   xPosition   ","   yPosition   ")");
    tooltip.select("text").text(d.y);
  });

                  
 

Всплывающая подсказка нестабильна. Он отображается не во всех столбцах. Я дважды вызываю метод draw(), затем всплывающие подсказки работают во всех столбцах.

введите описание изображения здесь

Из приведенного выше вы можете видеть, что нажатие кнопки Quarter и Month дважды решает проблему.

В чем здесь проблема?

Ответ №1:

Вы назначаете обработчики событий перед append rect тем, как использовать s.

При первом переходе от года к кварталу всплывающая подсказка появляется только в первом столбце, потому что событие было применено только к первым rect s, составляющим столбец, поскольку в представлении года был только один столбец.

Аналогично, при переходе от квартала к месяцу всплывающая подсказка отображается только в первых четырех столбцах, потому что именно столько столбцов было в представлении квартала.

Когда вы нажимаете квартал и месяц во 2-й (или более) раз rect , s теперь существуют с момента первого нажатия кнопки, и обработчики событий могут подключаться.

Согласованное поведение, которое вы ищете, — это просто вопрос использования этого кода

 var rect = layer.selectAll("rect")
  .data(function (d) {
    return d;
  }) // ------------------------------------------------------------ remove from below ↓↓↓↓↓
  .on("mouseover", function() { tooltip.style("display", null); })
  .on("mouseout", function() { tooltip.style("display", "none"); })
  .on("mousemove", function(d) {
    var xPosition = d3.mouse(this)[0] - 15;
    var yPosition = d3.mouse(this)[1] - 25;
    tooltip.attr("transform", "translate("   xPosition   ","   yPosition   ")");
    tooltip.select("text").text(d.y);
  });
 

И переместите его в раздел, где вы append rect сразу после // Draw Legends ends комментария:

 rect.enter().append("rect")
  .attr("x", function (d) {
    return x(d.x);
  })
  .attr("y", function (d) {
    return y(d.y   d.y0);
  })
  .attr("height", function (d) {
    return y(d.y0) - y(d.y   d.y0);
  }) 
  .attr("width", x.rangeBand()) // -------------------------------- add below here ↓↓↓↓↓
  .on("mouseover", function() { tooltip.style("display", null); })
  .on("mouseout", function() { tooltip.style("display", "none"); })
  .on("mousemove", function(d) {
    var xPosition = d3.mouse(this)[0] - 15;
    var yPosition = d3.mouse(this)[1] - 25;
    tooltip.attr("transform", "translate("   xPosition   ","   yPosition   ")");
    tooltip.select("text").text(d.y);
  });