我想在D3中实现一个条形图,但我在dx轴上的值是Date类型,D3库应该接受的数据类型,但它似乎给我一个这样的错误:属性宽度:预期长度,"NaN ".这是我的代码:
<html>
<head>
<meta charset="utf-8">
<title>a bar graph</title>
</head>
<style>
.axis path,
.axis line{
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
.MyRect {
fill: steelblue;
}
.MyText {
fill: white;
text-anchor: middle;
}
</style>
<body>
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script>
var width=400;
var height=400;
var svg=d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var padding = {left:30, right:30, top:20, bottom:20};
var dataset=[10,20,30,40,33,24,12,5];
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, width-padding.left-padding.right]);
var yScale = d3.scaleLinear()
.domain([0,d3.max(dataset)])
.range([height-padding.top-padding.bottom,0]);
var xAxis = d3.axisBottom()
.scale(xScale)
var yAxis = d3.axisLeft()
.scale(yScale)
var rectPadding=4;
var rects = svg.selectAll(".Myrect")
.data(dataset)
.enter()
.append("rect")
.attr("class","Myrect")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x",function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("width",xScale.range()- rectPadding)
.attr("height",function(d){
return height - padding.top - padding.bottom - yScale(d);
});
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.range() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
另一个错误:属性dx:预期长度,"NaN".我认为它来自乐队规模,但在使用官方介绍后,它仍然无法奏效.官方介绍:
var x = d3.scaleBand()
.domain(["a", "b", "c"])
.range([0, width]);
Run Code Online (Sandbox Code Playgroud)
因此,当我想调用代码时,我认为应该在我的粘贴代码中使用这样的代码:
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
})
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.range() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});
Run Code Online (Sandbox Code Playgroud)
但它似乎给了我两个错误.我是初学者.非常感谢你!
现在,对于矩形和dx文本的宽度,您正在使用:
xScale.range() - rectPadding
Run Code Online (Sandbox Code Playgroud)
但是xScale.range()返回一个数组,并且array - number会给你一个NaN。而且您不会带着NaN... 去任何地方
代替xScale.range(),它会返回一个数组,您应该使用:
xScale.bandwidth();
Run Code Online (Sandbox Code Playgroud)
不仅返回正确的数字,而且这也是您要查找的。
这是您所做的更改的代码:
xScale.range() - rectPadding
Run Code Online (Sandbox Code Playgroud)
PS:您不需要rectPadding。只需在band标度中设置填充即可:
var xScale = d3.scaleBand()
.domain(d3.range(dataset.length))
.range([0, width-padding.left-padding.right])
.padding(0.2);//some value here
Run Code Online (Sandbox Code Playgroud)