Làm cách nào để thêm chú giải công cụ vào đồ họa svg?


91

Tôi có một loạt các hình chữ nhật svg (sử dụng D3.js) và tôi muốn hiển thị thông báo khi di chuột qua, thông báo phải được bao quanh bởi một hộp hoạt động như nền. Cả hai đều phải được căn chỉnh hoàn hảo với nhau và với hình chữ nhật (ở trên cùng và ở giữa). Cách tốt nhất để làm việc này là gì?

Tôi đã thử thêm một văn bản svg bằng cách sử dụng các thuộc tính "x", "y", "width" và "height", sau đó thêm một ký tự svg. Vấn đề là điểm tham chiếu cho văn bản nằm ở giữa (vì tôi muốn nó căn giữa mà tôi đã sử dụng text-anchor: middle), nhưng đối với hình chữ nhật, đó là tọa độ trên cùng bên trái, cộng với việc tôi muốn có một chút lề xung quanh văn bản, điều này làm cho nó trở nên một nỗi đau.

Tùy chọn khác là sử dụng một div html, điều này sẽ rất hay, vì tôi có thể thêm văn bản và phần đệm trực tiếp nhưng tôi không biết cách lấy tọa độ tuyệt đối cho mỗi hình chữ nhật. Có cách nào để làm việc này không?


Nếu không còn cách nào khác, tôi đoán
nachocab

Đó có phải là một vấn đề, sử dụng đánh dấu cho những gì nó được thiết kế?
Phrogz

Chỉ là nó không giống như tốt đẹp, nhưng tôi đánh giá cao câu trả lời của bạn
nachocab

Câu trả lời:



175

Bạn có thể sử dụng đơn giản phần tử SVG<title> và trình duyệt mặc định hiển thị nó truyền tải không? (Lưu ý: thuộc tính này không giống với titlethuộc tính bạn có thể sử dụng trên div / img / spans trong html, nó cần phải là một phần tử con có tên 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>

Ngoài ra, nếu bạn thực sự muốn hiển thị HTML trong SVG của mình, bạn có thể nhúng HTML trực tiếp:

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>

… Nhưng sau đó bạn cần JS để bật và tắt màn hình. Như được hiển thị ở trên, một cách để làm cho nhãn xuất hiện ở đúng vị trí là quấn trực tiếp và HTML giống nhau <g>để đặt chúng lại với nhau.

Để sử dụng JS để tìm vị trí của phần tử SVG trên màn hình, bạn có thể sử dụng getBoundingClientRect(), ví dụ: http://phrogz.net/svg/html_location_in_svg_in_html.xhtml


Hoạt động tuyệt vời để tôi chèn tiêu đề vào phần tử svg!
Shivam Aggarwal

2
Câu trả lời hay. Nhưng xin lưu ý rằng foreignObject không được hỗ trợ trong Internet Explorer
Rehban Khatri

Trên Firefox SVG có kích thước 0x0? Nó có vẻ như bạn cần phải xác định chiều rộng và chiều cao như<rect width="200" height="50"></rect>
Franklin Yu

2
Thật không may là <title>không có hiệu lực trên thiết bị di động.
jengeb

Khi tôi đang cố gắng thêm tiêu đề bằng cách sử dụng js và thêm tiêu đề làm phần tử con. Chú giải công cụ không xuất hiện :(
Ankur Marwaha

36

Cách tốt nhất mà tôi tìm thấy là sử dụng Javascript để di chuyển chú giải công cụ <div>xung quanh. Rõ ràng điều này chỉ hoạt động nếu bạn có SVG bên trong tài liệu HTML - không phải độc lập. Và nó yêu cầu 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

Tôi luôn sử dụng tiêu đề css chung với thiết lập của mình. Tôi chỉ đang xây dựng phân tích cho trang quản trị blog của mình. Tôi không cần bất cứ thứ gì cầu kỳ. Đây là một số mã ...

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

Và ảnh chụp màn hình chrome ...

nhập mô tả hình ảnh ở đây


0

Tôi đã nghĩ ra một thứ chỉ sử dụng HTML + CSS. Hi vọng nó sẽ giúp ích cho bạn

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.