2013-08-20 45 views
9

Tôi đang tạo hình ảnh bằng cách sử dụng thư viện javascript D3. Tôi muốn tạo chú giải công cụ cho một số yếu tố của hình ảnh và khách hàng của tôi muốn chúng trông giống như một 'đoạn giấy/hậu kỳ'. Ban đầu, tôi đã tạo ra DIV cho các chú giải công cụ bằng cách sử dụng một số thủ thuật CSS đẹp để tạo ra giao diện mong muốn. (lấy cảm hứng từ this tutorial)Sizing của phần tử SVG foreignObject để phù hợp với phần tử HTML

Tôi muốn sử dụng đóng gói các chú giải công cụ vào phần tử SVG externalObject để nó phù hợp hơn với hình ảnh và tôi có thể thao tác chúng một cách dễ dàng. (ví dụ: zoom/panning) Vì vậy, câu hỏi của tôi là: làm thế nào để có được kích thước thích hợp của DIV, nằm bên trong phần tử waterObject, vì vậy tôi có thể thiết lập kích thước của phần tử ForeignObject một cách chính xác? Đặc biệt khi sử dụng lề/đệm/bóng ....

Tôi đã tìm ra bằng cách sử dụng .getBoundingClientRect() nhưng tôi không biết đây có phải là cách tốt nhất hay không.

Đây là một mã ví dụ:

var body = d3.select("body"); 

var svg = body.append("svg"); 

var tooltipContainer = svg.append("svg:g"); 

var html = tooltipContainer.append("foreignObject") 
var div = html.append("xhtml:div") 
    .attr('class', 'paper-tooltip') 
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum  dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet,  consectetur adipiscing elit. Donec eu enim quam. "); 

var bcr = div[0][0].getBoundingClientRect(); 

html.attr('x', 50) 
    .attr('y', 50) 
    .attr('width', bcr.width) 
    .attr('height', bcr.height); 

svg.call(d3.behavior.zoom().on('zoom', redrawOnZoom)); 

function redrawOnZoom(){ 
    tooltipContainer.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' +   d3.event.scale + ')'); 
}; 

Đây là một ví dụ jsFiddle làm việc: http://jsfiddle.net/jhe8Y/1/

EDIT:

tôi nhận ra, đó là cho bóng cài đặt hộp thư khác nhau .getBoundingClientRect() sẽ không hoạt động. tôi cũng nhận ra rằng với giải pháp đầu tiên của tôi, .getBoundingClientRect() trả về kích thước quá lớn, đặc biệt là ở kích thước phù hợp.

Vì vậy, tôi đã thử một cách khác bằng cách sử dụng jQuerys .outerWidth (true) /. OuterHeight (true) và tính toán kích thước bóng theo cách thủ công. Điều này dường như làm việc tốt, nhưng nó chỉ cảm thấy khủng khiếp để làm một cái gì đó như thế.

Có cách nào khác để có được kích thước chính xác của DIV với tất cả các thành phần của nó không?

Cập nhật jsFiddle là ở đây: http://jsfiddle.net/jhe8Y/3/

Trả lời

0

Tôi đã vật lộn với điều này trước và tôi đã tìm thấy rằng điều dễ nhất để làm chỉ là dựa vào Bootstrap's Tooltip.

Ví dụ:

// title: this is what gets shown as the title in the tooltip 
d3.select('svg').attr('title','This is my tooltip title'); 

// content: this will show up as the content if you go for 
// popovers instead . 
d3.select('svg').attr('data-content','This is some content'); 

// set the options – read more on the Bootstrap page linked to above 
$('svg').popover({ 
    'trigger':'hover' 
    ,'container': 'body' 
    ,'placement': 'top' 
    ,'white-space': 'nowrap' 
    ,'html':'true' // preserve html formatting 
}); 

Nó nắm để thêm titledata-content thuộc tính để bất cứ điều gì yếu tố svg bạn quan tâm trong việc thêm tootltips tới. Sau đó, đặt nội dung bằng bất cứ thứ gì bạn muốn. Vì vậy, trong trường hợp của bạn, html sẽ

<div class='paper-tooltip'>Lorem ipsum dolor sit amet, ... etc etc.</div> 

liên quan:

How do I show a bootstrap tooltip with an SVG object; Question on Stack Overflow

Bootstrap Tooltips

My super-short blog post on it

0

Bạn không cần phải mở rộng nó lên và xuống. Không có sử dụng thực sự của nó, phải không?Sau đó, bạn có thể đặt cả foreignObjectheightwidth thành 1 và qua bộ CSS foreignObject { overflow: visible; }.

Các vấn đề liên quan