我正在尝试绘制条形图,然后对其进行排序,并更改已排序条形的颜色。我已经绘制了图表,显示了每个步骤。由于我使用的是选择排序算法,因此从头到尾的小节将逐步更改颜色。我无法更改颜色,因为我正在使用滤镜,并且无法估计滤镜中的函数要传递的内容。这是我的尝试:
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Bar chart with D3.js</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="styles/da.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<div id='layout'>
<h2>Bar chart example</h2>
<div class='container'>
<svg class="chart" height="500" width="1000"/>
</div>
</div>
<p>Why this is not working?? </p>
</body>
<script>
var data = [12,4,5,1,7,20,18,9,11,6,3,17,8,2];
// var data2=data;
var i=0;
var svg = d3.select("svg");
console.log();
svg.selectAll("*").remove();
var margin=50,
width=svg.attr("width")-margin,
height=svg.attr("height")-margin;
var Xscale = d3.scaleBand()
.domain(data.map((e,i) => i+1))
.range([0, width])
.padding(0.2);
var Yscale=d3.scaleLinear()
.domain([0,d3.max(data)])
.range([height,0]);
var g=svg.append("g")
.attr("transform","translate("+margin+","+margin+")");
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(Xscale).tickFormat(function(d){
return d;
}).ticks(data.length))
;
g.append("g")
.call(d3.axisLeft(Yscale).tickFormat(function(d){
return d;
}).ticks(10))
.append("text")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("value");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d,i) { return Xscale(i+1); })
.attr("y", function(d,i) { return Yscale(d); })
.attr("width", Xscale.bandwidth())
.attr("height", function(d,i) { return height-Yscale(d); });
// data2=[10,9,8,7,6,5,4,3,2,1];
// data3=[1,2,3,4,5,6,7,8,9,10];
// setTimeout(function(){return 1;},1000);
// for(var i=0;i<data.length;i++){
// var min=i;
// for(var j=i;j<data.length;j++){
// if(data[j]<data[i])
// min=j;
// }
// var temp=data[i];
// data[i]=data[min];
// data[min]=temp;
// update(data);
var s_sort_timeout=setInterval(function(){check();},1000);
function check(){
selection_sort(i);
update(data,i);
// if(i==data.length-1)
// data2=data;
i++;
if(i>=data.length){
clearTimeout(s_sort_timeout);
// flash(-1);
}
}
function selection_sort(i) {
var min_index=i;
// console.log(i,min_index)
for(var j=i;j<data.length+1;j++){
if(data[j]<data[min_index])
min_index=j;
}
var temp=data[i];
data[i]=data[min_index];
data[min_index]=temp;
console.log("Swapped"+data[i]+" with "+data[min_index])
}
function flash(i) {
d3.selectAll(".bar")
.filter(function (d) {
console.log("here " +Yscale(d)+" "+data[i]);
return (false);
})
.style("fill","orange");
}
function update(data2,i){
svg.selectAll("bars").remove();
Xscale.domain(data2.map((e,i) => i+1)).range([0, width])
.padding(0.2);
Yscale.domain([0,d3.max(data2)]);
var bars = svg.selectAll(".bar")
.remove().exit()
.data(data2);
bars.enter().append("rect")
.attr("class","bar")
.attr("x", function(d,i) { return margin+Xscale(i+1); })
.attr("y", function(d,i) { return margin+Yscale(d); })
.attr("width", Xscale.bandwidth())
.attr("height", function(d,i) { return height-Yscale(d); });
flash(i);
}
</script>
</html>
为了简短起见,我想过滤带有值data [i]的条,请参阅flash()函数。好厉害我猜是什么。 但是,尝试了许多事情之后,我什么也没得到。请帮忙。谢谢!
答案 0 :(得分:1)
正如docs所说,d3.filter
过滤选择,返回一个新选择,该选择仅包含指定过滤器为true的元素。
在d3中使用匿名函数时,字母d
通常用于引用每次迭代中data()
中的每个元素。因此,如果我对不起,那么您的flash
函数应如下所示:
function flash(i) {
d3.selectAll(".bar")
.filter(function(d) {
return d == data[i];
})
.style("fill", "orange");
}