2012-06-13 44 views
13

Tôi muốn viết văn bản bên trong một hình chữ nhật tôi tạo như sau:Fit văn bản sang SVG tử (Sử dụng D3/JS)

body = d3.select('body') 

svg = body.append('svg').attr('height', 600).attr('width', 200) 

     rect = svg.append('rect').transition().duration(500).attr('width', 150) 
         .attr('height', 100) 
         .attr('x', 40) 
         .attr('y', 100) 
         .style('fill', 'white') 
         .attr('stroke', 'black') 

     text = svg.append('text').text('This is some information about whatever') 
         .attr('x', 50) 
         .attr('y', 150) 
         .attr('fill', 'black')​ 

Tuy nhiên, như bạn có thể nhìn thấy (http://jsfiddle.net/Tmj7g/3/) văn bản bị cắt đứt. Bất kỳ cách nào tiện lợi để viết một đoạn bên trong hình chữ nhật svg được tạo ra? Cảm ơn,

Trả lời

16

Câu trả lời cho this question có thể có liên quan. SVG không cung cấp cách tự động gói văn bản, nhưng bạn có thể nhúng HTML trong SVG và sau đó sử dụng ví dụ div.

Tôi đã cập nhật jsfiddle here nhưng không hoạt động tốt cùng với hoạt ảnh. Nếu bạn muốn làm cho nó hoạt động bình thường và hoạt động giống như bất kỳ phần tử SVG nào khác, bạn sẽ phải tính toán trước các ngắt dòng và chèn chúng theo cách thủ công.

+0

Điều này làm việc trên IE9? Nếu vậy các lựa chọn thay thế là gì? Tôi biết điều này đã được trả lời từ lâu rồi. – Jose

+0

Tôi chưa thử điều này trong IE9. –

+0

Có, nó không hoạt động ở tất cả trong IE9 bởi vì nó không hỗ trợ các đối tượng nước ngoài. Có bất kỳ lựa chọn thay thế nào để gói văn bản trong D3.js không? – Jose

15

Để làm cho nó hoạt động với các hình ảnh động chỉ cần đính kèm trong một phần tử nhóm và tạo hiệu ứng đó thay thế. http://jsfiddle.net/MJJEc/

body = d3.select('body') 
svg = body.append('svg') 
        .attr('height', 600) 
        .attr('width', 200); 
    var g = svg.append('g').attr("transform" ,"scale(0)"); 
    rect = g.append('rect') 
        .attr('width', 150) 
        .attr('height', 100) 
        .attr('x', 40) 
        .attr('y', 100) 
        .style('fill', 'none') 
        .attr('stroke', 'black') 
    text = g.append('foreignObject') 
        .attr('x', 50) 
        .attr('y', 130) 
        .attr('width', 150) 
        .attr('height', 100) 
        .append("xhtml:body") 
        .html('<div style="width: 150px;">This is some information about whatever</div>') 

    g.transition().duration(500).attr("transform" ,"scale(1)"); 
3

Kỹ thuật này có thể hữu ích. Nó hoạt động với thông số svg hiện tại và không có phần tử externalObject http://bl.ocks.org/mbostock/7555321

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi – Ian

2

Tôi gặp vấn đề tương tự và tìm ra giải pháp hợp lý bằng cách tính chiều rộng của hộp. Thứ hai, tôi đã tìm ra rằng trung bình chiều rộng ký tự cho phông chữ hiện tại của tôi là khoảng 8. Tiếp theo, tôi chỉ cần làm một chuỗi con trên văn bản sẽ được hiển thị. Điều đó dường như hoạt động hoàn hảo trong hầu hết các trường hợp.

var rectText = rectangles.append("text") 
    .text(function(d) { 

     TextBoxLength = timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime)); 
     return d.task.substring(0, Math.floor(TextBoxLength/8)); 
    }) 
    .attr("x", function(d) { 
     return (timeScale(dateFormat.parse(d.endTime)) - timeScale(dateFormat.parse(d.startTime)))/2 + timeScale(dateFormat.parse(d.startTime)) + theSidePad; 
    }) 
    .attr("y", function(d, i) { 
     return d.position * theGap + 14 + theTopPad; 
    }) 
    .attr("font-size", 12) 
    .attr("text-anchor", "middle") 
    .attr("text-height", theBarHeight) 
    .attr("fill", "#000000"); 
2

cách tiếp cận khác, khi cố gắng để phù hợp với một đường thẳng của văn bản thành một yếu tố svg, có thể sử dụng các chiến lược tìm thấy trong http://bl.ocks.org/mbostock/1846692:

node.append("text") 
    .text(function(d) { return d.name; }) 
    .style("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8)/this.getComputedTextLength() * 24) + "px"; }) 
    .attr("dy", ".35em"); 
Các vấn đề liên quan