จะเพิ่มคำแนะนำเครื่องมือลงในกราฟิก svg ได้อย่างไร?


92

ฉันมีชุดสี่เหลี่ยม svg (โดยใช้ D3.js) และฉันต้องการแสดงข้อความเมื่อวางเมาส์เหนือข้อความควรล้อมรอบด้วยกล่องที่ทำหน้าที่เป็นพื้นหลัง ทั้งสองควรจัดวางให้ชิดกันอย่างสมบูรณ์และเป็นรูปสี่เหลี่ยมผืนผ้า (ด้านบนและตรงกลาง) วิธีที่ดีที่สุดในการทำคืออะไร?

ฉันลองเพิ่มข้อความ svg โดยใช้แอตทริบิวต์ "x", "y", "width" และ "height" จากนั้นป้อน svg rect ไว้ล่วงหน้า ปัญหาคือจุดอ้างอิงของข้อความอยู่ตรงกลาง (เนื่องจากฉันต้องการจัดแนวกึ่งกลางที่ฉันใช้text-anchor: middle) แต่สำหรับสี่เหลี่ยมผืนผ้านั้นเป็นพิกัดด้านซ้ายบนและฉันต้องการระยะขอบเล็กน้อยรอบ ๆ ข้อความซึ่งทำให้เป็นแบบ ความเจ็บปวด.

อีกทางเลือกหนึ่งคือการใช้ html div ซึ่งน่าจะดีเพราะฉันสามารถเพิ่มข้อความและช่องว่างภายในได้โดยตรง แต่ฉันไม่รู้วิธีรับพิกัดสัมบูรณ์สำหรับแต่ละสี่เหลี่ยมผืนผ้า มีวิธีทำไหม?


ถ้าไม่มีวิธีอื่นฉันเดาว่า
nachocab

นั่นคือปัญหาโดยใช้มาร์กอัปสำหรับสิ่งที่ออกแบบมาเพื่อ?
Phrogz

มันดูไม่ดีเท่าไหร่ แต่ฉันขอขอบคุณสำหรับคำตอบของคุณ
nachocab

คำตอบ:


15

คุณสามารถใช้องค์ประกอบหัวเรื่องตามที่ Phrogz ระบุ นอกจากนี้ยังมีเคล็ดลับเครื่องมือที่ดีเช่น Tipsy ของ jQuery http://onehackoranother.com/projects/jquery/tipsy/ (ซึ่งสามารถใช้เพื่อแทนที่องค์ประกอบหัวเรื่องทั้งหมด) nvd3 ของ Bob Monteverde หรือแม้แต่คำแนะนำเครื่องมือของ Twitter จาก Bootstrap http: // twitter.github.com/bootstrap/


176

คุณสามารถใช้องค์ประกอบSVG<title>และเบราว์เซอร์เริ่มต้นที่แสดงผลได้หรือไม่? (หมายเหตุ: สิ่งนี้ไม่เหมือนกับtitleแอตทริบิวต์ที่คุณสามารถใช้ได้กับ div / img / spans ใน 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!
Shivam Aggarwal

2
คำตอบที่ดี แต่โปรดทราบว่าforeignObject Internet Explorer ไม่รองรับ
Rehban Khatri

ใน Firefox SVG มีขนาด 0x0? ดูเหมือนว่าคุณต้องระบุความกว้างและความสูงเช่น<rect width="200" height="50"></rect>
Franklin Yu

2
น่าเสียดายที่<title>ไม่มีผลกับอุปกรณ์มือถือ
jengeb

เมื่อฉันพยายามเพิ่มชื่อโดยใช้ js และต่อท้ายชื่อเป็นองค์ประกอบลูก คำแนะนำเครื่องมือไม่ปรากฏ :(
Ankur Marwaha

36

วิธีเดียวที่ดีที่ฉันพบคือใช้ 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>


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.