2016-10-03 5 views
1

현재 각 노드에 호버 효과와 범례의 각 요소에 대한 호버 효과가 있습니다.D3.js - 범례와 상호 작용할 때 차트 요소 강조 표시

사용자가 범례와 상호 작용할 때 효과를 실행하여 차트의 관련 노드가 강조 표시되고 반대의 경우도 마찬가지입니다. 나는 또한 효과를 켜거나 끄고 싶다.

사용자가 노드를 클릭하거나 가리키면 관련된 범례 항목이 회색으로 강조 표시됩니다.

사용자가 범례 항목을 클릭하거나 가리킬 때 관련 노드가 검은 색 선으로 강조 표시됩니다.

다음 (Selectable Elements)을 보았지만이 코드를 내 코드에 적용하는 방법을 찾을 수 없습니다.

토글시 마우스 오버시 &에서 관련된 요소에 클래스 (.selected와 같은)를 적용해야한다는 것을 지금까지 이해했습니다.

JSFiddle

많은 감사

//Nodes V2 

var width = 300, 
    height = 300, 
    colors = d3.scale.category20b(); 

var force = d3.layout.force() 
    .gravity(.2) 
    .charge(-3000) 
    .size([width, height]); 

//Svg Chart SVG Settings 
var svg = d3.select("#chart").append("svg:svg") 
    .attr("width", width) 
    .attr("height", height); 

var root = getData(); 
var nodes = flatten(root), 
    links = d3.layout.tree().links(nodes); 

nodes.forEach(function(d, i) { 
    d.x = width/2 + i; 
    d.y = height/2 + 100 * d.depth; 
}); 

root.fixed = true; 
root.x = width/2; 
root.y = height/2; 

force.nodes(nodes) 
    .links(links) 
    .start(); 

var link = svg.selectAll("line") 
    .data(links) 
    .enter() 
    .insert("svg:line") 
    .attr("class", "link"); 

var node = svg.selectAll("circle.node") 
    .data(nodes) 
    .enter() 
    .append("svg:circle") 
    .attr("r", function(d) { return d.size/200; }) 
    //.attr('fill', function(d) { return d.color; }) // Use Data colors 
    .attr('fill', function(d, i) { return colors(i); }) // Use D3 colors 
    .attr("class", "node") 
    .call(force.drag) 

    .on('click', function(){ 
     d3.select(function (d){ 
      return i.li; 
     }) 
      .style('background', '#000')  
    }) 

//Adding an event - mouseover/mouseout 
    .on('mouseover', function(d) { 

     d3.select(this) 
      .transition()//Set transition 
       .style('stroke', '#222222') 
       .attr("r", function(d) { return (d.size/200) + 2; }) 
    }) 

    .on('mouseout', function(d) { 

     d3.select(this) 
      .transition() 
       .style('stroke', '#bfbfbf') 
       .attr("r", function(d) { return (d.size/200) - 2; }) 

     d3.select('ul')   
    }); 

//Add a legend 
var legend = d3.select('#key').append('div') 
    .append('ul') 
    .attr('class', 'legend') 
    .selectAll('ul') 
    .data(nodes) 
    .enter().append('li') 
     .style('background', '#ffffff') 
    .text(function(d) { return d.name; }) 

    .on('mouseover', function(d) { 

     d3.select(this) 
      .transition().duration(200)//Set transition 
      .style('background', '#ededed') 
    }) 

    .on('mouseout', function(d) { 

     d3.select(this) 
      .transition().duration(500)//Set transition 
      .style('background', '#ffffff') 
    }) 

    .append('svg') 
     .attr('width', 10) 
     .attr('height', 10) 
     .style('float', 'right') 
     .style('margin-top', 4) 
    .append('circle') 
     .attr("r", 5) 
     .attr('cx', 5) 
     .attr('cy', 5) 
     .style('fill', function(d, i) { return colors(i); }); 

//Add Ticks 
force.on("tick", function(e) { 

    link.attr("x1", function(d) { return d.source.x; }) 
     .attr("y1", function(d) { return d.source.y; }) 
     .attr("x2", function(d) { return d.target.x; }) 
     .attr("y2", function(d) { return d.target.y; }); 

    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 

}); 


//Center Node 
var userCenter = d3.select("svg").append("svg:circle") 
    .attr('class', 'user') 
    .attr('r', 30) 
    .attr('cx', width/2) 
    .attr('cy', height/2) 
    .style('fill', '#bfbfbf') 

var label = d3.select('svg').append("text") 
    .text('USER') 
    .attr('x', width/2) 
    .attr('y', height/2) 
    .attr('text-anchor','middle') 
    .attr('transform', 'translate(0, 5)') 
    .style('font-size','12px') 
    .attr('fill','#666666') 

//Fix Root 
function flatten(root) { 
    var nodes = []; 
    function recurse(node, depth) { 
     if (node.children) { 
      node.children.forEach(function(child) { 
       recurse(child, depth + 1); 
      }); 
     } 
     node.depth = depth; 
     nodes.push(node); 
    } 
    recurse(root, 1); 
    return nodes; 
} 

//Data 
function getData() { 
    return { 
     "name": "flare", 
     "size": 0, 
      "children": [ 
       { "name": "Jobs", "size": 3743 }, 
       { "name": "Contact", "size": 3302 }, 
       { "name": "Dietary", "size": 2903 }, 
       { "name": "Bookings", "size": 4823 }, 
       { "name": "Menu", "size": 3002 }, 
       { "name": "Cards", "size": 3120 }, 
       { "name": "Newsletter", "size": 3302 } 
      ] 
    }; 
} 

답변

1

당신은 노드와 범례 항목에 대한 동일한 이벤트 (마우스 오버, 마우스를 이동하면) 기능을 사용해야합니다.

//Adding an event - mouseover/mouseout 
    .on('mouseover', onMouseover) 

    .on('mouseout', onMouseout); 
... 

//Legend 
    .on('mouseover', onMouseover) 

    .on('mouseout', onMouseout) 

그런 다음, 당신은 스타일을 변경 select에 올바른 요소를 함수에 전달 된 데이터를 사용합니다. 여기

function onMouseover(elemData) { 

    d3.select("svg").selectAll("circle") 
    .select(function(d) { return d===elemData?this:null;}) 
    .transition()//Set transition 
       .style('stroke', '#222222') 
       .attr("r", function(d) { return (d.size/200) + 2; }) 

    d3.select('#key').selectAll('li') 
    .select(function(d) { return d===elemData?this:null;}) 
      .transition().duration(200)//Set transition 
      .style('background', '#ededed') 


} 

function onMouseout(elemData) { 

    d3.select("svg").selectAll("circle") 
    .select(function(d) { return d===elemData?this:null;}) 
           .transition() 
       .style('stroke', '#bfbfbf') 
       .attr("r", function(d) { return (d.size/200) - 2; })   

    d3.select('#key').selectAll('li') 
    .select(function(d) { return d===elemData?this:null;}) 
         .transition().duration(500)//Set transition 
      .style('background', '#ffffff') 


} 

+0

감사 @Marcelo JSFiddle 업데이트됩니다 – henryd