2014-10-11 30 views
2

我與D3.js力圖形工作,但我無法找出從元件位置的元素ID(我知道讓網絡元素(ID) )。如何從D3.js力圖形元素位置

我使用的大躍進運動。我需要在沒有鼠標的情況下模擬鼠標事件(點擊,移動,拖動等)。而且,如果我是對的,爲了能夠做到這一點,我需要找出座標x和y中的元素id是什麼(我從Leap運動指針中知道這些座標)。所以從你上面寫的,我需要找出('.node')。 以下是我已經嘗試過,但沒有奏效:

Is it possible to use non-mouse, non-touch events to interact with a D3.js graph? If so, what is the most efficient way to go about it?

所以我用這個函數(見下文),但我需要知道元素的id,使其正常工作:

//graph.simulate(document.getElementById("r_1"), 'dblclick', {pointerX: posX, pointerY: posY}); 
//here id r_1 is hardcoded, but I need to find out id from x and y coordinates. 

this.simulate = function (element, eventName) { 
    function extend(destination, source) { 
     for (var property in source) 
      destination[property] = source[property]; 
     return destination; 
    } 

    var eventMatchers = { 
     'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, 
     'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/ 
    }; 

    var defaultOptions = { 
     pointerX: 0, 
     pointerY: 0, 
     button: 0, 
     ctrlKey: false, 
     altKey: false, 
     shiftKey: false, 
     metaKey: false, 
     bubbles: true, 
     cancelable: true 
    }; 

    var options = extend(defaultOptions, arguments[2] || {}); 
    var oEvent, eventType = null; 

    for (var name in eventMatchers) { 
     if (eventMatchers[name].test(eventName)) { 
      eventType = name; 
      break; 
     } 
    } 

    if (!eventType) 
     throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported'); 

    if (document.createEvent) { 
     oEvent = document.createEvent(eventType); 
     if (eventType == 'HTMLEvents') { 
      oEvent.initEvent(eventName, options.bubbles, options.cancelable); 
     } 
     else { 
      oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView, 
       options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY, 
       options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element); 
     } 
    element.dispatchEvent(oEvent); 
    } 
    else { 
     options.clientX = options.pointerX; 
     options.clientY = options.pointerY; 
     var evt = document.createEventObject(); 
     oEvent = extend(evt, options); 
     element.fireEvent('on' + eventName, oEvent); 
    } 
    return element; 
} 

非常感謝您的幫助和意見。

+0

我用另一個解決方案編輯了我的答案。看一看。 – 2014-10-12 21:22:40

回答

2

如果你想訪問的元素,它在D3的迭代器通過this是隱含的。

d3.selectAll('.node').each(function(d) { 
    console.log(this); // Logs the element attached to d. 
}); 

如果你真的需要訪問ID,您可以用selection.attr()得到它:

d3.selectAll('.node').each(function() { 
    console.log(d3.select(this).attr('id')); // Logs the id attribute. 
}); 

您不必使用each。任何迭代器,如attrstyle等,有「本」爲綁定元素:

d3.selectAll('.node').style('opacity', function(d) { 
    console.log(this);// Logs the element attached to d. 
}); 

如果你想在x和節點y座標,它的部分數據:

d3.selectAll('.node').each(function(d) { 
    console.log(d.x, d.y); // Logs the x and y position of the datum. 
}); 

如果你真的需要的節點屬性本身,你可以使用attr訪問。

d3.selectAll('.node').each(function(d) { 
    // Logs the cx and cy attributes of a node. 
    console.log(d3.select(this).attr('cx'), d3.select(this).attr('cy')); 
}); 

編輯:它看起來像你需要一個元素的引用,但你知道在上下文中節點的唯一事情是它的位置。一種解決方案是搜索所有節點上的匹配座標的節點。

// Brute force search of all nodes. 
function search(root, x, y) { 
    var found; 
    function recurse(node) { 
    if (node.x === x && node.y === y) 
     found = node; 
    !found && node.children && node.children.forEach(function(child) { 
     recurse(child); 
    }); 
    } 
    recurse(root); 
    return found; 
} 

但是,這隻給你節點對象,而不是元素本身。您可能需要的元素的引用存儲節點上:

// Give each node a reference to its dom element. 
d3.selectAll('.node').each(function(d) { 
    d.element = this; 
}); 

有了到位,你應該能夠訪問元素,並獲得其ID。

var id, node = search(root, x, y); 
if (node) { 
    id = node.element.getAttribute('id'); 
} 

的強力搜索是罰款少數節點,但如果你推大量節點的您可能需要使用D3的quadtree(example)以加快搜索。

+0

我編輯的問題更具體,請看看它。謝謝 – Jirka 2014-10-12 16:46:14

+0

非常感謝:-)它可以工作,但即使我沒有使用最後一個解決方案,也存在一些性能問題。這可能與跳躍運動裝置有關。 – Jirka 2014-10-18 13:47:14

2

使用d3.select( '#yourElementId')

欲瞭解更多信息檢查了這一點:https://github.com/mbostock/d3/wiki/Selections

+0

我不知道elementId,這正是我想要從x和y座標中找到的。 – Jirka 2014-10-11 19:00:35

+0

對不起,我還沒有很好地理解你的問題。也許你應該嘗試遍歷所有的元素,並檢查你的座標是否在元素內。 – slotomo 2014-10-11 19:25:39