我现在正在处理条形图,它在格式上与这里的类似http://bl.ocks.org/kiranml1/6872226,左侧为"x轴",底部为"y轴"。我在左边有一些数字作为我的"类别",比如3048、3060、3096…等等。这些类别中的每一个都是一个数字,每个都有某种不同。
我想知道,我该如何制作条形图,使每个类别的间距不均匀?现在,我有rangeroundbands
,它使它们的间距均匀,但我正在努力使条形之间的距离与类别之间的数字差相关。例如,假设3048、3096、4050,3048和3096之间的距离将小于3096和4050之间的距离,这足够直观,但也不会使条形图变得太大。
var yScale = d3.scale.ordinal()
.domain(d3.extent(molecules_0, function(d) {
return parseInt(d.molweight);
}))
.rangeRoundBands([padding, height - padding]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.tickSize(2)
.tickFormat(function(d, i) {
return molecules_0[i].molweight;
})
.tickValues(d3.range(20));
您必须修改Y轴。目前,它只使用categories
阵列的长度:
var yscale = d3.scale.linear()
.domain([0,categories.length])
.range([0,480]);
你真正要做的就是更改域的输入:
.domain(d3.extent(categories))
因此,您的Y位置也将基于类别值。
您希望以SVG rect
元素的y属性为目标。假设您的类别是一个类似[304830066]的数组,您可以将y属性设置为categories[i+1]-categories[i]。
以上内容在数组的最后一个元素处不起作用,因为[i+1]将是未定义的。您可以将语句包装成三进制,这样如果i===0,它只会返回零(因为0是falsy)。看起来是这样的:
i ? categories[i+1] - categories[i] : 0
如果比较容易的话,您可以创建一个"differences"数组,如下所示:[0,12,36]。这可能更容易处理,并且在计算记号的位置时可以重用它。(请参阅axy.tickValues([values])的D3文档。您可以提供一个数组来控制轴刻度位置)。
您可能还需要添加一些填充(somePadding
)。默认填充为19。
见以下建议修订:
var chart = canvas.append('g')
.attr("transform", "translate(150,0)")
.attr('id','bars')
.selectAll('rect')
.data(dollars)
.enter()
.append('rect')
.attr('height',19)
//.attr({'x':0,'y':function(d,i){ return yscale(i)+19; }})
// modify the y attribute of each SVG rect element
.attr({'x':0,'y':function(d,i){ return yscale(i) + (i ? categories[i+1] - categories[i] : 0) + somePadding; }})
.style('fill',function(d,i){ return colorScale(i); })
.attr('width',function(d){ return 0; });