Bir svg grafiğine araç ipucu nasıl eklenir?


92

Bir dizi svg dikdörtgenim var (D3.js kullanarak) ve fareyle üzerine gelindiğinde bir mesaj görüntülemek istiyorum, mesaj arka plan görevi gören bir kutu ile çevrelenmelidir. Her ikisi de birbirine ve dikdörtgene mükemmel şekilde hizalanmalıdır (üstte ve ortalanmış). Bunu yapmanın en iyi yolu nedir?

"X", "y", "genişlik" ve "yükseklik" özelliklerini kullanarak bir svg metni eklemeyi ve ardından bir svg rect eklemeyi denedim. Sorun şu ki, metin için referans noktası ortada (kullandığım ortalanmış olarak hizalanmasını istediğim için text-anchor: middle), ancak dikdörtgen için bu sol üst koordinat, ayrıca metnin etrafında biraz kenar boşluğu istedim Bir ağrı.

Diğer seçenek html div kullanmaktı, bu iyi olurdu, çünkü metni ve dolguyu doğrudan ekleyebilirim ancak her dikdörtgenin mutlak koordinatlarını nasıl elde edeceğimi bilmiyorum. Bunu yapmanın bir yolu var mı?


Başka bir yolu yoksa, sanırım
nachocab

Bu, tasarlandığı şey için işaretlemeyi kullanmak bir sorun mu?
Phrogz

Sadece pek hoş görünmüyor, ama cevabınız için minnettarım
nachocab

Yanıtlar:



175

Yalnızca SVG <title>öğesini ve onun taşıdığı varsayılan tarayıcı görüntülemesini kullanabilir misiniz ? (Not: Bu, html'deki div / img / spans üzerinde kullanabileceğiniz öznitelikle aynı değildir , adında titlebir alt öğe olması gerekir 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>

Alternatif olarak, SVG'nizde gerçekten HTML göstermek istiyorsanız, HTML'yi doğrudan gömebilirsiniz:

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>

… Ama sonra ekranı açıp kapatmak için JS'ye ihtiyacınız olacak. Yukarıda gösterildiği gibi, etiketin doğru noktada görünmesini sağlamanın bir yolu, rect ve HTML'yi <g>ikisini birlikte konumlandıracak şekilde aynı şekilde sarmaktır.

Bir SVG öğesinin ekranda nerede olduğunu bulmak üzere JS'yi kullanmak için getBoundingClientRect(), örneğin http://phrogz.net/svg/html_location_in_svg_in_html.xhtml kullanabilirsiniz.


Bir svg öğesine başlık eklemek benim için iyi çalışıyor!
Shivam Aggarwal

2
Güzel cevap. Ancak bunun foreignObject Internet Explorer'da desteklenmediğini
Rehban Khatri

Firefox'ta SVG'nin boyutu 0x0 mı? Görünüşe göre genişlik ve yüksekliği belirtmeniz gerekiyor<rect width="200" height="50"></rect>
Franklin Yu

2
Maalesef <title>mobil cihazlar üzerinde hiçbir etkisi yoktur.
jengeb

Js kullanarak başlığı eklemeye ve alt öğe olarak başlık eklemeye çalıştığımda. Araç ipucu görünmüyor :(
Ankur Marwaha

36

Bulduğum tek iyi yol, bir araç ipucunu hareket ettirmek için Javascript kullanmaktı <div>. Açıkçası, bu yalnızca bir HTML belgesinin içinde SVG varsa çalışır - bağımsız değil. Ve Javascript gerektirir.

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

Kurulumumda her zaman genel css başlığıyla giderim. Blog yöneticisi sayfam için analizler oluşturuyorum. Süslü bir şeye ihtiyacım yok. İşte bazı kodlar ...

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

Ve bir krom ekran görüntüsü ...

görüntü açıklamasını buraya girin


0

Yalnızca HTML + CSS kullanan bir şey buldum. Umarım senin için çalışır

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.