Bagaimana cara menambahkan tooltip ke grafik svg?

92

Saya memiliki serangkaian persegi panjang svg (menggunakan D3.js) dan saya ingin menampilkan pesan saat gerakan mouse, pesan harus dikelilingi oleh kotak yang bertindak sebagai latar belakang. Keduanya harus benar-benar sejajar satu sama lain dan dengan persegi panjang (di atas dan di tengah). Apa cara terbaik untuk melakukannya?

Saya mencoba menambahkan teks svg menggunakan atribut "x", "y", "width" dan "height", dan kemudian membuat persegi svg. Masalahnya adalah bahwa titik referensi untuk teks ada di tengah (karena saya ingin itu rata tengah yang saya gunakan text-anchor: middle), tetapi untuk persegi panjang itu adalah koordinat kiri atas, ditambah saya ingin sedikit margin di sekitar teks yang membuatnya semacam itu. sakit.

Opsi lainnya adalah menggunakan div html, yang akan menyenangkan, karena saya dapat menambahkan teks dan padding secara langsung tetapi saya tidak tahu cara mendapatkan koordinat absolut untuk setiap persegi panjang. Apakah ada cara untuk melakukan ini?

nachocab.dll
sumber
Jika tidak ada cara lain, saya kira
nachocab
Apakah itu masalah, menggunakan markup untuk tujuan desainnya?
Phrogz
Hanya saja tidak terlihat bagus, tapi saya menghargai jawaban Anda
nachocab

Jawaban:

175

Dapatkah Anda hanya menggunakan elemen SVG<title> dan perenderan browser default yang disampaikannya? (Catatan: ini tidak sama dengan titleatribut yang dapat Anda gunakan pada div / img / spans di html, ini harus berupa elemen anak bernama 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>

Atau, jika Anda benar-benar ingin menampilkan HTML di SVG, Anda dapat menyematkan HTML secara langsung:

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>

… Tapi kemudian Anda memerlukan JS untuk menghidupkan dan mematikan tampilan. Seperti yang ditunjukkan di atas, salah satu cara untuk membuat label muncul di tempat yang tepat adalah dengan membungkus persegi dan HTML di tempat yang sama <g>yang memposisikan keduanya.

Untuk menggunakan JS guna menemukan letak elemen SVG di layar, Anda dapat menggunakan getBoundingClientRect(), misalnya http://phrogz.net/svg/html_location_in_svg_in_html.xhtml

Phrogz
sumber
Berfungsi dengan baik bagi saya untuk memasukkan judul ke elemen svg!
Shivam Aggarwal
2
Jawaban bagus. Tetapi harap dicatat bahwa foreignObject tidak didukung di Internet Explorer
Rehban Khatri
Di Firefox, SVG berukuran 0x0? Sepertinya Anda harus menentukan lebar dan tinggi seperti<rect width="200" height="50"></rect>
Franklin Yu
2
Sayangnya <title>tidak berpengaruh pada perangkat seluler.
jengeb
Ketika saya mencoba menambahkan judul menggunakan js, dan menambahkan judul sebagai elemen anak. Tooltip tidak muncul :(
Ankur Marwaha
36

Satu-satunya cara terbaik yang saya temukan adalah menggunakan Javascript untuk memindahkan tooltip <div>. Jelas ini hanya berfungsi jika Anda memiliki SVG di dalam dokumen HTML - tidak berdiri sendiri. Dan itu membutuhkan 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>

Timmmm
sumber
3

Saya selalu menggunakan judul css generik dengan pengaturan saya. Saya hanya membangun analitik untuk halaman admin blog saya. Saya tidak butuh sesuatu yang mewah. Ini beberapa kode ...

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

Dan tangkapan layar chrome ...

masukkan deskripsi gambar di sini

VocoJax
sumber
0

Saya menemukan sesuatu hanya dengan menggunakan HTML + CSS. Semoga berhasil untuk Anda

.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>

mhdi
sumber