javascript - Configurar gráfico estático de diseño fijo en d3.js
graph svg (1)
Primero, aumente la fuerza de carga y reduzca la distancia de enlace . Hacerlo pone un mayor énfasis en la estructura global que en las conexiones locales. Además, si aumenta la fuerza de carga lo suficiente, la carga repulsiva empujará incluso a los nodos conectados directamente más lejos, lo que aumentará efectivamente la distancia de enlace al tiempo que proporciona una mejor estructura general. (La desventaja de una fuerza de carga más fuerte es que la inicialización del gráfico es más caótica, pero esto no debería ser un problema para los diseños estáticos).
En segundo lugar, es posible que deba aumentar el número de iteraciones o agregar fuerzas personalizadas para obtener mejores resultados. Los diseños de fuerza a menudo funcionan bien en gráficos arbitrarios, pero no hay garantía de que produzcan un resultado óptimo (o incluso bueno). Para cualquier gráfico en el que pueda hacer suposiciones simplificadoras (por ejemplo, trees ), puede haber fuerzas o restricciones adicionales que puede aplicar para alentar a la simulación a converger en una mejor solución.
Tengo un ejemplo de código de trabajo (solo la parte <script type="text/javascript">
) de un gráfico estático que usa d3.js
como se muestra a continuación:
/* Create graph data */
var nodes = [];
for (var i = 0; i < 13; i++)
{
var datum = {
"value": i
};
nodes.push(datum);
}
var links = [{"source": 0, "target": 1},
{"source": 1, "target": 2},
{"source": 2, "target": 0},
{"source": 1, "target": 3},
{"source": 3, "target": 2},
{"source": 3, "target": 4},
{"source": 4, "target": 5},
{"source": 5, "target": 6},
{"source": 5, "target": 7},
{"source": 6, "target": 7},
{"source": 6, "target": 8},
{"source": 7, "target": 8},
{"source": 9, "target": 4},
{"source": 9, "target": 11},
{"source": 9, "target": 10},
{"source": 10, "target": 11},
{"source": 11, "target": 12},
{"source": 12, "target": 10}];
/* Create force graph */
var w = 800;
var h = 500;
var size = nodes.length;
nodes.forEach(function(d, i) { d.x = d.y = w / size * i});
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("weight", h);
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.linkDistance(200)
.size([w, h]);
setTimeout(function() {
var n = 400
force.start();
for (var i = n * n; i > 0; --i) force.tick();
force.stop();
svg.selectAll("line")
.data(links)
.enter().append("line")
.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; });
svg.append("svg:g")
.selectAll("circle")
.data(nodes)
.enter().append("svg:circle")
.attr("class", "node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 15);
svg.append("svg:g")
.selectAll("text")
.data(nodes)
.enter().append("svg:text")
.attr("class", "label")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("text-anchor", "middle")
.attr("y", ".3em")
.text(function(d) { return d.value; });
}, 10);
y produce este diseño más bien revuelto:
Si bien técnicamente es el gráfico correcto, el diseño ideal debería ser algo como esto (ignorando los diferentes gráficos visuales):
Tenga en cuenta que el diseño debe ser fijo para que la recarga de la página no cambie la posición de cada nodo; el diseño también debe ser estático, ya que no hay efecto de animación y los nodos no se pueden arrastrar. Ambos requisitos ya se han logrado en el script anterior.
Entonces, ¿cómo debo configurar más este script d3
para producir un diseño que se muestra en la segunda imagen?