tutorial que javascript d3.js svg circle-pack

javascript - tutorial - que es d3 js



D3: Sustituyendo d3.svg.diagonal() con d3.svg.line() (4)

He implementado el siguiente gráfico con los bordes renderizados con d3.svg.diagonal (). Sin embargo, cuando intento sustituir la diagonal con d3.svg.line (), no parece que extraiga los datos de destino y de origen. ¿Qué me estoy perdiendo? ¿Hay algo que no entiendo sobre d3.svg.line?

El siguiente es el código al que me refiero, seguido del código completo:

var line = d3.svg.line() .x(function(d) { return d.lx; }) .y(function(d) { return d.ly; });

...

var link= svg.selectAll("path") .data(links) .enter().append("path") .attr("d",d3.svg.diagonal()) .attr("class", ".link") .attr("stroke", "black") .attr("stroke-width", "2px") .attr("shape-rendering", "auto") .attr("fill", "none");

El código completo:

var margin = {top: 20, right: 20, bottom: 20, left: 20}, width =1500, height = 1500, diameter = Math.min(width, height), radius = diameter / 2; var balloon = d3.layout.balloon() .size([width, height]) .value(function(d) { return d.size; }) .gap(50) var line = d3.svg.line() .x(function(d) { return d.lx; }) .y(function(d) { return d.ly; }); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + (margin.left + radius) + "," + (margin.top + radius) + ")") root = "flare.json"; root.y0 = height / 2; root.x0 = width / 2; d3.json("flare.json", function(root) { var nodes = balloon.nodes(root), links = balloon.links(nodes); var link= svg.selectAll("path") .data(links) .enter().append("path") .attr("d",d3.svg.diagonal()) .attr("class", ".link") .attr("stroke", "black") .attr("stroke-width", "2px") .attr("shape-rendering", "auto") .attr("fill", "none"); var node = svg.selectAll("g.node") .data(nodes) .enter() .append("g") .attr("class", "node"); node.append("circle") .attr("r", function(d) { return d.r; }) .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); node.append("text") .attr("dx", function(d) { return d.x }) .attr("dy", function(d) { return d.y }) .attr("font-size", "5px") .attr("fill", "white") .style("text-anchor", function(d) { return d.children ? "middle" : "middle"; }) .text(function(d) { return d.name; }) });

Una comparación de cómo desaparece el atributo d de la svg cuando se usa "línea".


La pregunta es bastante antigua, pero como no veo una respuesta y alguien podría enfrentar el mismo problema, aquí está.

La razón por la que el simple reemplazo de la diagonal con la línea no funciona es porque d3.svg.line y d3.svg.diagonal devuelven resultados diferentes:

  • d3.svg.diagonal devuelve una función que acepta datos y su índice y la transforma en una ruta utilizando la proyección . En otras palabras, diagonal.projection determina cómo la función obtendrá las coordenadas de los puntos del dato suministrado.
  • d3.svg.line devuelve una función que acepta una matriz de puntos de la línea y la transforma en ruta. Los métodos line.x y line.y determinan cómo se recuperan las coordenadas del punto desde el único elemento de la matriz suministrada

D3 SVG-Formas de referencia

SVG Paths y D3.js

Por lo tanto, no puede utilizar el resultado de la d3.svg.line directamente en las selecciones de d3 (al menos cuando desee dibujar varias líneas).

Necesitas envolverlo en otra función como esta:

var line = d3.svg.line() .x( function(point) { return point.lx; }) .y( function(point) { return point.ly; }); function lineData(d){ // i''m assuming here that supplied datum // is a link between ''source'' and ''target'' var points = [ {lx: d.source.x, ly: d.source.y}, {lx: d.target.x, ly: d.target.y} ]; return line(points); } // usage: var link= svg.selectAll("path") .data(links) .enter().append("path") .attr("d",lineData) .attr("class", ".link") .attr("stroke", "black") .attr("stroke-width", "2px") .attr("shape-rendering", "auto") .attr("fill", "none");

Aquí está la versión de trabajo de jsFiddle mobeets publicada: jsFiddle


Quizás encapsular la función diagonal y editar sus parámetros podría funcionar para usted:

var diagonal = d3.svg.diagonal(); var new_diagonal = function (obj, a, b) { //Here you may change the reference a bit. var nobj = { source : { x: obj.source.x, y: obj.source.y }, target : { x: obj.target.x, y: obj.target.y } } return diagonal.apply(this, [nobj, a, b]); } var link= svg.selectAll("path") .data(links) .enter().append("path") .attr("d",new_diagonal) .attr("class", ".link") .attr("stroke", "black") .attr("stroke-width", "2px") .attr("shape-rendering", "auto") .attr("fill", "none");


Solo establece el atributo d del enlace a la línea:

.attr("d", line)


Tuve el mismo problema ... Hay un jsFiddle here .

Tenga en cuenta que cambiar de line a diagonal lo hará funcionar.