如何避免散点图上的点折叠 d3.js
How to avoid dot collapsing on scatter plot d3.js
我是 d3 Js 宇宙的新手,我用 json 创建了一个散点图,但某些点具有相同的位置,我想将它们并排放置。我尝试将力碰撞与力模拟结合使用,但什么也没发生。
我遵循了很多例子 scatter plot with collision collision detection
function constructScatterPoint(){
svg = d3.select("#graphDiv").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(d3.axisBottom(xScale)).append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Periode")
.attr("stroke","black");
svg.append("g").call(d3.axisLeft(yScale)).append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", -6)
.text("Durée")
.attr("stroke","black");
const forceX = d3.forceX(width / 2).strength(0.015)
const forceY = d3.forceY(height / 2).strength(0.015)
var force = d3.forceSimulation()
.velocityDecay(0.2)
.force("x", forceX)
.force("y", forceY)
.force("collide", d3.forceCollide().radius(function(d){
return 5 + 0.5;
}).iterations(5))
.nodes(data).on("tick", tickActions);
maintenanceTaskDot=svg.selectAll("dot").data(data).enter().append("circle")
.attr("stroke", "var(--greydark)")
.attr("stroke-width", 1.5)
.attr("r", 5)
.attr("fill", function(d){ if(d.maintenance_work=="A") {return "var(--purple)"}else if(d.maintenance_work=="H"){return "var(--pink)"}return "var(--cyan)"} )
.style("opacity",0.5)
.on('mouseover', showTaskCode.show)
.on('mouseout',showTaskCode.hide)
.on("click", clickOnCircle)
function tickActions(e) {
svg.selectAll("circle")
.attr("cx", xValue)
.attr("cy", yValue)
}
}
找到了!
对应的xValue和yValue
xScale = d3.scaleLinear().range([0, width]);
yScale = d3.scaleLinear().range([height, 0]);
xValue=function(d){return xScale(d.period)};
yValue=function(d){return yScale(d.duration)};
var force = d3.forceSimulation(data)
.force("x", d3.forceX(xValue))
.force("y", d3.forceY(yValue))
.force("collide", d3.forceCollide().radius(7))
.force("manyBody", d3.forceManyBody().strength(-5))
.velocityDecay(0.8)
.alphaTarget(0.1)
.on("tick", tickActions);
function tickActions(e) {
maintenanceTaskDot
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; });
}
我是 d3 Js 宇宙的新手,我用 json 创建了一个散点图,但某些点具有相同的位置,我想将它们并排放置。我尝试将力碰撞与力模拟结合使用,但什么也没发生。 我遵循了很多例子 scatter plot with collision collision detection
function constructScatterPoint(){
svg = d3.select("#graphDiv").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(d3.axisBottom(xScale)).append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Periode")
.attr("stroke","black");
svg.append("g").call(d3.axisLeft(yScale)).append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", -6)
.text("Durée")
.attr("stroke","black");
const forceX = d3.forceX(width / 2).strength(0.015)
const forceY = d3.forceY(height / 2).strength(0.015)
var force = d3.forceSimulation()
.velocityDecay(0.2)
.force("x", forceX)
.force("y", forceY)
.force("collide", d3.forceCollide().radius(function(d){
return 5 + 0.5;
}).iterations(5))
.nodes(data).on("tick", tickActions);
maintenanceTaskDot=svg.selectAll("dot").data(data).enter().append("circle")
.attr("stroke", "var(--greydark)")
.attr("stroke-width", 1.5)
.attr("r", 5)
.attr("fill", function(d){ if(d.maintenance_work=="A") {return "var(--purple)"}else if(d.maintenance_work=="H"){return "var(--pink)"}return "var(--cyan)"} )
.style("opacity",0.5)
.on('mouseover', showTaskCode.show)
.on('mouseout',showTaskCode.hide)
.on("click", clickOnCircle)
function tickActions(e) {
svg.selectAll("circle")
.attr("cx", xValue)
.attr("cy", yValue)
}
}
找到了!
对应的xValue和yValue xScale = d3.scaleLinear().range([0, width]);
yScale = d3.scaleLinear().range([height, 0]);
xValue=function(d){return xScale(d.period)};
yValue=function(d){return yScale(d.duration)};
var force = d3.forceSimulation(data)
.force("x", d3.forceX(xValue))
.force("y", d3.forceY(yValue))
.force("collide", d3.forceCollide().radius(7))
.force("manyBody", d3.forceManyBody().strength(-5))
.velocityDecay(0.8)
.alphaTarget(0.1)
.on("tick", tickActions);
function tickActions(e) {
maintenanceTaskDot
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; });
}