23

私はD3でこの問題に何度も遭遇しました。多くの場合、SVG上にHTMLオブジェクトをオーバーレイするのが好きです。

私の現在の戦略は、.html-overlayと呼ばれるSVG要素の横に空のDIVを作成することです。メイングラフィックのSVGで設定した内部パディング(例:20px)に従って配置します。次に、次の関数(jQueryを使用)を使用して、HTML要素をどこに配置するかを判断します。

//element is the object returned by D3 .append()
var getOffset: function(element) {
        var $element = $(element[0][0]);
        return {
            left: $element.offset().left - $('.html-overlay').offset().left,
            top: $element.offset().top - $('.html-overlay').offset().top
        };
    }

要素のオフセットをすばやく取得するには、内部(jQueryに依存しない)方法が必要だと思います。これは非常に便利です(特に、要素が複数の平行移動、回転、スケールなどを通過した後)。

また、要素の「中心」のオフセット、要素の最上点、最下部、左端、右端などを把握するための機能があると便利です。

ノート:

getBoundingClientRect()は、何らかの理由で正しい番号を提供しません。

var $element = $(element[0][0]);

            console.log($element.offset(), element[0][0].getBoundingClientRect())
Object
left: 328
top: 248.8333282470703
__proto__: Object

ClientRect
bottom: 376.83331298828125
height: 139.99998474121094
left: 328
right: 478
top: 236.8333282470703
width: 150
4

3 に答える 3

17

試しましたか

var xywh =element[0][0].getBoundingClientRect();

すべてが入っているように見えますか?(元のソリューションはこの投稿にあります)

于 2012-10-24T01:14:06.083 に答える
11

問題はgetBoundingClientRect、スクロール位置またはドキュメントに対する要素のコンテナ位置を考慮していない にあります。ドキュメントの上と左の座標に対するそのアイテムの正確な位置のみを報告します。

要素の位置を報告する d3 メソッドを作成しました。コンテナー SVG が見つかるまで親要素をループ処理し、その項目の位置を計算で考慮します。から通常受け取るものを返しますgetBoundingClientRect

メソッドは次のとおりです。

d3.selection.prototype.position = function() {

    var el = this.node();
    var elPos = el.getBoundingClientRect();
    var vpPos = getVpPos(el);

    function getVpPos(el) {
        if(el.parentElement.tagName === 'svg') {
            return el.parentElement.getBoundingClientRect();
        }
        return getVpPos(el.parentElement);
    }

    return {
        top: elPos.top - vpPos.top,
        left: elPos.left - vpPos.left,
        width: elPos.width,
        bottom: elPos.bottom - vpPos.top,
        height: elPos.height,
        right: elPos.right - vpPos.left
    };

};

そして、これを次のように使用できます。

d3.select(element).position()

ここでは、スクロール位置を考慮するコードを実際に追加していないことに注意してください。

于 2013-12-05T18:02:08.750 に答える
0

最新バージョンの IE をサポートするために James Lai の回答を拡張する:

function getVpPos(el) {
    if(el.parentNode.nodeName === 'svg') {
        return el.parentNode.getBoundingClientRect();
    }
    return getVpPos(el.parentNode);
}

注: parentElementは parentNode に変更され tagNamenodeName に変更されます

于 2015-02-25T19:06:18.733 に答える