我正在尝试创建一个使用时间刻度(日期)作为x轴的发散条形图。我在使用带日期的ScaleBands时遇到问题,日期标签重叠。
这是我到目前为止所得到的。 https://jsfiddle.net/14ch7yeo/当我使用scaleTime时,遗憾的是,图表无法加载。
我需要在此图表上使用缩放和画笔。
<!DOCTYPE html>
<meta charset="utf-8">
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var data = [{"Date":"2015-01-02T00:00:00.000Z","Buy":554646.5,"Sell":-406301.3547},{"Date":"2015-02-02T00:00:00.000Z","Buy":565499.5,"Sell":-673692.5697},{"Date":"2015-03-02T00:00:00.000Z","Buy":421954.5,"Sell":-571685.4629},{"Date":"2015-04-02T00:00:00.000Z","Buy":466242.0,"Sell":-457477.7121},{"Date":"2015-05-02T00:00:00.000Z","Buy":350199.7,"Sell":-579682.8772},{"Date":"2015-06-02T00:00:00.000Z","Buy":391035.1,"Sell":-338816.6205},{"Date":"2015-07-02T00:00:00.000Z","Buy":437644.6,"Sell":-502329.557},{"Date":"2015-08-02T00:00:00.000Z","Buy":291978.9,"Sell":-504067.0329},{"Date":"2015-09-02T00:00:00.000Z","Buy":360913.8,"Sell":-489519.6652},{"Date":"2015-10-02T00:00:00.000Z","Buy":505799.1,"Sell":-723353.7089},{"Date":"2015-11-02T00:00:00.000Z","Buy":510691.0,"Sell":-374061.8139},{"Date":"2015-12-02T00:00:00.000Z","Buy":527757.1,"Sell":-597800.0116},{"Date":"2016-01-02T00:00:00.000Z","Buy":564799.1,"Sell":-451779.1593},{"Date":"2016-02-02T00:00:00.000Z","Buy":336533.7,"Sell":-522601.1707},{"Date":"2016-03-02T00:00:00.000Z","Buy":460684.6,"Sell":-643556.0079999999},{"Date":"2016-04-02T00:00:00.000Z","Buy":428388.1,"Sell":-349216.2376},{"Date":"2016-05-02T00:00:00.000Z","Buy":525459.5,"Sell":-597258.4075},{"Date":"2016-06-02T00:00:00.000Z","Buy":677659.1,"Sell":-513192.107},{"Date":"2016-07-02T00:00:00.000Z","Buy":365612.8,"Sell":-287845.8089},{"Date":"2016-07-03T00:00:00.000Z","Buy":358775.2,"Sell":-414573.209}]
var parseTime = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ");
data.forEach(d => {
d["Date"] = parseTime(d["Date"]);
})
var series = d3.stack()
.keys(["Buy", "Sell"])
.offset(d3.stackOffsetDiverging)
(data);
var svg = d3.select("svg"),
margin = {top: 20, right: 30, bottom: 30, left: 60},
width = +svg.attr("width"),
height = +svg.attr("height");
var x = d3.scaleBand()
.domain(data.map(function(d) { return d['Date']; }))
.rangeRound([margin.left, width - margin.right])
.padding(0.1);
var y = d3.scaleLinear()
.domain([d3.min(series, stackMin), d3.max(series, stackMax)])
.rangeRound([height - margin.bottom, margin.top]);
var z = d3.scaleOrdinal()
.range(["green","red"]);
svg.append("g")
.selectAll("g")
.data(series)
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("width", x.bandwidth)
.attr("x", function(d) { return x(d.data["Date"]); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
svg.append("g")
.attr("transform", "translate(0,"+ (height-margin.top) + ")")
.call(d3.axisBottom(x));
svg.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));
function stackMin(serie) {
return d3.min(serie, function(d) { return d[0]; });
}
function stackMax(serie) {
return d3.max(serie, function(d) { return d[1]; });
}
</script>
答案 0 :(得分:1)
d3.scaleTime
必须在多个方面区别对待。
比例不会将填充作为参数:
var x = d3.scaleTime()
.domain(d3.extent(data, function(d) { return d.Date; }))
.rangeRound([margin.left, width - margin.right]);
时间是连续的而不是谨慎的,因此条形的宽度需要手动计算为rect
属性的比率。我得到了这个,但也许你想要更优雅的东西:
.attr("width", width/series.length - 450)