2016-12-23 6 views
1

Я использую эту реализацию макета D3 дерева:Как определить, является ли узел D3 дерева выходит за пределами SVG контейнер

http://bl.ocks.org/robschmuecker/7880033

Я получил мое дерево в ответ на внешние события, и для этого, Я хотел бы знать, является ли какой-то определенный узел невидимым (за пределами контейнера svg), чтобы я мог, например, повторно загрузить его.

После некоторых исследований я нашел этот SO ответ, который выглядел именно то, что мне было нужно:

Getting Screen Positions of D3 Nodes After Transform

При перемещении узла в верхнем левом углу и нажав на него, я бы ожидать, что координаты будет [ 0,0]. Но по какой-то причине координата x всегда ошибочна довольно большим смещением. Сделана скрипка об этом здесь:

https://jsfiddle.net/syberyan/yd8L4v0q/

Я изменил функцию мыши(), так что он выводит координаты целевого узла.

function getElementCoords(element, coords) { 
    var ctm = element.getCTM(), 
    x = ctm.e + coords.x*ctm.a + coords.y*ctm.c, 
    y = ctm.f + coords.x*ctm.b + coords.y*ctm.d; 
    return {x: x, y: y}; 
}; 

function click(d) { 
    if (d3.event.defaultPrevented) return; // click suppressed 
    d3.selectAll('.node').each(function (node, i) { 
    if (d === node) { 
     let coords = getElementCoords(this, node); 
     console.log(coords.x, coords.y); // shows coords relative to my svg container 
    } 
    }); 
} 

Я новичок в D3, поэтому я, вероятно, сделал что-то не так, но что? Или, может быть, есть лучший способ сделать это?

ответ

0

Я не слишком внимательно смотрел на связанный вопрос или ваши текущие расчеты. Вместо этого, я думаю, что расчеты могут быть упрощена:

function getElementCoords(element) {  
    // translate on node 
    var trans = d3.transform(d3.select(element).attr('transform')).translate, 
     // transform on parent "zoom" container 
     transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')), 
     // translate on zoom container 
     transParent = transFormParent.translate, 
     // scale on zoom container 
     scaleParent = transFormParent.scale, 
     // final position of node 
     pos = { 
     x: trans[0] + transParent[0]/scaleParent[0], 
     y: trans[1] + transParent[1]/scaleParent[1] 
     }; 

    return pos; 
} 

Вызов как:

function click(d) { 
    console.log(getElementCoords(this)); 
} 

Обновлено fiddle.

редактирует

@Christian отметил в комментариях, моя математика была выключена, должно быть:

function getElementCoords(element) {  
    // translate on node 
    var trans = d3.transform(d3.select(element).attr('transform')).translate, 
     // transform on parent "zoom" container 
     transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')), 
     // translate on zoom container 
     transParent = transFormParent.translate, 
     // scale on zoom container 
     scaleParent = transFormParent.scale, 
     // final position of node 
     pos = { 
     x: trans[0] * scaleParent[0] + transParent[0], 
     y: trans[1] * scaleParent[1] + transParent[1] 
     }; 

    return pos; 
} 
+0

Кажется, работает, но не после масштабирования. Координаты слишком большие, должно быть проблемой при расчете шкалы. – Christian

+1

Это, кажется, чтобы сделать работу: 'Coords = { х: транс [0] * scaleParent [0] + ПРОЗРАЧНЫЙ [0], у: транс [1] * scaleParent [1] + ПРОЗРАЧНЫЙ [1] } ; ' – Christian

+0

@ Христиан, ох, мой плохой. Спасибо, что поймал это. Я обновил свой ответ с исправленной математикой для потомков. – Mark

 Смежные вопросы

  • Нет связанных вопросов^_^