2017-10-05 2 views
0

Ich habe derzeit eine D3, die ein Force-Netzwerk zeigt und seine Kinder auf Klick reduzieren. Ich möchte auch die Namen der Knoten beim Hover anzeigen. Etwas wie dieses: https://bl.ocks.org/mbostock/1212215d3 Node Labels und kollabiert

Unten ist mein Code so weit.

.node { 
    cursor: pointer; 
    stroke: #3182bd; 
    stroke-width: 1.5px; 
} 

.link { 
    fill: none; 
    stroke: #9ecae1; 
    stroke-width: 1.5px; 
} 

</style> 
<body> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 

var width = 960, 
    height = 500, 
    root; 

var force = d3.layout.force() 
    .size([width, height]) 
    .on("tick", tick); 

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

//Added markers to indicate that this is a directed graph 
svg.append("defs").selectAll("marker") 
    .data(["arrow"]) 
    .enter().append("marker") 
    .attr("id", function(d) { return d; }) 
    .attr("viewBox", "0 -5 10 10") 
    .attr("refX", 15) 
    .attr("refY", -1.5) 
    .attr("markerWidth", 4) 
    .attr("markerHeight", 4) 
    .attr("orient", "auto") 
    .append("path") 
    .attr("d", "M0,-5L10,0L0,5"); 

var link = svg.selectAll(".link"), 
    node = svg.selectAll(".node"); 

d3.json("test.json", function(json) { 
    root = json; 
    //Give nodes ids and initialize variables 
    for(var i=0; i<root.nodes.length; i++) { 
    var node = root.nodes[i]; 
    node.id = i; 
    node.collapsing = 0; 
    node.collapsed = false; 
    } 
    //Give links ids and initialize variables 
    for(var i=0; i<root.links.length; i++) { 
    var link = root.links[i]; 
    link.source = root.nodes[link.source]; 
    link.target = root.nodes[link.target]; 
    link.id = i; 
    } 
    // for (var i=0; i<root.nodes.length; i++){ 
    // var node = root.nodes[i]; 

    // } 
    update(); 
}); 

function update() { 
    //Keep only the visible nodes 
    var nodes = root.nodes.filter(function(d) { 
    return d.collapsing == 0; 
    }); 
    var links = root.links; 
    //Keep only the visible links 
    links = root.links.filter(function(d) { 
    return d.source.collapsing == 0 && d.target.collapsing == 0; 
    }); 

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

    // Update the links… 
    link = link.data(links, function(d) { return d.id; }); 

    // Exit any old links. 
    link.exit().remove(); 

    // Enter any new links. 
    link.enter().insert("line", ".node") 
     .attr("class", "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; }) 


    // Update the nodes… 
    node = node.data(nodes, function(d){ return d.id; }).style("fill", color); 

    // Exit any old nodes. 
    node.exit().remove(); 

    // Enter any new nodes. 
    node.enter().append("circle") 
     .attr("class", "node") 
     .attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }) 
     .attr("r", function(d) { return Math.sqrt(d.size)/10 || 4.5; }) 
     .style("fill", color) 
     .on("click", click) 
     .call(force.drag); 
} 

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("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 
} 

// Color leaf nodes orange, and packages white or blue. 
function color(d) { 
    return d.collapsed ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c"; 
} 

// Toggle children on click. 
function click(d) { 
    if (!d3.event.defaultPrevented) { 
    //check if link is from this node, and if so, collapse 
    root.links.forEach(function(l) { 
     if(l.source.id == d.id) { 
     if(d.collapsed){ 
      l.target.collapsing--; 
     } else { 
      l.target.collapsing++; 
     } 
     } 
    }); 
    d.collapsed = !d.collapsed; 
    } 
    update(); 
} 

</script> 

Mein Problem ist mit der Update-Funktion. Ich konnte es zur Anzeige bringen, aber als ich auf "Abbrechen" klickte, wurden die Labels nicht mehr angezeigt. Ich bin mir nicht sicher, ob ich die Zecke twittern soll oder was.

danke!

+1

können Sie auch test.json – Cyril

+0

posten Die JSON-Datei liesmich.json aus dem Link wird mit dem Code arbeiten – Jakeeln

Antwort

2

Gruppieren Sie die Kreis- und Textbeschriftungen mithilfe des SVG-Gruppenelements wie unten gezeigt.

var groupNodes = node.enter().append("g") 
    .attr("class", "node") 
    .attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; }); 
    .on("click", click) 
    .on("mouseover", function(){ 
     d3.select(this).select("text").style("display","block"); 
    }) 
    .on("mouseout", function(){ 
     d3.select(this).select("text").style("display","none"); 
    }) 
    .call(force.drag); 

groupNodes.append("circle")     
     .attr("r", function(d) { return Math.sqrt(d.size)/10 || 4.5; }) 
     .style("fill", color); 

var label = groupNodes.append("text") 
     .attr("dy", ".35em") 
     .style("display", "none) 
     .text(function(d) { return d.name; //Use the key which holds the name value }); 

Der obige Code ersetzt den folgenden Teil des Codes in der Update-Funktion.

node.enter().append("circle") 
     .attr("class", "node") 
     .attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }) 
     .attr("r", function(d) { return Math.sqrt(d.size)/10 || 4.5; }) 
     .style("fill", color) 
     .on("click", click) 
     .call(force.drag); 

und jetzt die Zecke Funktion ändern

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+")"; 
    }); 
} 

folgt nun alle anderen Funktionalitäten sollte wie erwartet funktionieren.

+0

Ich habe einige Probleme, die dies in meinen Code integrieren. Wo genau geht der erste Block? Ich bekomme Verwendungen mit den Knoten und node.enter Variablen – Jakeeln

+0

Der erste Block sollte innerhalb der Update-Funktion geschrieben werden. Dieser Code wird Knoten als Gruppen erstellen, die jeden Kreis und entsprechende Textelemente enthalten. – Gilsha

+0

Danke für die Klarstellung! Jetzt werden die Namen statisch angezeigt. Gibt es eine einfache Möglichkeit, die Anzeige im Hover zu ändern? Oder vielleicht sollte ich nach einem neuen Thread fragen. – Jakeeln