#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);
});