2017-05-11 4 views
1

D3で強制有向グラフを作成しようとしています。今のように、ノードの半径はJSON にキー値ペアに依存 (d.size)D3ノードの半径はリンクの数に依存します:weightプロパティ

Iカウントするために使用することができるd3.weight性を認識してよリンクの数は円のの半径属性と関連付けます、しかし私はどういうわけかそれを動作させることができませんでした。

私にこれを手伝ってください。

以下のコード検索:

d3.json('graph.json', (error, graph) => { 
    const width = 1200; 
    const height = 900; 

    const simulation = d3.forceSimulation() 
    .nodes(graph.nodes) 
    .force('link', d3.forceLink().id(d => d.id)) 
    .force('charge', d3.forceManyBody().strength([-605])) 
    .force('center', d3.forceCenter(width/2, height/2)) 
    .on('tick', ticked); 

    simulation.force('link') 
    .links(graph.links) 
    .distance([140]); 

    const R = 30; 

    const svg = d3.select('body').append('svg') 
    .attr('width', width) 
    .attr('height', height); 

    // add defs-marker 
    // add defs-markers 
    svg.append('svg:defs').selectAll('marker') 
    .data([{ id: 'end-arrow', opacity: 1 }, { id: 'end-arrow-fade', opacity: 0.1 }]) 
    .enter().append('marker') 
     .attr('id', d => d.id) 
     .attr('viewBox', '0 0 10 10') 
     .attr('refX', 2 * R) 
     .attr('refY', 5) 
     .attr('markerWidth', 4) 
     .attr('markerHeight', 4) 
     .attr('orient', 'auto') 
     .append('svg:path') 
     .attr('d', 'M0,0 L0,10 L10,5 z') 
     .style('opacity', d => d.opacity); 

    let link = svg.selectAll('line') 
    .data(graph.links) 
    .enter().append('line'); 

    link 
    .attr('class', 'link') 
    .attr('marker-end', 'url(#end-arrow)') 
    .on('mouseout', fade(1)); 

    let node = svg.selectAll('.node') 
    .data(graph.nodes) 
    .enter().append('g') 
    .attr('class', 'node'); 

    node.append('circle') 
    .attr('r', function (d) { 
       return (d.size * 12); 
      }) 
    .on('mouseover', fade(0.1)) 
    .on('mouseout', fade(1)) 
    .call(d3.drag() 
     .on("start", dragstarted) 
     .on("drag", dragged) 
     .on("end", dragended)); 

    node.append('text') 
    .attr('x', 0) 
    .attr('dy', '.35em') 
    .text(d => d.name); 

    function ticked() { 
    link 
     .attr('x1', d => d.source.x) 
     .attr('y1', d => d.source.y) 
     .attr('x2', d => d.target.x) 
     .attr('y2', d => d.target.y); 

    node 
     .attr('transform', d => `translate(${d.x},${d.y})`); 
    } 


    function dragstarted(d) { 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
    } 

    function dragged(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
    } 

    function dragended(d) { 
    if (!d3.event.active) simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
    } 

    const linkedByIndex = {}; 
    graph.links.forEach(d => { 
    linkedByIndex[`${d.source.index},${d.target.index}`] = 1; 
    }); 

    function isConnected(a, b) { 
    return linkedByIndex[`${a.index},${b.index}`] || linkedByIndex[`${b.index},${a.index}`] || a.index === b.index; 
    } 

    function fade(opacity) { 
    return d => { 
     node.style('stroke-opacity', function (o) { 
     const thisOpacity = isConnected(d, o) ? 1 : opacity; 
     this.setAttribute('fill-opacity', thisOpacity); 
     return thisOpacity; 
     }); 

     link.style('stroke-opacity', o => (o.source === d || o.target === d ? 1 : opacity)); 
     link.attr('marker-end', o => (opacity === 1 || o.source === d || o.target === d ? 'url(#end-arrow)' : 'url(#end-arrow-fade)')); 
    }; 
    } 
}) 

JSONの構造は以下の通りです:

{ 
    "nodes": [ 
     { 
      "name": "A", 
      "id": 0, 
      "size": 1 
     }, 
     { 
      "name": "D", 
      "id": 1, 
      "size": 2 
     }, 
     { 
      "name": "K", 
      "id": 2, 
      "size": 3 
     } 
    ], 
    "links": [ 
     { 
      "source": 0,  //id of the soure application 
      "target": 1  //id of the destination application 
     }, 
     { 
      "source": 0, 
      "target": 2 
     }, 
     { 
      "source": 3, 
      "target": 4 
     } 
    ] 
} 
+0

* *「私はリンクの数をカウントするために使用することができますd3.weightプロパティを知ってる」...だけでなく、何の 'd3.weightはありません'D3 v4.xでは。 –

+0

@GerardoFurtadoその情報をありがとう!本当に助けました:) –

答えて

1

d3.v4は、重量プロパティをサポートしていません。だから私は自分でノードの重みを計算しなければならないと思います。このようにしてください。

d3.v3では、we3はweightプロパティを持ち、次のように使用できます。

node.append("circle") 
    .attr("r", function(d) { 
    var minRadius = 10; 
    return minRadius + (d.weight * 2); 
    }); 

フィドル例 - https://jsfiddle.net/gilsha/9d6edrte/

+0

あなたのお返事ありがとうございます。最初の解決策は私のためにうまくいきませんでした! –

+0

回避策ができるように、フィドルを作成できますか? – Gilsha

+0

私はフィドルを作成し、ランダムなデータで正常に動作するようです。 https://jsfiddle.net/gilsha/n4m1r8nb/214/ – Gilsha

関連する問題