我是D3.js的新手,并且我的垂直条形图有问题.由于某种原因,当我使用rangeRoundBands进行缩放时,轴和条之间的距离太大了.
在API中,这样解释:
在API中,这样解释:
所以问题似乎是outerPadding.但是将outerPadding设置为零并没有帮助.但是,当我使用rangeBands时,问题就消失了,并且杆正确定位在轴的正下方.但是我会得到这些令人讨厌的抗锯齿效果,所以这不是一个真正的选择.这是我的代码:
var margin = {top: 40,right: 40,bottom: 20,left: 20},width = 900 - margin.left - margin.right,height = x - margin.top - margin.bottom; var x = d3.scale.linear().range([0,width]); var y = d3.scale.ordinal().rangeRoundBands([0,height],.15,0); var xAxis = d3.svg.axis() .scale(x) .orient("top"); var xAxis2 = d3.svg.axis() .scale(x) .orient("bottom"); var xAxis3 = d3.svg.axis() .scale(x) .orient("bottom") .tickSize(-height,0) .tickFormat(""); var svg = d3.select("#plotContainer").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 + ")"); x.domain(d3.extent(data,function(d) { return d.size; })).nice(); y.domain(data.map(function(d) { return d.name; })); svg.append("g") .attr("class","x axis") .call(xAxis); svg.append("g") .attr("class","x axis") .attr("transform","translate(0," + height + ")") .call(xAxis2); svg.append("g") .attr("class","grid") .attr("transform"," + height + ")") .call(xAxis3); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class",function(d) { return d.size < 0 ? "bar negative" : "bar positive"; }) .attr("x",function(d) { return x(Math.min(0,d.size)); }) .attr("y",function(d) { return y(d.name); }) .attr("width",function(d) { return Math.abs(x(d.size) - x(0)); }) .attr("height",y.rangeBand()) .append("title") .text(function(d) { return "This value is " + d.name; }); ; svg.selectAll(".bar.positive") .style("fill","steelblue") .on("mouSEOver",function(d) { d3.select(this).style("fill","yellow"); }) .on("mouSEOut","steelblue"); }); svg.selectAll(".bar.negative") .style("fill","brown") .on("mouSEOver","brown"); }); svg.selectAll(".axis") .style("fill","none") .style("shape-rendering","crispEdges") .style("stroke","#000") .style("font","10px sans-serif"); svg.selectAll(".grid") .style("fill","none") .style("stroke","lightgrey") .style("opacity","0.7"); svg.selectAll(".grid.path") .style("stroke-width","0");
编辑:
请看看这个小提琴:
http://jsfiddle.net/GUYZk/9/
我的问题是可重复的.您不能使用rangeRoundBands更改outerPadding,而rangeBands表现正常.
解决方法
TL; DR:这是数学的结果.要解决这个问题,请使用rangeBands布局栏,并在CSS中使用
shape-rendering: crispEdges
将其与像素边界对齐.
完全解释:
因为rangeRandsBands函数必须在所提供的像素范围内均匀分布条,而且它还必须提供整数rangeBand,它使用Math.floor来剔除每个连续条的分数位.
这种额外的外部填充化合物与更长的数据集的原因是因为所有这些分数像素必须在某处结束.此功能的作者选择在范围的开始和结束之间均匀分割它们.
因为每个圆形条的分数像素在间隔(0,1)上,所以每个端部上的额外像素将跨越数据条计数的约1/4.有10个酒吧,2-3个额外的像素将永远不会被注意到,但如果您有100个或更多,额外的25像素变得更加明显.
一个可能的解决方案似乎在Chrome中用于svg:rect:使用rangeBands布局,但是将shape-rendering: crispEdges
作为CSS样式应用到您的条形路径/ rects.
这样就可以使SVG渲染器上的元素轻推每个条形到像素边界,但它们的整体更均匀分布,间距方面的间隔偏差可以解释整个图表上的错误.
就个人而言,我使用形状渲染:optimizeSpeed,并让渲染代理进行任何权衡,以快速渲染(潜在的小数)条形位置.