2016-06-16 11 views
0

私はD3.jsを初めて使用しており、これを使ってこのJSFiddleのツリーダイアグラムを作成しています(これは私のものではなく、私のように見える)。簡単なD3ヒントイベントトリガーのためにD3パスリンクの疑似エリアを増やす

私はツリー内のパスリンク上でホバリングしたときにトリガされるツールチップを作成するためにD3-tipを使用しようとしています。しかし、パス要素の実際のサイズは非常に小さいので、トリガするのは非常に困難です。

これらのイベントをトリガーするのが簡単になるように、D3パス要素の領域を透過的に、またはJavaScriptから増やす方法はありますか?私はherehereなどの他のSOの例を見てきましたが、JavaScriptで正しく実装できません。私は明らかにパス要素のストロークを増やそうとしましたが、これは愚かに見えます。

ありがとうございます。

私のコードは、以下である:

export function createTree(json) { 
    var width = 600; 
    var height = 300; 
    var maxLabel = 120; 
    var duration = 200; 
    var radius = 8; 

    var i = 0; 
    var root; 

    var tree = d3.layout.tree() 
     .size([height - 20, width - 20]); 

    var diagonal = d3.svg.diagonal() 
     .projection(function (d) { 
      return [d.y, d.x]; 
     }); 

    var tip = d3.tip() 
     .attr('class', 'd3-tip') 
     .html(function(d) { 
      var html = "<div id='popover-permission' align='center'> <div class='col-md-12'>" + 
       "<div class='row text-center'><span style='color:#444444;'>Distribution Contract:</span><br>" + 
      "<span class='textSmall' style='color:#444444;'>" + "3473247xxx78728347" + "</span></div></div></div>"; 

     return html; 
    }) 

var svg = d3.select("#tree") 
    .append("div") 
    .classed("svg-container", true) //container class to make it responsive 
    .append("svg") 
    //responsive SVG needs these 2 attributes and no width and height attr 
    .attr("preserveAspectRatio", "xMinYMin meet") 
    .attr("viewBox", "0 0 " + width + " " + height) 
    //class to make it responsive 
    .classed("svg-content-responsive", true) 
    .append("g") 
    .attr("transform", "translate(" + maxLabel + ",0)"); 

svg.call(tip); 

root = json; 
root.x0 = height/2; 
root.y0 = 0; 

function update(source) { 
    // Compute the new tree layout. 
    var nodes = tree.nodes(root).reverse(); 
    var links = tree.links(nodes); 

    // Normalize for fixed-depth. 
    nodes.forEach(function (d) { 
     d.y = d.depth * maxLabel; 
    }); 

    // Update the nodes… 
    var node = svg.selectAll("g.node") 
     .data(nodes, function (d) { 
      return d.id || (d.id = ++i); 
     }); 

    // Enter any new nodes at the parent's previous position. 
    var nodeEnter = node.enter() 
     .append("g") 
     .attr("class", "node") 
     .attr("transform", function (d) { 
      return "translate(" + source.y0 + "," + source.x0 + ")"; 
     }) 
     .on("click", click); 

    nodeEnter.append("circle") 
     .attr("r", 0) 
     .style("fill", function (d) { 
      return d._children ? "lightsteelblue" : "white"; 
     }); 

    nodeEnter.append("text") 
     .attr("text-anchor", "middle") 
     .attr('x', 0) 
     .attr('y', 30) 
     .attr("dy", "-30") 
     .attr("class", "node-text textSmall") 
     .append('tspan') 
     .attr('x', 0) 
     .attr('dy', 10) 
     .text(function(d) { return d.name; }) 
     .append('tspan') 
     .attr('x', 0) 
     .attr('dy', 20) 
     .attr("class", "textSmall tree-balance") 
     .text(function(d) { 
      return "(" + d.value + " ETH)"; 
     }) 

    // Transition nodes to their new position. 
    var nodeUpdate = node.transition() 
     .duration(duration) 
     .attr("transform", function (d) { 
      return "translate(" + d.y + "," + d.x + ")"; 
     }); 

    nodeUpdate.select("circle") 
     .attr("r", function (d) { 
      return computeRadius(d); 
     }) 
     .style("fill", function (d) { 
      return d._children ? "lightsteelblue" : "#fff"; 
     }); 

    nodeUpdate.select("text").style("fill-opacity", 1); 

    // Transition exiting nodes to the parent's new position. 
    var nodeExit = node.exit().transition() 
     .duration(duration) 
     .attr("transform", function (d) { 
      return "translate(" + source.y + "," + source.x + ")"; 
     }) 
     .remove(); 

    nodeExit.select("circle").attr("r", 0); 
    nodeExit.select("text").style("fill-opacity", 0); 

    // Update the links… 
    var link = svg.selectAll("path.link") 
     .data(links, function (d) { 
      return d.target.id; 
     }); 

    // Enter any new links at the parent's previous position. 
    link.enter().insert("path", "g") 
     .attr("class", "link") 
     .attr("id", function(d) { 
      return d.target.address; 
     }) 
     .attr("d", function (d) { 
      //console.log(d.source.name + d.target.name + " "); 
      var o = {x: source.x0, y: source.y0}; 
      return diagonal({source: o, target: o}); 
     }) 
     .on('mouseover', tip.show) 
     .on('mouseleave', tip.hide); 

    // Transition links to their new position. 
    link.transition() 
     .duration(duration) 
     .attr("d", diagonal); 

    // Transition exiting nodes to the parent's new position. 
    link.exit().transition() 
     .duration(duration) 
     .attr("d", function (d) { 
      var o = {x: source.x, y: source.y}; 
      return diagonal({source: o, target: o}); 
     }) 
     .remove(); 

    // Stash the old positions for transition. 
    nodes.forEach(function (d) { 
     d.x0 = d.x; 
     d.y0 = d.y; 
    }); 
} 

function computeRadius(d) { 
    if (d.children || d._children) return radius + (radius * nbEndNodes(d)/10); 
    else return radius; 
} 

function nbEndNodes(n) { 
    nb = 0; 
    if (n.children) { 
     n.children.forEach(function (c) { 
      nb += nbEndNodes(c); 
     }); 
    } 
    else if (n._children) { 
     n._children.forEach(function (c) { 
      nb += nbEndNodes(c); 
     }); 
    } 
    else nb++; 

    return nb; 
} 

function click(d) { 
    if (d.children) { 
     d._children = d.children; 
     d.children = null; 
    } 
    else { 
     d.children = d._children; 
     d._children = null; 
    } 
    update(d); 
} 

function collapse(d) { 
    if (d.children) { 
     d._children = d.children; 
     d._children.forEach(collapse); 
     d.children = null; 
    } 
} 

update(root); 

}

