D3 を使用して、css web-font スタイルの svg テキスト要素を次々と配置する際に問題が発生しています。ロード時にテキスト要素を最初に配置すると、それらが重なります。
ただし、遅延またはボタンを介してトリガーされた同じ関数を使用して要素を少し後に配置すると、それらは重なりません。
問題はgetBBox()
あり、getBoundingClientRect()
どちらも最初は要素の適切な幅を返さないようです。
最初に正しい幅を取得する方法についてのアイデアはありますか?
JS は以下、例はこちら: http://bl.ocks.org/yanofsky/6618496 、完全なコードはこちら: https://gist.github.com/yanofsky/6618496
//helper function to grab transform coordinates
function transformCoordOf(elem) {
var separator = elem.attr("transform").indexOf(",") > -1 ? "," : " ";
var trans = elem.attr("transform").split(separator);
return { x: (trans[0] ? parseFloat(trans[0].split("(")[1]) : 0), y: (trans[1] ? parseFloat(trans[1].split(")")[0] ): 0) };
}
//position the elements based on the one before it
function positionElements() {
txts.filter(function(d,i){return i != 0}) //filter out the first element
.attr("transform",function(d,i){
var prev = d3.select(txts[0][i]), //use i b/c the list shifts on filter
prevWidth = parseFloat(prev.node().getBoundingClientRect().width)
prevCoords = transformCoordOf(prev);
var cur = d3.select(this),
curWidth = parseFloat(cur.node().getBoundingClientRect().width)
curCoords = transformCoordOf(cur);
var y = prevCoords.y,
x = prevCoords.x + prevWidth + 10;
return "translate("+x+","+y+")";
})
}
var names = ["apples","oranges","bananas"]
var canvas = d3.select("#content")
.append("svg")
.attr("width","600px")
.attr("height","100px");
var txts = canvas.selectAll("text").data(names)
.enter()
.append("text")
.attr("transform","translate(10,50)")
.text(function(d){return d});
positionElements()
d3.select("button").on("click",function(){positionElements()})