【问题标题】:How do I add a click event to a directed graph using dagre d3.js(javascript library)?如何使用 dagre d3.js(javascript 库)将点击事件添加到有向图?
【发布时间】:2014-11-24 18:40:57
【问题描述】:

我已经能够使用 dagre 绘制有向图。但是,现在我想删除一个节点/边点击它。我可以使用 g.delEdge 和 g.delNode 进行删除,但我如何知道有人点击了该节点?请在下面查看我的 javascript dagre 代码并告诉我需要添加的内容。(我正在从 json 文件中读取所需的节点和边,解析数据并绘制它们)

function MyFunc()
{
var buffer = JSON.parse(data);
var nodesarray = new Array();
for(var i=0;i<Object.keys(buffer[0].nodes).length;i++)
{
 nodesarray.push(buffer[0].nodes[i].name);
}

// Create the input graph
var g = new dagreD3.Digraph();

for(i=0;i<nodesarray.length;i++)
{
 //To give styles to nodes
 //g.addNode(0,  { label: 'Female', labelStyle: 'font-weight: bold;', style: 'stroke: #f66; stroke-width: 10px;', nodeclass: 'type-TOP' });
 g.addNode(nodesarray[i],{label:nodesarray[i]});
}

for(var i=0;i<Object.keys(buffer[0].edges).length;i++)
{ 
 var source = buffer[0].edges[i].source; 
 var destination = buffer[0].edges[i].destination;
 var weight = buffer[0].edges[i].weight;
 var strokewidth = weight*10;
 var mystyle='stroke:#f66; stroke-width:';
 mystyle = mystyle + strokewidth + 'px';

 //To give styles to edges 
 //g.addEdge(null, 5, 7, { style: 'stroke: #f66; stroke-width: 3px;',label: "Label for the edge" });
 g.addEdge(i,source,destination,{style:  mystyle,label:weight});
}

/* Deleting a node/edge example */
//g.delNode(nodesarray[0]);
//g.delNode(nodesarray[1]);
//g.delEdge(0);

// Create the renderer
var renderer = new dagreD3.Renderer();
var l = dagreD3.layout()
              .nodeSep(100)
              .rankSep(200)
              .edgeSep(80)
              .rankDir("LR");
renderer.layout(l);

// Override drawNodes to add nodeclass as a class to each node in the output
// graph.
var oldDrawNodes = renderer.drawNodes();
renderer.drawNodes(function(graph, root) {
  var svgNodes = oldDrawNodes(graph, root);
  svgNodes.each(function(u) { d3.select(this).classed(graph.node(u).nodeclass, true); });
  return svgNodes;
});

// Disable pan and zoom
renderer.zoom(false);
//renderer.edgeInterpolate('linear');

// Set up an SVG group so that we can translate the final graph.
var svg = d3.select('svg'),
    svgGroup = svg.append('g');

// Run the renderer. This is what draws the final graph.
var layout = renderer.run(g, d3.select('svg g'));

// Center the graph
var xCenterOffset = (svg.attr('width') - layout.graph().width) / 2;
svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 80)');
svg.attr('height', layout.graph().height + 200);
}

【问题讨论】:

    标签: javascript d3.js graph onclicklistener dagre-d3


    【解决方案1】:

    我看到您已经重写了添加类选择器的功能,您可以类似地添加点击事件处理程序,请参见以下示例。

        // Override drawNodes to set up the click.
        var oldDrawNodes = renderer.drawNodes();
        renderer.drawNodes(function(g, svg) {
          var svgNodes = oldDrawNodes(g, svg);
    
          // on click event handler
          svgNodes.on('click', function(d) { console.log('Clicked on node - ' + d); });
    
          return svgNodes;
        });
    

    要为边缘添加点击事件处理程序,请尝试以下代码

        var oldDrawEdges = renderer.drawEdgePaths();
        renderer.drawEdgePaths(function(g, svg) {
            var edges = oldDrawEdges(g, svg);
            edges.on('click', function (edgeId) { alert('Clicked on - ' + edgeId);});
            return edges;
        });
    

    【讨论】:

    • 哇哦!有用。但我有几个问题。 1. .on 是 dagre 中的函数还是来自 svg?它的文档在哪里?如果它来自 svg,我可以在 dagre 中使用所有 svg 函数吗? 2. 我尝试通过将renderer.drawNodes 替换为renderer.drawEdge 来使边缘可点击。但它不起作用。如何使边缘可点击?
    • 我认为 'on' 功能来自 SVG。我实际上浏览了 D3 资源并尝试了它。您可以尝试在 D3 源中查找“defaultDrawNodes”,并查看节点是如何绘制的。对于边缘,您可能必须尝试覆盖“drawEdgePaths”,我自己没有尝试过,但它应该可以工作。尝试在 D3 源中查找“defaultDrawEdgePaths”,以查看边缘是如何绘制的。
    • 我尝试了边缘的单击事件处理程序并且它有效,请参阅我更新的帖子。
    • 我要纠正自己,'on' 函数不是 SVG 函数,而是来自 D3,您可以在 D3 Wiki - github.com/mbostock/d3/wiki/Selections#on 上找到 API 参考
    • 工作,谢谢...但我在这里有点困惑,drawEdgePaths 是来自 dagre 的函数,但 .on 来自 d3?嗯……能用一两行解释上面的代码sn-p吗?我想我无法理解 dagre,d3 和 svg 是如何共存的。 2.另外,是否可以在事件中编辑已绘制节点的样式?即,我已经使用 g.addNode(nodesarray[i],{label:nodesarray[i]}); 绘制了一个节点,假设我想在单击时更改节点的颜色,是否必须删除节点然后将其重绘为 g.addNode(0, { nodeclass: 'some-class-in-css' });或者可以直接编辑吗?
    【解决方案2】:

    这对我处理节点点击有用:

    svg.selectAll("g.node").on("click", function(id) {
      console.log("Clicked " + id);
    });
    

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2013-04-10
      • 2010-12-09
      相关资源
      最近更新 更多