Вставить фигуру SVG в подсказке d3tip

1

Я работаю с популярной библиотекой наконечников d3-tip.js, пример которой можно найти здесь. Как правило, подсказка содержит текст, который определяется динамически следующим образом:

var tip = d3.tip()
  .attr('class', 'd3-tip')
  .offset([-10, 0])
  .html(function(d) {
    html = "";
    html += "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
    return html;
  })

Однако, скажем, у меня есть такая легенда:

  var legend = g.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 10)
      .attr("text-anchor", "end")
    .selectAll("g")
    .data(keys.slice().reverse())
    .enter().append("g")
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

  legend.append("rect")
      .attr("x", width - 19)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", z);

  legend.append("text")
      .attr("x", width - 24)
      .attr("y", 9.5)
      .attr("dy", "0.32em")
      .text(function(d) { return d; });

Я хотел бы как-то добавить небольшой svg rect внутри инструмента d3. Таким образом, когда вы наводите курсор на график с разными классами (например, сгруппированная гистограмма), всплывающая подсказка будет иметь SVG прямой соответствия цвета в дополнение к html-тексту. В идеале, используя существующую легендарную переменную, как видно выше.

Если это невозможно, просто объясните, почему, и я могу принять это как ответ.

Для наглядности здесь есть приблизительное представление о том, что я собираюсь визуально: Изображение 174551

Теги:
d3.js

1 ответ

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

Легко создать SVG внутри всплывающей подсказки d3.tip. Фактически, вам просто нужно использовать ту же логику любого другого созданного D3 SVG: выберите контейнер и добавьте SVG к нему.

В следующей демонстрации, в вашем var tip, я создам пустой div с заданным ID. В этом случае div имеет идентификатор с именем mySVGtooltip:

var tool_tip = d3.tip()
    .attr("class", "d3-tip")
    .offset([20, 40])
    .html("<div id='mySVGtooltip'></div>");

После этого, это просто вопрос внутри события mouseover, выбрав этот div по ID и добавив к нему SVG:

var legendSVG = d3.select("#mySVGtooltip")
    .append("svg")
    .attr("width", 160)
    .attr("height", 50);

Вот демо, наведите указатель мыши на круги:

var svg = d3.select("body")
  .append("svg")
  .attr("width", 300)
  .attr("height", 300);

var tool_tip = d3.tip()
  .attr("class", "d3-tip")
  .offset([20, 40])
  .html("<div id='mySVGtooltip'></div>");

svg.call(tool_tip);

var data = [20, 10, 30, 15, 35];

var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle");

circles.attr("cy", 50)
  .attr("cx", function(d, i) {
    return 30 + 55 * i
  })
  .attr("r", function(d) {
    return d
  })
  .attr("fill", "lightgreen")
  .attr("stroke", "dimgray")
  .on('mouseover', function(d) {
    tool_tip.show();
    var legendSVG = d3.select("#mySVGtooltip")
      .append("svg")
      .attr("width", 160)
      .attr("height", 50);

    var legend = legendSVG.append("g")
      .attr("font-family", "sans-serif")
      .attr("font-size", 10);
      
      legend.append("text")
      .attr("x", 80)
      .attr("text-anchor", "middle")
      .attr("y", 16)
      .attr("font-size", 14)
      .text("Age Group:");

    legend.append("rect")
    	.attr("y", 25)
      .attr("x", 10)
      .attr("width", 19)
      .attr("height", 19)
      .attr("fill", "goldenrod");

    legend.append("text")
      .attr("x", 35)
      .attr("y", 40)
      .text(function() {
        return d + " years and over";
      });
  })
  .on('mouseout', tool_tip.hide);
.d3-tip {
  line-height: 1;
  background: gainsboro;
  border: 1px solid black;
  font-size: 12px;
}

p {
  font-family: Helvetica;
}
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>

Обратите внимание, что в этой простой демонстрации я использую datum (d), переданную анонимной функции событием mouseover. Я вижу в вашем вопросе, что у вас есть свои данные. Таким образом, измените код в моей демонстрации соответственно.

  • 0
    Это действительно круто! Вы объяснили это хорошо в комплекте с демо, очень приятно. Теперь я вижу преимущества пользовательской подсказки.
  • 0
    Привет, я в конечном итоге ударил несколько ударов по дороге. По какой-то причине текст добавляется в самом низу страницы. Я считаю, что это признак того, что div добавляется асинхронно. Есть ли <div id='mySVGtooltip'></div> способ убедиться, что <div id='mySVGtooltip'></div> всегда находится внутри всплывающей подсказки? Должен ли я установить абсолютную позицию или что-то?
Показать ещё 2 комментария

Ещё вопросы

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