2013-12-07 2 views
2

Я использую D3 api, чтобы показать некоторые узлы в порядке, узлы приходят на страницу того же цвета. При наведении курсора на узел затем его изменение на другой цвет. но я хочу фиксированный цвет для узла (отличного от других) во время загрузки. Я использую этот апи .. пожалуйста, помогите мне ...Как указать 3 разных пользовательских цвета для 3 узлов в макете D3 force при загрузке

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 
    .node circle { 
stroke: white; 
stroke-width: 1.5px; 
opacity: 1.0; 
    } 

line { 
stroke: black; 
stroke-width: 1.5px; 
stroke-opacity: 1.0; 
} 
</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 
    data = { 
     nodes : [ { 
      size : 10 
     }, { 
      size : 5 
     }, { 
      size : 2 
     }, { 
      size : 3 

     } ], 
     links : [ { 
      source : 0, 
      target : 1 
     }, { 
      source : 0, 
      target : 2 

     } ] 
    } 

    var mouseOverFunction = function(d,i) { 
     var circle = d3.select(this); 
     //$ fill = d3.scale.category20(); 
     node.transition(500).style("opacity", function(o) { 
      return isConnected(o, d) ? 1.0 : 0.2; 
     }).style("fill", function(o) { 
      if (isConnectedAsTarget(o, d) && isConnectedAsSource(o, d)) { 
       fillcolor = 'green'; 
      } else if (isConnectedAsSource(o, d)) { 
       fillcolor = 'red'; 
      } else if (isConnectedAsTarget(o, d)) { 
       fillcolor = 'blue'; 
      } else if (isEqual(o, d)) { 
       fillcolor = "hotpink"; 
      } else if(isNot(o,d)){ 

       //here the output will shown when no mouse event is occured 


      } 
      return fillcolor; 
     }); 

     link 
       .transition(500) 
       .style("stroke-opacity", function(o) { 
        return o.source === d || o.target === d ? 1 : 0.2; 
       }) 
       .transition(500) 
       .attr(
         "marker-end", 
         function(o) { 
          return o.source === d || o.target === d ? "url(#arrowhead)" 
            : "url()"; 
         }); 

     circle.transition(500).attr("r", function() { 
      return 1.4 * node_radius(d) 
     }); 
    } 

    var mouseOutFunction = function() { 
     var circle = d3.select(this); 

     node.transition(500); 

     link.transition(500); 

     circle.transition(500).attr("r", node_radius); 
    } 

    function isConnected(a, b) { 
     return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) 
       || a.index == b.index; 
    } 

    function isConnectedAsSource(a, b) { 
     return linkedByIndex[a.index + "," + b.index]; 
    } 

    function isConnectedAsTarget(a, b) { 
     return linkedByIndex[b.index + "," + a.index]; 
    } 

    function isEqual(a, b) { 
     return a.index == b.index; 
    } 

     //here i have trying to make root node a separate color and the child nodes two separate colors 
    function isNot(a,b){ 

    return d3.scale.category20()(i); 
    } 


    function tick() { 
     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("transform", function(d) { 
      return "translate(" + d.x + "," + d.y + ")"; 
     }); 
    } 

    function node_radius(d) { 
     return Math.pow(40.0 * d.size, 1/3); 
    } 

    var width = 1000; 
    var height = 500; 

    var nodes = data.nodes 
    var links = data.links 

    var force = d3.layout.force().nodes(nodes).links(links).charge(-3000) 
      .friction(0.6).gravity(0.6).size([ width, height ]).start(); 

    var linkedByIndex = {}; 
    links.forEach(function(d) { 
     linkedByIndex[d.source.index + "," + d.target.index] = true; 
    }); 

    var svg = d3.select("body").append("svg").attr("width", width).attr(
      "height", height); 

    var link = svg.selectAll("line") 
       .data(links) 
       .enter() 
       .append("line"); 

    var node = svg.selectAll(".node") 
       .data(nodes) 
       .enter() 
     .append("g") 
     .style("fill", function (d) { 
        return '#1f77b4'; 
       }) 
     .attr("class", "node") 
       .attr("cx",function(d) { 
        return d.x; 
       }) 
      .attr("cy",function(d) { 
        return d.y; 
       }) 
     //.attr("fill",function(d){return color(d.range);}) 
     .call(force.drag); 

    node.append("circle") 
       .attr("r", node_radius) 
       .on("mouseover", mouseOverFunction) 
       .on("mouseout", mouseOutFunction); 

    svg.append("marker") 
       .attr("id", "arrowhead") 
       .attr("refX", 6 + 7) // Controls the shift of the arrow head along the path 
     .attr("refY", 2) 
       .attr("markerWidth", 6) 
       .attr("markerHeight", 4) 
       .attr("orient", "auto") 
       .append("path") 
       .attr("d", "M 0,0 V 4 L6,2 Z"); 

    link.attr("marker-end", "url()"); 

    force.on("tick", tick); 
</script> 
</body> 

This is the output I got

But This is what I want..

+0

Как вы определяете цвет узла? Это в данных? –

+0

нет, в данных мы можем определить размер узла. Я думаю, что цвет указан в приведенной ниже функции mouseOverFunction. Я думаю, что черный цвет наступит, когда в этой функции не будет указателя мыши. Я хочу пометить 3 узла 3 различных цвета onload – Subho

+0

} else { fillcolor = '# 000'; } return fillcolor; это отвечает за то, что код черного цвета необходимо изменить здесь, чтобы сделать 3 разных цвета. – Subho

ответ

1

Я думаю, вы почти там с вашим кодом. При наведении мыши вы должны изменить свойство «fill» css вашего узла.

Для этого в d3 вы должны использовать:

node.append("circle") 
    .attr("r", node_radius) 
    .on("mouseover",mouseOverFunction) 

, как вы делали. В moueOverFunction у вас есть два варианта, чтобы получить свойства для данного узла:

1) Получить цвет из свойства узла:

function mouseoverFunction(node) { 
    if(node.size<10) { 
     return 'blue' 
    } else { 
     return 'red' 
    } 
} 

2) Получить цвет из положения узла в массив данных:

function mouseoverFunction(node,index) { 
    if(index<2) { 
     // Will color the two first nodes blue 
     return 'blue' 
    } else { 
     // All others will be red 
     return 'red' 
    } 
} 

В конце концов для вашей конкретной проблемы, я хотел бы сделать:

function mouseoverFunction(node,index) { 
    if(index<3) { 
     return ['red','green','blue'][index] 
    } else { 
     // index should be less than 3 
     return 'black' 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^