Ich mache ein interaktives Blasendiagramm und ich arbeite an der Funktionalität, um die Daten in zwei Gruppen zu teilen, die sich auf die gegenüberliegenden Seiten des Bildschirms bewegen. Ich verwende eine Zentrierungskraft für meine Simulation, weil ich denke, dass sie eine viel schönere und konsistentere Darstellung der Daten liefert als die Verwendung von forceX und forceY. Ich habe jedoch Probleme mit der Aufteilung meiner Daten.d3.js: Übergeben Sie die anonyme Funktion als Parameter für die Zentrierungskraft?
Ich hatte die Idee, dass, weil Sie eine anonyme Funktion als Parameter forceX übergeben können, um zu bestimmen, ob ein Knoten nach links oder rechts bewegt, könnten Sie theoretisch das gleiche für den x-Wert in einer zentrierenden Kraft tun. Mein Center Kraft-Code sieht wie folgt aus:
var forceCenterSplit = d3.forceCenter(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}, height/2)
Zum Vergleich hier ist der Code für die forceX, die das gleiche erreicht:
var forceXsplit = d3.forceX(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}).strength(.05);
Leider ist die Konsole sagt „Unerwarteter Wert NaN cx Parsen Attribut." wenn ich die Zentrierungskraft starte und alle Daten auf cx = 0 (den Standardwert) schiebe.
Fehle ich etwas Grundlegendes hier? Können Sie keine anonyme Funktion als Parameter für die Zentrierungskraft übergeben? Wenn nicht, gibt es einen besseren Weg, dies zu tun?
Danke!
// nicer looking splitting forces that use forceCenter
var forceCenterCombine = d3.forceCenter(width/2, height/2);
var forceCenterSplit = d3.forceCenter(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}, height/2);
// simple splitting forces that only use forceX
var forceXSplit = d3.forceX(function(d) {
if (d[splitParameter] >= splitVal)
return 3*width/4;
else
return width/4;
}).strength(.05);
var forceXCombine = d3.forceX(width/2).strength(.05);
// collision force to stop the bubbles from hitting each other
var forceCollide = d3.forceCollide(function(d){
console.log("forceCollide");
return radiusScale(d[radiusParam]) + 1;
}).strength(.75)
// This code is for the simulation that combines all the forces
var simulation = d3.forceSimulation()
.force("center", forceCenterCombine)
.force("collide", forceCollide)
.on('end', function(){console.log("Simulation ended!");});
function ticked() {
circles
.attr("cx", function(d){
return d.x;
})
.attr("cy", function(d){
return d.y;
})
}
var splitFlag = false;
// dynamically divide the bubbles into two (or probably more later on) groups
$scope.split = function() {
// split them apart
if (!splitFlag){
console.log("splitForce");
simulation.force("center", forceXSplit)
.force("y", d3.forceY(height/2).strength(.05))
.alphaTarget(.25)
.restart();
splitFlag = true;
}
// bring them back together
else {
console.log("combineForce");
simulation.force("center", forceCenterCombine)
.alphaTarget(.25)
.restart();
splitFlag = false;
}
};
Aufgrund der Natur von 'd3.forceCenter' ist das nicht möglich. Die API sagt: * "Die Zentrierkraft übersetzt Knoten gleichmäßig, so dass die mittlere Position von ** allen Knoten ** (der Massenschwerpunkt, wenn alle Knoten gleiches Gewicht haben) an der gegebenen Position ⟨x, y⟩ liegt." *, Betonung meiner. Somit ist hier kein Platz für eine Accessor-Funktion. 'forceX' und' forceY' hingegen setzen * den Koordinaten-Accessor auf die angegebene Zahl oder ** function ** "* (betonung wieder meine). –
Ah, das ist nervig.Wie ich im Originalbeitrag erwähnt habe, zeigen forceX und forceY eine wesentlich harmlosere Darstellung als das forceCenter - Knoten kollidieren endlos, bleiben in Clustern anderer Knoten stecken, bewegen sich nicht so weit, wie sie sollen, usw. Ich nehme an der einzige Weg, wie ich zwei verschiedene Massenzentren haben könnte, wäre, verschiedene Simulationen zu haben, die auf zwei verschiedenen Knotengruppen laufen? Danke für die Antwort von der Art und Weise –
Aber, wenn Sie 2 Simulationen haben, wie würden Sie 'kollidieren' verwenden, um überlappende Knoten zu vermeiden? Es sei denn, die Knoten sind sehr voneinander getrennt. –