Як додати підказку до графіки svg?


91

У мене є серія прямокутників svg (з використанням D3.js), і я хочу відобразити повідомлення при наведенні миші, повідомлення повинно бути оточене вікном, який виконує роль фону. Вони обидва повинні бути ідеально вирівняні між собою та прямокутником (зверху та по центру). Який найкращий спосіб це зробити?

Я спробував додати текст svg, використовуючи атрибути "x", "y", "width" і "height", а потім додавши до прямого запису svg. Проблема полягає в тому, що опорна точка для тексту знаходиться посередині (оскільки я хочу, щоб він був вирівняний по центру, який я використовував text-anchor: middle), але для прямокутника це верхня ліва координата, плюс я хотів трохи поля навколо тексту, що робить його таким біль.

Іншим варіантом було використання html div, що було б непогано, тому що я можу додавати текст та відступ безпосередньо, але я не знаю, як отримати абсолютні координати для кожного прямокутника. Чи є спосіб зробити це?


Якщо іншого шляху немає, я здогадуюсь
nachocab

Це проблема, якщо використовувати розмітку для того, для чого вона була розроблена?
Фрогц,

Просто це виглядає не так приємно, але я ціную вашу відповідь
nachocab

Відповіді:


15

Ви можете використовувати елемент заголовка, як вказав Phrogz. Є також кілька хороших підказок, таких як Підказка jQuery http://onehackoranother.com/projects/jquery/tipsy/ (яка може бути використана для заміни всіх елементів заголовка), nvd3 Боба Монтеверде або навіть підказка Twitter із їх Bootstrap http: // twitter.github.com/bootstrap/


175

Чи можете ви просто використовувати елемент SVG<title> та браузер за замовчуванням, який він передає? (Примітка: це не те саме, що titleатрибут, який ви можете використовувати на div / img / span в html, це повинен бути дочірній елемент з іменем title)

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}
<p>Mouseover the rect to see the tooltip on supporting browsers.</p>

<svg xmlns="http://www.w3.org/2000/svg">
  <rect>
    <title>Hello, World!</title>
  </rect>
</svg>

Крім того, якщо ви дійсно хочете показати HTML у своєму SVG, ви можете вбудувати HTML безпосередньо:

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}

foreignObject {
  width: 100%;
}

svg div {
  text-align: center;
  line-height: 150px;
}
<svg xmlns="http://www.w3.org/2000/svg">
  <rect/>
  <foreignObject>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <div>
        Hello, <b>World</b>!
      </div>
    </body>      
  </foreignObject>
</svg>

... але тоді вам знадобиться JS, щоб увімкнути та вимкнути дисплей. Як показано вище, один із способів зробити мітку відображеною в потрібному місці - це обернути rect та HTML тим самим, <g>що позиціонує їх обох разом.

Щоб використовувати JS, щоб знайти, де на екрані є елемент SVG, ви можете використовувати getBoundingClientRect(), наприклад, http://phrogz.net/svg/html_location_in_svg_in_html.xhtml


Для мене добре працює вставлення заголовка в елемент svg!
Шивам Аггарвал,

2
Приємна відповідь. Але зверніть увагу, що foreignObject Internet Explorer не підтримує
Рехбан Хатрі,

У Firefox SVG має розмір 0x0? Здається, вам потрібно вказати ширину та висоту, як<rect width="200" height="50"></rect>
Франклін Ю

2
На жаль, <title>це не впливає на мобільні пристрої.
jengeb

Коли я намагаюся додати заголовок за допомогою js та додавати заголовок як дочірній елемент.
Підказка

35

Єдиний хороший спосіб, який я знайшов, - це використовувати Javascript для переміщення підказки <div>. Очевидно, це працює лише у тому випадку, якщо у вас є SVG всередині документа HTML - не автономно. І для цього потрібен Javascript.

function showTooltip(evt, text) {
  let tooltip = document.getElementById("tooltip");
  tooltip.innerHTML = text;
  tooltip.style.display = "block";
  tooltip.style.left = evt.pageX + 10 + 'px';
  tooltip.style.top = evt.pageY + 10 + 'px';
}

function hideTooltip() {
  var tooltip = document.getElementById("tooltip");
  tooltip.style.display = "none";
}
#tooltip {
  background: cornsilk;
  border: 1px solid black;
  border-radius: 5px;
  padding: 5px;
}
<div id="tooltip" display="none" style="position: absolute; display: none;"></div>

<svg>
  <rect width="100" height="50" style="fill: blue;" onmousemove="showTooltip(evt, 'This is blue');" onmouseout="hideTooltip();" >
  </rect>
</svg>


3

Завжди встановлюю загальний заголовок css. Я просто будую аналітику для сторінки адміністратора мого блогу. Мені не потрібно нічого вигадливого. Ось код ...

let comps = g.selectAll('.myClass')
   .data(data)
   .enter()
   .append('rect')
   ...styling...
   ...transitions...
   ...whatever...

g.selectAll('.myClass')
   .append('svg:title')
   .text((d, i) => d.name + '-' + i);

І скріншот хрому ...

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


0

Я щось придумав, використовуючи лише HTML + CSS. Сподіваюся, це працює для вас

.mzhrttltp {
  position: relative;
  display: inline-block;
}
.mzhrttltp .hrttltptxt {
  visibility: hidden;
  width: 120px;
  background-color: #040505;
  font-size:13px;color:#fff;font-family:IranYekanWeb;
  text-align: center;
  border-radius: 3px;
  padding: 4px 0;
  position: absolute;
  z-index: 1;
  top: 105%;
  left: 50%;
  margin-left: -60px;
}

.mzhrttltp .hrttltptxt::after {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent transparent #040505 transparent;
}

.mzhrttltp:hover .hrttltptxt {
  visibility: visible;
}
<div class="mzhrttltp"><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="none" stroke="#e2062c" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-heart"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><div class="hrttltptxt">علاقه&zwnj;مندی&zwnj;ها</div></div>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.