我有一个三条相互重叠的条形图。首先渲染灰色条形图,然后是鲑鱼一和蓝色条形图。但是当它们被排序时,这个顺序似乎随机变化,所以有时会在其他两个上面绘制一个灰色条,然后它们就看不到了。
解决方案: jsFiddle
以下是此问题的jsfiddle。
<!DOCTYPE html>
<body>
<div style="text-align:left;">
<form id="form">
<strong>Sort by: </strong><span class="clocktime-radio"><input type="radio" name="stack" checked value="clock">Clock time and place </span>
<span class="racetime-radio"><input class="racetime-radio" type="radio" name="stack" value="race">Race time </span>
<span class="handicap-radio"><input type="radio" name="stack" value="hand">Handicap </span>
</form>
</div>
<div id="race_graph">
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {
top: 50,
right: 50,
bottom: 100,
left: 80
},
width = 500 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
// Get the data
var data = [{
"name": "RT",
"clocktime": "21:33",
"handicap": "02:30",
"racetime": "19:03"
},
{
"name": "KM",
"clocktime": "22:13",
"handicap": "00:45",
"racetime": "21:28"
},
{
"name": "SD",
"clocktime": "22:15",
"handicap": "01:45",
"racetime": "20:30"
},
{
"name": "DK",
"clocktime": "22:20",
"handicap": "02:45",
"racetime": "19:35"
},
{
"name": "BD",
"clocktime": "22:21",
"handicap": "02:15",
"racetime": "20:06"
},
{
"name": "KC",
"clocktime": "22:21",
"handicap": "02:00",
"racetime": "20:21"
},
{
"name": "PM",
"clocktime": "22:22",
"handicap": "00:45",
"racetime": "21:37"
},
{
"name": "NR",
"clocktime": "22:23",
"handicap": "01:45",
"racetime": "20:38"
},
{
"name": "LM",
"clocktime": "22:25",
"handicap": "02:15",
"racetime": "20:10"
},
{
"name": "SL",
"clocktime": "22:26",
"handicap": "00:15",
"racetime": "22:11"
}
]
var parseTime = d3.timeParse("%M:%S");
var timeformat = d3.timeFormat("%M:%S")
// format the data
data.forEach(function(d) {
d.racetime = parseTime(d.racetime);
d.handicap = parseTime(d.handicap);
d.clocktime = parseTime(d.clocktime);
d.place = +d.place;
d.points = +d.points;
d.raceplace = +d.raceplace;
d.timeplace = +d.timeplace;
});
// set the domains and ranges
var x = d3.scaleBand()
.domain(data.map(function(d) {
return d.name
}))
.range([0, width]);
// temporal y-scale
var y = d3.scaleTime()
.domain([parseTime('00:00'), d3.max(data, function(d) {
return d.clocktime
// return d.handicap
})])
.range([height, 0]); //time must increase from 0 to height else racetime and handicap are inverted!!!
// spacial y-scale (race distance)
var y1 = d3.scaleLinear()
.domain([0, 1200]) //race distance
.range([height, 0]);
// points y-scale
var y2 = d3.scaleLinear()
.domain([0, 10]) //points awarded
.range([height, 0]);
//****************************
//***** Main Graph setup *****
//****************************
var svg = d3.select("#race_graph")
.data(data)
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Add the X Axis
var xAxis = d3.axisBottom(x)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.style("font", "7px times")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
// Add the left Y Axis
svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y)
.ticks(7)
.tickFormat(d3.timeFormat("%M:%S")));
// text label for the y axis on left
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Time (minutes:seconds)");
//************************************************************
//******* BarChart by clocktime *******************************
//************************************************************
var rects0 = svg.selectAll(".bar")
.data(data);
var newRects0 = rects0.enter();
// Note: y2(d.points) is the y coordinate of rect
newRects0.append('rect')
.attr('x', function(d, i) {
return x(d.name) + 2;
})
.attr('width', 20)
.attr("transform", "translate(5,0)")
.style('fill', 'gray')
.attr("class", "bar")
.attr('y', function(d, i) {
return y(d.clocktime);
})
.attr('height', function(d, i) {
return height - y(d.clocktime)
});
//************************************************************
//******* BarChart by racetime *******************************
//************************************************************
var newRects1 = rects0.enter();
// Note: y2(d.points) is the y coordinate of rect
newRects1.append('rect')
.attr('class', 'bar')
.attr('x', function(d, i) {
return x(d.name) + 2;
})
.attr('width', 20)
.attr("transform", "translate(5,0)")
.style('fill', 'salmon')
.attr('y', function(d, i) {
return y(d.racetime);
})
.attr('height', function(d, i) {
return height - y(d.racetime)
});
//************************************************************
//******* BarCharts by handicap ******************************
//************************************************************
var newRects2 = rects0.enter();
newRects2.append('rect')
.attr('x', function(d, i) {
return x(d.name) + 2;
})
.attr('width', 20)
.attr("transform", "translate(5,0)")
.style('fill', 'blue')
.attr('y', function(d, i) {
return y(d.handicap);
})
.attr('height', function(d, i) {
return height - y(d.handicap)
})
.attr('class', 'bar');
d3.selectAll("input[name='stack']").on("change", change);
function change() {
var x0 = x.domain(data.sort(this.value == "clock" ?
(function(a, b) {
return (new Date(b.clocktime) - new Date(a.clocktime)) * -1;
}) : (this.value == "race") ?
(function(a, b) {
return (new Date(b.racetime) - new Date(a.racetime)) * -1;
}) : (function(a, b) {
return (new Date(b.handicap) - new Date(a.handicap)) * -1;
})).map(function(d) {
return d.name;
}))
.copy();
svg.selectAll(".bar")
.sort(function(a, b) {
return x0(a.name) - x0(b.name);
});
var transition = svg.transition().duration(750),
delay = function(d, i) {
return i * 5;
};
transition.selectAll(".bar")
.delay(delay)
.attr("x", function(d) {
return x0(d.name);
});
transition.select(".x.axis") //selects the x-axis
.call(xAxis)
.selectAll("g")
.delay(delay);
}
</script>
</body>
也许当我绘制多个条形图时,我不应该像我一样重复每个条形图,并且有一些方法可以更有效地绘制它们,这将摆脱我所拥有的渲染问题。
由于