2

我正在尝试基于 M Bostock ( http://bl.ocks.org/mbostock/7607999 ) 实现创建一个动态分层边缘捆绑:

在此处输入图像描述

我的数据集的 bl.ocks 版本在这里:http ://bl.ocks.org/ratnakarv/91ace0b5f77fff5ef0ab

与原来的节点 1 和节点 2 之间的关系是一种方式(即节点 1 可以导入节点 2 或其他方式)不同,在我的数据集中,节点 1 和节点 2 可以有两种方式的导入关系。这在业务流程中经常发生,这就是我的应用程序。

  • 当前挑战:

在此示例中,“评估”导入“创建 QOS 降级报告”,“创建 QOS ...”也导入“评估”。但是当鼠标悬停时,'Assess', node - 'Create..' 显示为红色,但线为绿色。当鼠标悬停在节点“创建...”上时,导入行以及“评估”显示为红色。

  • 所需要求:

我的要求是,如果存在双向导入,则 - 1. 线以及其他节点以第三种颜色显示(红色或绿色除外)或 2. 线以及其他节点显示为红色.

对此的任何指示都会有所帮助。我有 D3 的基本知识,但我不是数据可视化专家,我只是尝试在我的工作领域中使用可视化来更好地沟通。

4

1 回答 1

3

有几种方法可以解决这个问题,但这是我目前能想到的最简单的一种。

请注意,在您的块之间和块之间有两条路径具有相等但相反的值(因为它们既是彼此的源是目标)。其中一个恰好放在另一个之上,使它们看起来像是一条路径。这就是为什么这两个节点之间的链接有些参差不齐,而其他节点却是平滑的。也许我们可以利用这一点。AssessCreate QoS Degradation Report

如果您调整 CSS 的定义,link--source使其link--target不透明度值小于 1,则部分透明的源链接将与部分透明的目标链接重叠,从而呈现“新”的不同颜色的外观。

至于节点颜色,使用“新”颜色创建一个新的 CSS 类,如果在函数中两者都为真,node--both则将其应用于节点。n.sourcen.targetmousovered

node
    .classed("node--both", function(n) { return n.source && n.target; })
    .classed("node--target", function(n) { return n.target; })
    .classed("node--source", function(n) { return n.source; });

这并不完美,但这里有一个小提琴证明了这一点:http: //jsfiddle.net/w2rfwokx/

关键是适当地选择源链接和目标链接的颜色和不透明度值(我没有这样做),以便获得与源链接和目标链接足够不同的新颜色,并且无论是源链接还是目标链接,颜色都相同目标链接在“顶部”。在当前的 fiddle 版本中,您可以看到颜色略有不同,具体取决于哪个节点处于活动状态。这个线程或类似的东西可能会有所帮助。

您还可以尝试操作links数组以将两个相同的路径合并为一个,并添加一个属性以指示这是一个源和目标链接,并在稍后处理时使用此属性。

更新:您的评论中有正确的想法。无论如何,颜色技巧更像是一种黑客行为。

links数组包含两个项目,用于双向导入节点之间的一条路径。让我们删除其中一个并在另一个中设置一个属性以指示这是双向导入。

var unique_links = links.reduce(function(p,c) {
    var index=p.map(function(d,i) { if(d.source===c.target && d.target===c.source) return i;}).shift();
    if(!isNaN(index)) p[index].both=true; else p.push(c);
    return p;
 },[]);

现在unique_links每条边只有一个元素,而那个元素有both=true. 让我们也将both属性传递给捆绑布局。

link = link
      .data(bundle(unique_links))
    .enter().append("path")
      .each(function(d) {
        d.source = d[0], 
        d.target = d[d.length - 1],
        d.both = unique_links.filter(function(v) { if (v.source===d.source && v.target===d.target) return v.both; }).shift();
      })
      .attr("class", "link")
      .attr("d", line);

最后一步是更改mouseovered函数以使用不同的颜色设置新的 CSS 类both

function mouseovered(d) {
  node
      .each(function(n) { n.target = n.source = false; });

  link
      .classed("link--both", function(l) { if((l.target===d || l.source===d) && l.both) return l.source.source = l.source.target = l.target.source = l.target.target = true;})
      .classed("link--target", function(l) { if (l.target === d && !l.both) return l.source.source = true; })
      .classed("link--source", function(l) { if (l.source === d && !l.both) return l.target.target = true; })
    .filter(function(l) { return l.target === d || l.source === d; })
      .each(function() { this.parentNode.appendChild(this); });

  node
      .classed("node--both", function(n) { return n.target && n.source; })
      .classed("node--target", function(n) { return n.target; })
      .classed("node--source", function(n) { return n.source; });
}

并重置类mouseouted

function mouseouted(d) {
  link
      .classed("link--both", false)
      .classed("link--target", false)
      .classed("link--source", false);

  node
      .classed("node--both", false)
      .classed("node--target", false)
      .classed("node--source", false);
}

记得在 CSS 中定义新的类:

.link--both {
  stroke: orange;
}

.node--both {
  fill: orange;
}

这是完整代码的更新小提琴:http: //jsfiddle.net/w2rfwokx/1/

于 2014-10-03T04:54:09.787 回答