ボタンを押したときに気泡がばらばらになって元に戻るバブルグラフがあります。トグル後衝突検出が失われました(d3v4)
私の場合、バブルグラフに入力する生データには、Character、Total_Words、Sexの3つの列があります。バブルグラフの働きは、それぞれのキャラクターが独自のバブルで表現されています。各バブルの領域は、各文字のTotal_Wordsに基づいてスケーリングされます。バブルはセックスに応じて色付けされ(そして動的に分割されます)
私はこれを美しく動作させることができました。バブルはすべてボタンのクリックで分離して円になり、2番目のボタンをクリックすると一緒に戻ります。私が持っている問題は、気泡が最初に画面に現れたときに、衝突検出が美しく機能することです(どこにでも均等に気泡があります)。しかし、気泡を2つのグループに分けた後(2番目のシミュレーションで)、衝突検出は(明示的に呼び出されても)機能しなくなりました。 上記の画像内:左:衝突検出が動作し、すべての気泡が正しく配置されています。右:スイッチを「オン」にすると、気泡が分裂するが、衝突検出は機能しない。気泡が重なり、決してジッタを止めません。
ここで私が働いているもののbl.ocksデモです。 https://bl.ocks.org/ProQuestionAsker/79d0228ae7161e349770e7d553cf4c94
これは、現在使用している.jsスクリプト全体です。この問題は、私がシミュレーションを呼び出す「Toggle Switchesの追加」領域にあるかもしれないと思うが、この作業をするために何かを調整することはできない。
(function() {
var width = 400,
height = 300;
var svg = d3.select("#chart")
.append("svg")
.attr("height", height)
.attr("width", width)
.append("g")
.attr("transform", "translate(0,0)")
var radiusScale = d3.scaleSqrt().domain([1, 3114]).range([1, 50])
var forceXSplit = d3.forceX(function(d){
if(d.Sex === "male") {
return (width * .30)
} else {
return (width * .70)
}
}).strength(0.15)
var forceXCombine = d3.forceX((width)/2).strength(0.1)
var forceCollide = d3.forceCollide(function(d){
return radiusScale(d.Total_Words) + 1
})
var simulation = d3.forceSimulation()
.force("x", forceXCombine)
.force("y", d3.forceY(height/2).strength(0.09))
.force("collide", forceCollide)
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "20")
.style("visibility", "hidden")
.style("color", "white")
.style("padding", "8px")
.style("background-color", "rgba(0, 0, 0, 0.75)")
.style("border-radius", "6px")
.style("font", "12px sans-serif")
.text("");
// Importing data file
d3.queue()
.defer(d3.csv, "data.csv")
.await(ready)
function ready (error, datapoints) {
var circles = svg.selectAll(".Character")
.data(datapoints)
.enter().append("circle")
.attr("class", "Character")
.attr("r", function(d){
return radiusScale(d.Total_Words)
})
.style("fill", function(d) {
var returnColor;
if (d.Sex === "male") { returnColor = "#355C7D";
} else if (d.Sex === "female") {returnColor = "#F67280";}
return returnColor;
})
.on("mouseover", function(d) {
tooltip.html(d.Character + "<br><br> Words Spoken: " + d.Total_Words);
tooltip.style("visibility", "visible");
})
.on("mousemove", function() {
return tooltip.style("top", (d3.event.pageY-10)+"px").style("left", (d3.event.pageX+10)+"px");
})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
// Adding Toggle Switches
var atRight = true
var rect = svg.append("rect")
.attr("x", 10)
.attr("y", 10)
.attr("rx", 22)
.attr("ry", 22)
.style("fill", "lightgray")
.attr("width", 64)
.attr("height", 40);
var circle = svg.append("circle")
.attr("cx", 30)
.attr("cy", 30)
.attr("r", 16)
.style("fill", "white")
.on("click", function(){
if(atRight === true){
simulation
.force("x", forceXSplit)
.alphaTarget(0.2)
.force("collide", forceCollide)
setAtRight(!atRight)
} else {
simulation
.restart()
.force("x", forceXCombine)
.alphaTarget(0.2)
forceCollide.initialize(simulation.nodes());
setAtRight(!atRight)
}
});
var setAtRight = function(newValue) {
atRight = newValue;
circle.transition().duration(250)
.attr("cx", (atRight? (30) : (54)))
.style("fill", "white");
rect.transition().duration(250)
.style("fill", atRight? "lightgray" : "#F67280");
};
var res = {
'getValue': function() { return atRight; },
'setValue': setAtRight,
'remove': function() { circle.remove(); }
};
simulation.nodes(datapoints)
.on('tick', ticked)
function ticked() {
circles
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
}
}
})();
私は運が無ければsimulation.restart()
を使ってみました。私はこの質問hereから提案されたようにforceCollide.initialize(simulation.nodes());
を使ってみましたが、まだ泡はお互いに重なっています。
私はd3.jsに新しく、明らかに何かが欠落している可能性がありますが、これを動作させることはできません。
洞察力は非常に高く評価されます。前もって感謝します!
実際に役立つデモがあります。これの実行可能なバージョンを提供できますか? – altocumulus
@altocumulus、すばらしい返答をいただきありがとうございます!私は[リンク](https://bl.ocks.org/ProQuestionAsker/79d0228ae7161e349770e7d553cf4c94)を追加するための説明を編集しました。 –