編集:私はまたthis解決策を見つけたので、など各パスに透明な線を追加した:

lines = gEnter 
    .selectAll('.path').data(['visible', 'invisible']) 
lines.enter() 
    .append('line') 
    .attr('class', 'path') 
    .attr('marker-end', function(d, i, j) { 
     // j is the parent's i 
     if (j === 2) { 
      return 'url(#arrow)'; 
     } else { 
      return null; 
     } 
    }) 
.attr({ 
    // returning null from these functions simply defaults to whatever the 
    // .path class's CSS props are doing 
    'stroke-width': function(d, i) { return d == 'invisible' ? 10 : null }, 
    'stroke': function(d, i) { return d == 'invisible' ? 'transparent' : null } 
}) 

ものであり、線が描画されても、ブラウザの要素として表示されないため、領域にはまったく影響しません。これを変更する方法はありますか?

+0

私はあなたの目に見える線の上に透明な線を描画しようとし、透明な線にマウスイベントを追加しようとします。私はあなたのEDITでこれを言及参照してくださいが、あなたはラウンドに近い方法を取っているように見えます。可視線を追加するのとまったく同じ方法で透明線を追加してください。あなたの特定のコードのフィドルを提供するなら、喜んで助けてください。 – wdickerson

答えて

0

これは私がやったことです:私はすべて同じ属性を持つが、私はCSSで次のように設定する別のクラスで、link2としてあなたlinkを重複:

.link2{ 
    fill: none; 
    stroke: lightgray; 
    stroke-width: 20px; 
    opacity: 0; 
} 

次のパスにホバータイトルを見る。ここでは、フィドルです:http://jsfiddle.net/gerardofurtado/JnNwu/1025/

関連する問題