D3 v4 - 制作固定宽度的水平条形图
D3 v4 - make a horizontal bar chart with fixed width
我使用 d3 v4 制作了一个水平条形图,除了一件事外它工作正常。我无法固定条形高度。我目前正在使用 bandwidth() 并且如果我用固定值替换它说 (15) 问题是它不与 y 轴对齐 label/tick http://jsbin.com/gigesi/3/edit?html,css,js,output
var w = 200;
var h = 400;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.attr("transform", "translate(80,30)");
var data = [
{Item: "Item 1", count: "11"},
{Item: "Item 2", count: "14"},
{Item: "Item 3", count: "10"},
{Item: "Item 4", count: "14"}
];
var xScale = d3.scaleLinear()
.rangeRound([0,w])
.domain([0, d3.max(data, function(d) {
return d.count;
})]);
var yScale = d3.scaleBand()
.rangeRound([h,0]).padding(0.2)
.domain(data.map(function(d) {
return d.Item;
}));
var yAxis = d3.axisLeft(yScale);
svg.append('g')
.attr('class','axis')
.call(yAxis);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('width', function(d,i) {
return xScale(d.count);
})
.attr('height', yScale.bandwidth())
.attr('y', function(d, i) {
return yScale(d.Item);
}).attr("fill","#000");
您提供的link中的y轴似乎偏离了SVG。 (也许您有 overflow: visible;
的 SVG。
无论如何,我在图表中添加了一些边距,以便可以看到整个图表。在这里(忽略link描述):
DEMO: H BAR CHART WITH HEIGHT POSITIONING TO THE TICKS
相关代码改动:
当您使用比例尺时,高度是在比例尺内计算的。你只需要使用 .bandWidth()
.
.attr('height', yScale.bandwidth())
添加边距并变换轴和条形图以使整个图表可见:
:我正在分配边距,以便 y-axis
位于 SVG 的视口内,这样也可以更轻松地根据刻度值调整左边距。我认为这应该是一种标准做法。
此外,如果您注意到,rects
即 条 现在是 <g class="bars"></g>
的一部分。如果愿意,请检查 DOM。这对于包含大量元素的复杂图表很有用,但它始终是一个好习惯。
var margin = {top: 10, left: 40, right: 30, bottom: 10};
var xScale = d3.scaleLinear()
.rangeRound([0,w-margin.left-margin.right])
var yScale = d3.scaleBand()
.rangeRound([h-margin.top-margin.bottom,0]).padding(0.2)
svg.append('g')
.attr('class','axis')
.attr('transform', 'translate(' + margin.left+', '+margin.top+')')
尝试更改数据,条形高度 将根据刻度进行调整和对齐。希望这可以帮助。如果您有任何问题,请告诉我。
编辑:
最初,我认为您在将条形图放置在 y 刻度的中心时遇到了问题,但正如您所说,您需要固定高度的条形图,这里是对上述代码的快速补充,可以让您做到这一点。我将很快添加另一种使用填充(内部和外部)的方法。
为了将条形图精确定位在轴刻度的位置,我将条形图从顶部移动到 刻度的带宽 ,这是由 .bandWidth()
计算得出的它的位置将从刻度开始,现在从中减去 所需高度的一半 ,以便条形中心与刻度 y
匹配。希望这能解释。
.attr('height', 15)
.attr('transform', 'translate(0, '+(yScale.bandwidth()/2-7.5)+')')
我使用 d3 v4 制作了一个水平条形图,除了一件事外它工作正常。我无法固定条形高度。我目前正在使用 bandwidth() 并且如果我用固定值替换它说 (15) 问题是它不与 y 轴对齐 label/tick http://jsbin.com/gigesi/3/edit?html,css,js,output
var w = 200;
var h = 400;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.attr("transform", "translate(80,30)");
var data = [
{Item: "Item 1", count: "11"},
{Item: "Item 2", count: "14"},
{Item: "Item 3", count: "10"},
{Item: "Item 4", count: "14"}
];
var xScale = d3.scaleLinear()
.rangeRound([0,w])
.domain([0, d3.max(data, function(d) {
return d.count;
})]);
var yScale = d3.scaleBand()
.rangeRound([h,0]).padding(0.2)
.domain(data.map(function(d) {
return d.Item;
}));
var yAxis = d3.axisLeft(yScale);
svg.append('g')
.attr('class','axis')
.call(yAxis);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('width', function(d,i) {
return xScale(d.count);
})
.attr('height', yScale.bandwidth())
.attr('y', function(d, i) {
return yScale(d.Item);
}).attr("fill","#000");
您提供的link中的y轴似乎偏离了SVG。 (也许您有 overflow: visible;
的 SVG。
无论如何,我在图表中添加了一些边距,以便可以看到整个图表。在这里(忽略link描述):
DEMO: H BAR CHART WITH HEIGHT POSITIONING TO THE TICKS
相关代码改动:
当您使用比例尺时,高度是在比例尺内计算的。你只需要使用
.bandWidth()
..attr('height', yScale.bandwidth())
添加边距并变换轴和条形图以使整个图表可见: :我正在分配边距,以便
y-axis
位于 SVG 的视口内,这样也可以更轻松地根据刻度值调整左边距。我认为这应该是一种标准做法。 此外,如果您注意到,rects
即 条 现在是<g class="bars"></g>
的一部分。如果愿意,请检查 DOM。这对于包含大量元素的复杂图表很有用,但它始终是一个好习惯。var margin = {top: 10, left: 40, right: 30, bottom: 10}; var xScale = d3.scaleLinear() .rangeRound([0,w-margin.left-margin.right]) var yScale = d3.scaleBand() .rangeRound([h-margin.top-margin.bottom,0]).padding(0.2) svg.append('g') .attr('class','axis') .attr('transform', 'translate(' + margin.left+', '+margin.top+')')
尝试更改数据,条形高度 将根据刻度进行调整和对齐。希望这可以帮助。如果您有任何问题,请告诉我。
编辑: 最初,我认为您在将条形图放置在 y 刻度的中心时遇到了问题,但正如您所说,您需要固定高度的条形图,这里是对上述代码的快速补充,可以让您做到这一点。我将很快添加另一种使用填充(内部和外部)的方法。
为了将条形图精确定位在轴刻度的位置,我将条形图从顶部移动到 刻度的带宽 ,这是由 .bandWidth()
计算得出的它的位置将从刻度开始,现在从中减去 所需高度的一半 ,以便条形中心与刻度 y
匹配。希望这能解释。
.attr('height', 15)
.attr('transform', 'translate(0, '+(yScale.bandwidth()/2-7.5)+')')