我有一个菜鸟问题。 我试图基于按钮单击来重新缩放散点图元素(沿着X轴的圆)-创建“放大”活动。我为此降低了X轴域。
它与Xaxis一起使用时效果很好,但是对于圆形而言则更难。我必须将它们全部删除并再次绘制(代码中标记的位置)。当涉及到很多元素时,这会使过程变慢,并且不允许进行轴缩放所用的过渡。
是否可以更改不需要删除并重新绘制所有内容的圆的属性?
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
// Define Canvas size
var width = 500;
var height = 500;
// Generate Toy Data
var randomX = d3.randomUniform(0, 880);
var randomY = d3.randomUniform(0, 800);
data_x = [];
data_y = [];
for (i = 0; i < 10000; i++) {
nume = Math.floor((Math.random() * 100));
data_x.push(nume);
data_y.push(nume);
}
// Scaling Coeffs
var coeffX = 1;
var coeffY = 1;
var coeffR = 1;
var coordX = (Math.max.apply(null, data_x)/coeffX);
var coordy = (Math.max.apply(null, data_y)/coeffY);
var x = d3.scaleLinear()
.domain([0, coordX])
.range([ 0, width]).nice();
var y = d3.scaleLinear()
.domain([0, coordy])
.range([height, 0]).nice();
var yAxis = d3.axisLeft(y).ticks(5);
var xAxis = d3.axisBottom(x).ticks(5)
//Create SVG element
var canvas = d3.select("body")
.append("svg")
.attr("width", width+50)
.attr("height", height+50)
.append("g");
// --------------- Draw Elements ---------------------
var circles = canvas.selectAll("circlepoint")
.data(data_x)
.enter()
.append("g");
circles.append("circle")
.attr("cx",function(d, i){
var tempe = data_x[i];
return x(tempe);
})
.attr("cy", function(d, i){
var tempe = data_y[i];
return y(tempe);
})
.attr("r", function(){
return 3;
})
.style("stroke", "steelblue")
.style("fill", "none")
.attr("transform", "translate(40, -20)");
var xsCont = canvas.append("g")
.attr("transform", "translate(40, " + (height-20) +")")
.attr("class","xaxis")
.call(xAxis);
var ysCont = canvas.append("g")
.attr("transform", "translate(40, -20)")
.call(yAxis);
function rescaleAxisX(tempCoeffX, tempCoeffR){
coordX = (Math.max.apply(null, data_x)/tempCoeffX);
x.domain([0, Math.max.apply(null, data_x)/tempCoeffX])
// -------- This part works well-------
canvas.select(".xaxis")
.transition().duration(750)
.call(xAxis);
// -------- End -------------
// -------- This one doesn't as expected-------
circles.remove();
circles = canvas.selectAll("circlepoint")
.data(data_x)
.enter()
.append("g");
circles.append("circle")
.attr("cx",function(d, i){
var tempe = data_x[i];
return x(tempe);
})
.attr("cy", function(d, i){
var tempe = data_y[i];
return y(tempe);
})
.attr("r", function(d, i){
return tempCoeffR;
})
.style("stroke", "steelblue")
.style("fill", "none")
.attr("transform", "translate(40, -20)");
}
// -------- End -------
// Zoom in button
var buttonZoomPlusX = d3.select("body")
.append("input")
.attr("type","button")
.attr("class","button")
.attr("value", "+")
.on("click", function(){
coeffX = coeffX + 1;
coeffR = coeffR + 1;
rescaleAxisX(coeffX, coeffR);
})
</script>
</body>
</html>
在这里实现小提琴 https://jsfiddle.net/sma76ntq/
非常感谢
答案 0 :(得分:0)
一如既往,这是菜鸟的错误。缺少两件事: 1.在圆形上添加一些类,以便在绘制更多圆形时不要在画布上选择所有内容
circles.append("circle")
.attr("cx",function(d, i){
var tempe = data_x[i];
return x(tempe);
})
.attr("cy", function(d, i){
var tempe = data_y[i];
return y(tempe);
//return y(d.y);
})
.attr("r", function(){
return 3;
})
.attr("class","eles")
.style("stroke", "steelblue")
.style("fill", "none")
.attr("transform", "translate(40, -20)");
在重绘时,只需选择类并更改属性即可。
canvas.selectAll(".eles").data(data_x)
.transition()
.duration(750)
.attr("cx",function(d, i){
var tempe = data_x[i];
return x(tempe);
})
.attr("cy", function(d, i){
var tempe = data_y[i];
return y(tempe);
});
在这里工作的小提琴:https://jsfiddle.net/v7q14nbm/1/