2012-05-07 12 views
5

Para los lectores estimados. Soy bastante nuevo en JavaScript y me he encontrado con este problema. Estoy tratando de poner en práctica una versión modificada de esta fuerza gráfico dirigido: se generaConfiguración del gráfico D3 force directed

http://mbostock.github.com/d3/ex/force.html

Los datos JSON sobre la marcha desde un script PHP. La idea es colorear todas las líneas que se conectan a un nodo específico (definido en un script php) en un color y todas las demás en tonos de gris. Estoy tratando de hacerlo, haciendo coincidir la variable de origen en el archivo JSON a la variable del script PHP y el cambio de color cuando eso es cierto como esto:

var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
    .style("stroke-opacity", function(d) { return d.value/10;}) 
    .style("stroke", function(d) { 
    x = (tested == d.source) ? return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 
    }) 

sin embargo, esto no funciona. El script funciona bien, pero sin el cambio de color si acabo de hacer esta

var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
    .style("stroke-opacity", function(d) { return d.value/10;}) 
    .style("stroke", function(d) { 
    return '#707070'; 
    }) 

He estado mirando esto por días tratando de averiguar para hacer esto y estoy atascado. ¡Cualquier ayuda sería muy apreciada!

Aquí es mi completa guión

<script type="text/javascript"> 

var width = 1200, 
    height = 1200; 

var color = d3.scale.category20(); 

var tested=<?php echo $tested_source;?>; //<-- the variable from php 

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

d3.json("data.json", function(json) { 

var force = d3.layout.force() 
    .charge(-130) 
    .linkDistance(function(d) { return 500-(50*d.value);}) 
    .size([width, height]); 

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

    var link = svg.selectAll("line.link") 
     .data(json.links) 
     .enter().append("line") 
     .attr("class", "link") 
     .style("stroke-width", function(d) { return Math.sqrt(d.value);}) 
     .style("stroke-opacity", function(d) { return d.value/10;}) 
     .style("stroke", function(d) { 
     x = (tested == d.source) ? return '#1f77b4' : '#707070'; //<-- Attempt to change the color of the link when this is true. But is is not working... :(
     }) 


    var node = svg.selectAll("circle.node") 
     .data(json.nodes) 
    .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 12) 
     .style("fill", function(d) { return color(d.group); }) 
     .call(force.drag); 

    node.append("title") 
     .text(function(d) { return d.name; }); 

    force.on("tick", function() { 
    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; }); 
    }); 
}); 

</script> 

Respuesta

8

d.source es un objeto, no se puede utilizar para determinar si ==tested es un objeto similar. Have a look at this answer for more details on object equality.

Si desea probar un valor específico del objeto d.source que se describe a continuación, que supongo que desea, debe especificarlo.

Aquí es la arquitectura objeto de origen: (estoy usando the example you pointed lo que los datos proviene de la miserables.json)

source: Object 
    group: 4 
    index: 75 
    name: "Brujon" 
    px: 865.6440689638284 
    py: 751.3426708796574 
    weight: 7 
    x: 865.9584580575608 
    y: 751.2658636251376 

Ahora, aquí es la parte rota en el código:

x = (tested == d.source) ? return '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 

No funciona porque la devolución está fuera de lugar. va a mezclar declaraciones y ternarios return pero no los ponga en el orden correcto:

return test ? value_if_true : value_if_false; 

si desea asignar el valor de x de todos modos, se puede hacer

x = test ? value_if_true : value_if_false; 
return x; 

Usted debe hacer algo como esto:

return (tested == d.source) ? '#1f77b4' : '#707070';// <-- Attempt to change the color of the link when this is true. 

eso es la sintaxis general, pero esto no funcionará como es Yo u necesidad de elegir uno de los valores para la prueba, por ejemplo:

return (tested === d.source.name) ? '#1f77b4' : '#707070'; 

Además, si la variable de PHP es una cadena que debe hacer

var tested="<?php echo $tested_source;?>"; //<-- the variable from php 

y en la mayoría de los casos se debe utilizar json_encode a mapear variables de PHP en javascript.

Como nota final, recomendaría el uso de console funciones junto con Firebug 's panel de la consola si está usando Firefox o el Chrome Developer Tool' s panel de la consola si está utilizando un navegador basado en Chromium. Le permitiría depurar su código más fácilmente.


código de trabajo

var width = 960, 
    height = 500; 

var color = d3.scale.category20(); 

var force = d3.layout.force().charge(-120).linkDistance(30).size([width, height]); 

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

var tested = 20; 

d3.json("miserables.json", function (json) { 
    force.nodes(json.nodes).links(json.links).start(); 

    var link = svg.selectAll("line.link") 
    .data(json.links) 
    .enter() 
    .append("line") 
    .attr("class", "link") 
    .style("stroke-width", function (d) { 
    return Math.sqrt(d.value); 
    }).style("stroke-opacity", function (d) { 
    return d.value/10; 
    }).style("stroke", function (d) { 
    return (tested == d.source.index) ? '#ee3322' : '#707070'; //'#1f77b4' 
    }); 

    var node = svg.selectAll("circle.node") 
    .data(json.nodes) 
    .enter() 
    .append("circle") 
    .attr("class", "node") 
    .attr("r", 5) 
    .style("fill", function (d) { 
    return color(d.group); 
    }).call(force.drag); 

    node.append("title").text(function (d) { 
    return d.name; 
    }); 

    force.on("tick", function() { 
    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; 
    }); 
    }); 
}); 
+0

Gracias! Soy un novato completo cuando se trata de javascript. La sugerencia hace que el script funcione, pero aún no cambia el color de las líneas de conexión. Creo que puede haber un problema al recuperar d.source de la matriz json. ¿¿Ayuda?? – user1378824

+0

He editado mi respuesta con algún código relacionado con el objeto de origen que está probando contra 'tested'. Creo que el problema viene de ahí. –

+0

Gracias por la respuesta rápida. Tal vez estoy malinterpretando algo, pero el objeto al que te refieres es el nodo. Estoy tratando de cambiar el color de las líneas de conexión entre los nodos. Este valor se define en los "Enlaces" en el archivo miserables.json. ¿Estoy malentendiendo algo completamente? – user1378824

Cuestiones relacionadas