我开始尝试将D3简单化为业余爱好而且我想创建一种动画类型,显示“method of exhaustion”以近似圆形区域。我希望获得的行为显示在animation。
中我能够绘制圆圈,圆圈周围的点以及三角形。现在我正在开发一个名为'update'的函数,它在侦听HTML上的滑块事件时会动态更改'n'的值,并使用它来重新计算坐标并在屏幕上显示它们。
我已经设法能够更改圆圈的填充但除此之外,更新功能不会更新圆圈的坐标以及添加新圆圈。我真的很感激,如果有人可以帮助我实现这一目标,并提供一些有关我的方法失败的见解。
var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;
function points() {
coords = []; //Clear Coords Array
for (var i = 0; i < n; i++) {
var p_i = {};
p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
p_i.id = i;
coords.push(p_i);
}
//id++;
};
points(); //Generate Points
var svg = d3.select('body') //SVG Canvas
.append('svg')
.attr('width', w)
.attr('height', h);
var circle = svg.append('circle') //Draw Big Circle
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r)
.attr('fill', 'teal')
.attr('stroke', 'black')
.attr('stroke-width', w / 100);
var center = svg.append('circle') //Construct Center
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r / 50)
.attr('fill', 'red')
.attr('stroke', 'red')
.attr('stroke-width', w / 100);
var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
.data(coords, function(d) {
return d.id; //Sets Identifier to uniquely identify data.
})
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', w / 100)
.attr('fill', 'red');
var approx_tri = svg.selectAll('polygon') //Draw Triangles
.data(coords, function(d) {
return d.id;
})
.enter()
.append('polygon')
.attr('points', function(d, i) {
if (i != n - 1) {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
} else {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
}
})
.attr('fill', 'Transparent')
.attr('stroke', 'orange')
.attr('stroke-width', w / 250);
d3.select('#slider') //Listen to Slider Event Change
.on('input', function() {
n = +this.value;
update(n);
});
function update() {
console.log('Hey man!');
points(); // Re-generate points
console.log('coords[1].x = ' + coords[1].x);
console.log('coords[1].y = ' + coords[1].y);
//Make Selection
approx_pts
.selectAll('circle')
.data(coords, function(d) {
return d.id;
});
approx_pts
.attr('fill', 'blue')
.attr('r', r / 25);
approx_pts
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', r / 50)
.attr('fill', 'green');
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">
答案 0 :(得分:3)
您错过了正确的“输入”,“更新”和“退出”选项:
var updateSelection = svg.selectAll('.circle_points')
.data(coords, function(d) {
return d.id;
});
var exitSelection = updateSelection.exit().remove();
updateSelection.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', r / 50)
.attr('fill', 'blue')
.attr('r', r / 25);
var enterSelection = updateSelection.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', r / 50)
.attr('fill', 'green')
.attr("class", "circle_points");
以下是包含这些更改的代码:
var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;
function points() {
coords = []; //Clear Coords Array
for (var i = 0; i < n; i++) {
var p_i = {};
p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
p_i.id = i;
coords.push(p_i);
}
//id++;
};
points(); //Generate Points
var svg = d3.select('body') //SVG Canvas
.append('svg')
.attr('width', w)
.attr('height', h);
var circle = svg.append('circle') //Draw Big Circle
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r)
.attr('fill', 'teal')
.attr('stroke', 'black')
.attr('stroke-width', w / 100);
var center = svg.append('circle') //Construct Center
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r / 50)
.attr('fill', 'red')
.attr('stroke', 'red')
.attr('stroke-width', w / 100);
var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
.data(coords, function(d) {
return d.id; //Sets Identifier to uniquely identify data.
})
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', w / 100)
.attr('fill', 'red')
.attr("class", "circle_points");
var approx_tri = svg.selectAll('polygon') //Draw Triangles
.data(coords, function(d) {
return d.id;
})
.enter()
.append('polygon')
.attr('points', function(d, i) {
if (i != n - 1) {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
} else {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
}
})
.attr('fill', 'Transparent')
.attr('stroke', 'orange')
.attr('stroke-width', w / 250);
d3.select('#slider') //Listen to Slider Event Change
.on('input', function() {
n = +this.value;
update(n);
});
function update() {
points(); // Re-generate points
//Make Selection
var updateSelection = svg.selectAll('.circle_points')
.data(coords, function(d) {
return d.id;
});
var exitSelection = updateSelection.exit().remove();
updateSelection.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', r / 50)
.attr('fill', 'blue')
.attr('r', r / 25);
var enterSelection = updateSelection.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', r / 50)
.attr('fill', 'green')
.attr("class", "circle_points");
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">
答案 1 :(得分:1)
您需要删除&#39; circle_points&#39;然后是.exit()。remove()然后是.enter()
此处需要Update Pattern。
var w = 500;
var h = 250;
var n = 4;
var r = h / 2 - 201
var coords = [];
//var id = 0;
function points() {
coords = []; //Clear Coords Array
for (var i = 0; i < n; i++) {
var p_i = {};
p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
p_i.id = i;
coords.push(p_i);
}
};
points(); //Generate Points
var svg = d3.select('body') //SVG Canvas
.append('svg')
.attr('width', w)
.attr('height', h);
var circle = svg.append('circle') //Draw Big Circle
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r)
.attr('fill', 'teal')
.attr('stroke', 'black')
.attr('stroke-width', w / 100);
var center = svg.append('circle') //Construct Center
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r / 50)
.attr('fill', 'red')
.attr('stroke', 'red')
.attr('stroke-width', w / 100);
var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
.data(coords, function(d) {
return d.id; //Sets Identifier to uniquely identify data.
})
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', w / 100)
.attr('fill', 'red');
var approx_tri = svg.selectAll('polygon') //Draw Triangles
.data(coords, function(d) {
return d.id;
})
.enter()
.append('polygon')
.attr('points', function(d, i) {
if (i != n - 1) {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
} else {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
}
})
.attr('fill', 'Transparent')
.attr('stroke', 'orange')
.attr('stroke-width', w / 250);
d3.select('#slider') //Listen to Slider Event Change
.on('input', function() {
n = +this.value;
update(n);
});
function update(n) {
points(); // Re-generate points
d3.selectAll("circle").remove();
var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
.data(coords);
approx_pts.exit().remove();
approx_pts.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', 6)
.attr('fill', 'red');
d3.selectAll("polygon").remove();
var approx_tri = svg.selectAll('polygon') //Draw Triangles
.data(coords)
approx_tri.exit().remove();
approx_tri.enter()
.append('polygon')
.attr('points', function(d, i) {
if (i != n - 1) {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
} else {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
}
})
.attr('fill', 'Transparent')
.attr('stroke', 'orange')
.attr('stroke-width', w / 250);
};
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<input id="slider" type="range" min="3" max="100" step="4" value="17">
</body>
&#13;
答案 2 :(得分:0)
var w = 500;
var h = 500;
var n = 17;
var r = h / 2 - 20;
var coords = [];
//var id = 0;
function points() {
coords = []; //Clear Coords Array
for (var i = 0; i < n; i++) {
var p_i = {};
p_i.x = w / 2 + r * math.cos((2 * math.pi / n) * i);
p_i.y = h / 2 - r * math.sin((2 * math.pi / n) * i);
p_i.id = i;
coords.push(p_i);
}
//id++;
};
points(); //Generate Points
var svg = d3.select('body') //SVG Canvas
.append('svg')
.attr('width', w)
.attr('height', h);
var circle = svg.append('circle') //Draw Big Circle
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r)
.attr('fill', 'teal')
.attr('stroke', 'black')
.attr('stroke-width', w / 100);
var center = svg.append('circle') //Construct Center
.attr('cx', w / 2)
.attr('cy', h / 2)
.attr('r', r / 50)
.attr('fill', 'red')
.attr('stroke', 'red')
.attr('stroke-width', w / 100);
var approx_pts = svg.selectAll('circle_points') //Construct Approx Points
.data(coords, function(d) {
return d.id; //Sets Identifier to uniquely identify data.
})
.enter()
.append('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('r', w / 100)
.attr('fill', 'red');
var approx_tri = svg.selectAll('polygon') //Draw Triangles
.data(coords, function(d) {
return d.id;
})
.enter()
.append('polygon')
.attr('points', function(d, i) {
if (i != n - 1) {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[i + 1].x + ',' + coords[i + 1].y;
} else {
return w / 2 + ',' + h / 2 + ' ' + d.x + ',' + d.y + ' ' + coords[0].x + ',' + coords[0].y;
}
})
.attr('fill', 'Transparent')
.attr('stroke', 'orange')
.attr('stroke-width', w / 250);
d3.select('#slider') //Listen to Slider Event Change
.on('input', function() {
n = +this.value;
update(n);
});
function update(n) {
//console.log('Hey man!');
points(); // Re-generate points
//console.log('coords[1].x = ' + coords[1].x);
//console.log('coords[1].y = ' + coords[1].y);
//Make Selection
approx_pts
.selectAll('circle')
.data(coords, function(d) {
return d.id;
});
approx_pts
.attr('fill', 'blue')
.attr('r', r / 25);
approx_pts
.attr('cx', function(d) {
return (d.x)+n;
})
.attr('cy', function(d) {
return d.y+n;
})
.attr('r', r / 50)
.attr('fill', 'green');
};
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.16.2/math.min.js"></script>
<input id="slider" type="range" min="3" max="100" step="1" value="3">
&#13;
请记住在拖动时更新值