我正在尝试通过D3可视化进行Mergesort算法。在JS脚本中,我定义了全局变量(元素数量,时间等),svg,标签和圆圈。
var count = 11;
var durationTime = 250;
var array = d3.shuffle(d3.range(1,count));
var unsortedArray = [...array];
var sortedArray = [];
var stop = false;
var steps = 0;
var margin = {top: 40, right: 40, bottom: 180, left: 40},
width = 960 - margin.left - margin.right,
height = 100 - margin.top - margin.bottom;
var space = width/count;
changeElementNumber = function (elementNumber) {
count = elementNumber;
console.log(count);
reset();
};
changeElementSpeed = function (elementSpeedValue) {
durationTime = elementSpeedValue*1000;
}
var x = d3.scaleLinear().domain([0,count]).range([0, width]);
var svg = d3.select("#Merge").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("border","1")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var circles = svg.append("g")
.attr("transform", "translate(" + space + ",2)")
.selectAll("circle")
.data(unsortedArray)
.enter().append("circle");
circles.attr("id", function(d) {return "circle" + d})
.attr("transform", function(d, i) {return "translate(" + (x(i) - space) + ",0)"})
.attr("r","15")
.attr("fill", "#262626");
var labels = svg.selectAll("text")
.data(unsortedArray)
.enter().append("text")
labels.attr("id", function(d) {return "text" + d})
.attr("transform", function(d, i) {return "translate(" + (x(i) - 9) + ",8)"})
.html(function(d) {return d;})
.attr("fill", "#e2e2e2");
在HTML中,我可以看到10个带标签的圆圈(数字保存到数组中)。当我单击一个按钮进行合并排序时,这很好。我可以看到动画和所有内容。
function mergeSort() {
console.log(unsortedArray);
var mergeReps = (unsortedArray.length).toString(2).length + 1;
var mergeArrays = [[...unsortedArray], []];
for (i=0; i<unsortedArray.length; i += 2) {
mergeArrays[1].push(mergeTwo([unsortedArray[i]], [unsortedArray[i+1]]))
}
for (n=2; n<mergeReps; n++) {
mergeArrays[n] = [];
var unMerged = mergeArrays[n-1];
for (i=0; i<unMerged.length; i += 2) {
mergeArrays[n].push(mergeTwo(unMerged[i], unMerged[i+1] ? unMerged[i+1] : []))
}
}
for (i=1; i<mergeArrays.length; i++) {
mergeArrays[i] = d3.merge(mergeArrays[i])
}
mergeMove(0);
function mergeTwo(iArray, nArray) {
var newArray = [];
for (var i=0, n=0; i<iArray.length || n<nArray.length;) {
if (iArray[i] < nArray[n]) {
newArray.push(iArray[i++])
} else if (iArray[i] > nArray[n]) {
newArray.push(nArray[n++])
} else if (!(iArray[i])) {
newArray.push(nArray[n++])
} else if (!(nArray[n])) {
newArray.push(iArray[i++])
}
}
return newArray;
}
function mergeMove(j) {
var oldArray = mergeArrays[j],
newArray = [...mergeArrays[j+1]],
sortedArray = [];
moveStep(0);
function moveStep(n) {
if (stop) return stop = false;
d3.selectAll("circle").attr("class", "").attr("r", 15);
d3.select("#counter").html(++steps);
d3.select("#circle" + newArray[n]).attr("class", "testing").attr("r", 20);
sortedArray.push(newArray[n])
oldArray.shift()
circles.transition().duration(durationTime)
.attr("transform", function(d) {
var xVal = sortedArray.indexOf(d) > -1 ? sortedArray.indexOf(d) : oldArray.indexOf(d) + sortedArray.length;
return "translate(" + x(xVal - 1) + ",0)"
})
labels
.classed("sorted", function(d) {
return !mergeArrays[j + 2] && sortedArray.indexOf(d) == d - 1;
})
.transition().duration(durationTime)
.attr("transform", function(d) {
var xVal = sortedArray.indexOf(d) > -1 ? sortedArray.indexOf(d) : oldArray.indexOf(d) + sortedArray.length;
return "translate(" + (x(xVal) - 9) + ",8)"
})
d3.timeout(function() {
if (oldArray.length > 0) {
moveStep(++n)
} else if (mergeArrays[j + 2]) {
mergeMove(++j)
} else {
circles.classed("testing", false)
}
}, durationTime);
}
}
}
问题: 现在,在HTML中,我放置了新的元素数量(假设为7)和新的持续时间(持续时间现在不重要,我正在尝试解决数组问题。)并使用“重置”功能定义了新的全局变量,删除svg并制作一个新的。我也放了console.log,它工作正常:每按一次按钮,该数组中的元素都会更改。但是在单击按钮进行mergesort之后,该第一个创建的数组将用作新数组。没有动画,甚至没有最后排序。
changeElementNumber = function (elementNumber) {
count = elementNumber;
console.log(count);
reset();
};
changeElementSpeed = function (elementSpeedValue) {
durationTime = elementSpeedValue*1000;
}
function reset() {
var array = d3.shuffle(d3.range(1,count));
var unsortedArray = [...array];
var sortedArray = [];
console.log(unsortedArray);
d3.select("#counter").html(steps = 0)
d3.selectAll("svg").remove();
var x = d3.scaleLinear().domain([0,count]).range([0, width]);
var svg = d3.select("#Merge").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("border","1")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var circles = svg.append("g")
.attr("transform", "translate(" + space + ",2)")
.selectAll("circle")
.data(unsortedArray)
.enter().append("circle");
circles.attr("id", function(d) {return "circle" + d})
.attr("transform", function(d, i) {return "translate(" + (x(i) - space) + ",0)"})
.attr("r","15")
.attr("fill", "#262626");
var labels = svg.selectAll("text")
.data(unsortedArray)
.enter().append("text")
labels.attr("id", function(d) {return "text" + d})
.attr("transform", function(d, i) {return "translate(" + (x(i) - 9) + ",8)"})
.html(function(d) {return d;})
.attr("fill", "#e2e2e2");
array = d3.shuffle(d3.range(1,count));
unsortedArray = [...array];
sortedArray = [];
stop = false;
}
不更改元素数量的控制台日志:
mergeD3.js:8 Default array: 6,7,3,9,1,4,8,2,10,5
mergeD3.js:55 New array but in mergesort function: 6,7,3,9,1,4,8,2,10,5
mergeD3.js:130 Sorted: 6,7,3,9,1,4,8,2,10,5
更改元素数后的控制台日志:
mergeD3.js:8 Default array: 4,5,6,9,7,8,2,1,10,3
mergeD3.js:17 new number of elemets: 7
mergeD3.js:143 New array: 3,1,4,6,5,2
mergeD3.js:55 New array but in mergesort function: 4,5,6,9,7,8,2,1,10,3
mergeD3.js:130 Sorted: 4,5,6,9,7,8,2,1,10,3