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]
});
};
さて、これまでのところ、とても良いです-ベジェのコントロールハンドルが私が望む場所にないことを除いて。たとえば、ノード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>
これにより、例のページから樹状図のように見えます。折りたたみ可能な樹状図の例で私が気付いたのは、軸の反転を返すことです。
return [d.y, d.x]
しかし、これを行うと、コントロールポイントが希望どおりに配置されている間、ポイントの位置が狂ってしまいます(つまり、x / y座標も逆になり、効果的に変換されます。
他の誰かがこのような問題に遭遇したか、それを修正する方法のアイデアを持っていますか?