2016-02-12 56 views
0

我正在使用SVG在D3.js中繪製文本和形狀,並且想要以文本和文本的類似尺寸內聯繪製形狀。我能想到的唯一方法就是在每個tspan周圍繪製矩形,然後在相對於tspan矩形的相對位置繪製形狀。其結果是:d3js svg文本和形狀在同一行上

這是矩形[]這是一個圓()

當上面的括號表示SVG形狀。當前代碼如下。

JS:

function setupSVG(){ 
    d3.select("div#chartId") 
     .append("div") 
     .classed("svg-container", true) 
     .append("svg") 
     .attr("preserveAspectRatio", "xMinYMin meet") 
     .attr("viewBox", "0 0 200 200") 
     .attr("id", "svg_area_id") 
} 

function renderSVGText(){ 
    var svgArea = d3.select("svg#svg_area_id"); 

    svgArea.append("rect")  
     .attr("x", 100)   
     .attr("y", 0)   
     .attr("height", 10)  
     .attr("width", 10)  
     .attr("id", "shape"); 

    var group = svgArea.append("g") 
     .attr("width", "100%") 
     .attr("height", "100%") 
     .style("stroke", "red") //I only want to draw rect stroke 
     .style("fill", "none"); 

    var text = group.append("text") 
     .attr("y", "0") 
     .attr("font-size",52) 
     .attr("dy", "1em") 
     .style('fill', 'black') 

    var tspan1 = text.append('tspan') 
    tspan1.text("This is a square"); 
    var tspan2 = text.append('tspan') 
    tspan2.text("and this is a triangle"); 

    var boundingRect = group.append("rect") 
    //see http://phrogz.net/SVG/tspan_bounding_box.xhtml 
    var bbox = tspan1.getBoundingClientRect(); 
    var pt = svg.createSVGPoint(); 
    pt.x = bbox.left; 
    pt.y = bbox.top; 
    var pt2 = pt.matrixTransform(xform); 
    rect.setAttribute('x',pt2.x); 
    rect.setAttribute('y',pt2.y); 

    pt.x = bbox.right; 
    pt.y = bbox.bottom; 
    pt = pt.matrixTransform(xform); 
    boundingRect.attr('width', pt.x-pt2.x); 
    boundingRect.attr('height',pt.y-pt2.y); 

    /* this draws a rect around all text 
    var textSize = text.node().getBBox(); 
    boundingRect.attr("width", textSize.width) 
     .attr("height", textSize.height); 
    */ 

}

HTML:

<div class="svg-container" id="chartId"></div> 

CSS:

.svg-container { 
    display: inline-block; 
    width: 512px; 
    height: 512px; 
    padding-top: 50px; 
    padding-bottom: 100%; /* aspect ratio */ 
    vertical-align: top; 
    overflow: hidden; 
    border: 1px solid black; 
} 

如何做到這一點任何想法?比我所追蹤的曲目更簡單的方法?

回答

0

我試圖使用tspan.node()。getComputedTextLength()獲得tspan維度,但是這返回了一個錯誤,我推測因爲它沒有在通話時呈現。我只是使用text.node()。getBBox()來獲取每個文本塊的尺寸,而不是:

function renderSVGText(){ 
    var svgArea = d3.select("svg#svg_area_id"); 

    var group = svgArea.append("g") 
     .attr("width", "100%") 
     .attr("height", "100%") 
     .style("stroke", "red") 
     .style("fill", "none"); 

    var text = group.append("text") 
     .attr("y", "0") 
     .attr("font-size",52) 
     .attr("dy", "1em") 
     .attr("id", "text_id") 
     .style('fill', 'black'); 

    var tspan1 = text.append('tspan') 
     .attr("id", "tspan1_id") 
    tspan1.text("This is a square"); 

    var boundingRect = svgArea.append("rect") 
     .style("stroke", "pink") 
     .style("fill", "none"); 

    var textSize = text.node().getBBox(); 
    boundingRect.attr("width", textSize.width) 
     .attr("height", textSize.height); 

    svgArea.append("rect") 
     .attr("x", textSize.width+10) 
     .attr("y", 0) 
     .attr("height", textSize.height) 
     .attr("width", textSize.height) 
     .attr("id", "shape"); 

    var text2 = group.append("text") 
     .attr("x", textSize.width+textSize.height+20) 
     .attr("y", "0") 
     .attr("font-size",52) 
     .attr("dy", "1em") 
     .attr("id", "text2_id") 
     .style('fill', 'black'); 

    var tspan2 = text2.append('tspan') 
    tspan2.text("and this is a triangle"); 
}