我正在从D3开始绘制网络图(我不喜欢Force Directed的输出)。为此,我生成了一个节点数组,每个节点都有一个x / y坐标。
{
"nodes" : [
{
"name" : "foo",
"to" : ["bar"]
},
{
"name" : "bar",
"to" : ["baz"]
},
{
"name" : "baz"
}
]
}
然后我生成一个带有父svg:g的svg,并将此数据绑定到一系列挂在父节点上的svg:g元素。
addSvg = function () {
// add the parent svg element
return d3.select('#visualisation')
.append('svg')
.attr('width', width)
.attr('height', height);
};
addSvgGroup = function (p) {
// add a containing svg:g
return p.append('svg:g').
attr('transform', 'translate(0,0)');
};
addSvgNodes = function(p, nodes) {
// attach all nodes to the parent p data
// and render to svg:g
return p.selectAll('g')
.data(nodes)
.enter()
.append('svg:g')
.attr('class', 'node');
};
然后我手动定位节点(这将是后来的动态,我只是站起来)
transformNodes = function (nodes) {
// position nodes manually
// deprecate later for column concept
nodes.attr('transform', function (o, i) {
offset = (i + 1) * options.nodeOffset;
// options.nodeOffset = 150
o.x = offset;
o.y = offset / 2;
return 'translate(' + offset + ',' + offset / 2 + ')';
});
};
然后我将这些项目附加到父svg:g,并挂掉一些文本。 这导致在svg内从左到右下降的文本阶梯。到目前为止,非常好。
接下来,我想生成一些链接,因此我使用一种方法来确定当前节点是否有关系,然后获取该节点的位置。最后,我使用d3.svg.diagonal生成一系列链接,并将其源/目标设置为适当的节点。为了清晰起见书面的手写。
getLinkGenerator = function (o) {
return d3.svg.diagonal()
.source(o.source)
.target(o.target)
.projection(function (d) {
console.log('projection', d);
return [d.x, d.y]
});
};
现在,到目前为止,这么好 - 除了bezier的控制手柄不是我想要的。例如,从节点A到节点B,路径d属性是:
<path d="M150,75C150,112.5 300,112.5 300,150" style="fill: none" stroke="#000"></path>
但我希望它改变控制手柄的方向 - 即
<path d="M150,75C200,75 250,150 300,150" style="fill: none" stroke="#000"></path>
这会使它看起来更像是示例页面中的dendrograph。我在折叠式dendrograph示例中注意到它返回轴的反转:
return [d.y, d.x]
但是如果我这样做,虽然控制点是我想要的,但是点的位置是不正常的(即它们的x / y坐标也是相反的,有效地翻译它们。
是否有其他人遇到过这样的问题,或者想知道如何修复它?
答案 0 :(得分:1)
好的,所以我看了一眼就找到了解决方案。看起来有些布局(树状图,折叠树)正在反转路径链接中源/目标的坐标,这样当它们点击投影调用时,它们会反转回正确的位置,但是方向为他们的bezier点旋转。
因此,如果您正在手动设置自定义布局并且想要水平定位贝塞尔控件(如示例),那就是您需要做的事情。