这是代码。
var mapXOffset = 20;
var mapYOffset = 20;
var personSize = 4;
var redCount = 200;
var blueCount = 200;
function redraw() {
var svg = d3.select("svg");
var tempArray = makeRandomArray(0,10000, redCount+blueCount);
var redArray = tempArray.slice(0,redCount);
var blueArray = tempArray.slice(redCount,redCount+blueCount);
var redData = svg.selectAll("rect.red")
.data(redArray);
var blueData = svg.selectAll("rect.blue")
.data(blueArray);
redData.enter().append("rect")
.attr("x", function(d, i)
{
return mapXOffset + personSize * (d%100);
})
.attr("y", function(d)
{
return mapYOffset + personSize * (d/100);
})
.attr("width", personSize)
.attr("height", personSize)
.attr("class", "red");
blueData.enter().append("rect")
.attr("x", function(d, i)
{
return mapXOffset + personSize * (d%100);
})
.attr("y", function(d)
{
return mapYOffset + personSize * (d/100);
})
.attr("width", personSize)
.attr("height", personSize)
.attr("class", "blue");
redData.transition()
.duration(1000)
.attr("x", function(d, i)
{
return mapXOffset + personSize * (d%100);
})
.attr("y", function(d)
{
return mapYOffset + personSize * (d/100);
});
blueData.transition()
.duration(1000)
.attr("x", function(d, i)
{
return mapXOffset + personSize * (d%100);
})
.attr("y", function(d)
{
return mapYOffset + personSize * (d/100);
});
};
如图所示,除redData
部分外,blueData
和.attr("class", "");
的工作几乎相同。重构代码的方法更好:(1)将redundent代码包装到函数中(2)创建数组[redArray, BlueArray]
并迭代它。或者其他方式更喜欢?
答案 0 :(得分:1)
本质上,您希望使用getter-setter方法将图表实现为闭包,这使您可以根据需要重复使用图表代码,同时还可以为您提供修改现有图表对象属性的可配置性。
答案 1 :(得分:1)
看起来你可以简单地通过创建updateData()
方法并从重绘中调用它来重构。
function updateData(selector, class, array) {
var svg = d3.select("svg");
var data = svg.selectAll(selector).data(array);
data.enter().append('rect')
.attr('x', function(d, i) {
return mapXOffset + personSize * (d%100); })
.attr('y', function(d) {
return mapYOffset + personSize * (d/100); })
.attr("width", personSize)
.attr("height", personSize)
.attr("class", class);
data.transition()
.duration(1000)
.attr("x", function(d, i) {
return mapXOffset + personSize * (d%100); })
.attr("y", function(d) {
return mapYOffset + personSize * (d/100); });
}
function redraw() {
var tempArray = makeRandomArray(0,10000, redCount+blueCount);
var redArray = tempArray.slice(0,redCount);
var blueArray = tempArray.slice(redCount,redCount+blueCount);
updataData('rect.red', 'red', redArray);
updataData('rect.blue', 'blue', blueArray);
};
或者,您可以在svg
中定义refresh
并将其作为另一个参数传递。如果添加的参数太多,请考虑将它们作为对象文字传递。
您也可以迭代一个数组,但每个数组元素需要的参数多于redArray
和blueArray
。最终,它是基于哪种方法产生最简洁和/或可读代码的判断调用。
这就是我想象阵列版本的样子。它具有一定的吸引力,因为它不需要单独的函数定义。
function redraw() {
var tempArray = makeRandomArray(0,10000, redCount+blueCount);
var redArray = tempArray.slice(0,redCount);
var blueArray = tempArray.slice(redCount,redCount+blueCount);
var svg = d3.select("svg");
var red = {selector: 'rect.red', class: 'red', array: redArray};
var blue = {selector: 'rect.blue', class: 'blue', array: blueArray};
[red, blue].forEach(function(item) {
var data = svg.selectAll(item.selector).data(item.array);
data.enter().append('rect')
.attr('x', function(d, i) {
return mapXOffset + personSize * (d%100); })
.attr('y', function(d) {
return mapYOffset + personSize * (d/100); })
.attr("width", personSize)
.attr("height", personSize)
.attr("class", item.class);
data.transition()
.duration(1000)
.attr("x", function(d, i) {
return mapXOffset + personSize * (d%100); })
.attr("y", function(d) {
return mapYOffset + personSize * (d/100); });
});
}