我正在研究的D3图表有几个问题:
我无法让y axis
在页面上正确对齐。数字超过了最左边的边界,无法看到。
我希望条形图中使用的列在刻度线之间整齐排列,并在两侧均匀分布。
小提琴:http://jsfiddle.net/bf1gf8ep/8/
D3.js
var barWidth = 70;
var width = (barWidth + 10) * 7;
var height = 200;
var data = [{"label" : "1/7yrs", "contract" : "111830.17", "annReturn" : "1.63%"},
{"label" : "2/7yrs", "contract" : "115311.17", "annReturn" : "2.07%"},
{"label" : "3/7yrs", "contract" : "118984.65", "annReturn" : "2.52%"},
{"label" : "4/7yrs", "contract" : "122859.65", "annReturn" : "2.98%"},
{"label" : "5/7yrs", "contract" : "126947.77", "annReturn" : "3.46%"},
{"label" : "6/7yrs", "contract" : "131260.74", "annReturn" : "3.94%"},
{"label" : "7/7yrs", "contract" : "135810.92", "annReturn" : "4.44%"}];
var margin = { top: 20, right: 20, bottom: 20, left: 20 };
var chart = d3.selectAll("body").append("svg:svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom + 20);
var x = d3.scale.linear().domain([0, data.length]).range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);
chart.append("g")
.attr("class", "axis").call(xAxis)
.attr("transform", "translate(0," + (height) + ")");
chart.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + 10 + ",0)")
.call(yAxis);
x = d3.scale.linear().domain([0, data.length]).range([0, width]);
y = d3.scale.linear().domain([0, 135810.92 + 1000]).range([height, 0]);
chart.selectAll("rect")
.data(data)
.enter()
.append("svg:rect")
.attr("x", function (d, i) { return x(i); })
.attr("y", function (d) { return y(d.contract); })
.attr("height", function (d) { return height - y(d.contract); })
.attr("width", barWidth)
.attr("fill", "#2d578b");
chart.selectAll("text.contractInfo")
.data(data)
.enter()
.append("svg:text")
.attr("x", function(d, i) { return x(i) + barWidth; })
.attr("y", function(d) { return y(d.contract); })
.attr("dx", -barWidth / 2)
.attr("dy", "1.2em")
.attr("text-anchor", "middle")
.text(function(d) { return d.contract; })
.attr("fill", "white")
.attr("class", "contractInfo");
chart.selectAll("text.yAxis")
.data(data)
.enter().append("svg:text")
.attr("x", function (d, i) { return x(i) + barWidth; })
.attr("y", height)
.attr("dx", -barWidth / 2)
.attr("dy", "15px")
.attr("text-anchor", "middle")
.attr("style", "font-size: 12; font-family; Helvetica, sans-serif")
.text(function (d) { return d.label; })
.attr("transform", "translate(0, 18)")
.attr("class", "yAxis");
屏幕截图
答案 0 :(得分:2)
您已完成所有艰苦工作,只需稍微使用保证金变量即可。你真正想做的是通过20px
或margin.left
向右推杆,并将它们居中。 width
变量已设置为barwidth + 10
,因此您需要10px
填充。要使其居中,您需要将一半填充添加到条带宽度。因此,在创建条形图时将它们放在一起需要添加margin.left和5,即:
.attr("x", function (d, i) { return x(i) + margin.left + 5; })
您还需要使用完全相同的代码移动文本。
还需要移动xAxis,再次添加margin.left值,如:
.attr("transform", "translate(" + margin.left + "," + (height) + ")");
我还注意到你硬编码了y scale max,所以我引入了ymax变量来计算最大值并修改y变量如下所示;
var ymax = d3.max(data, function(d) { return d.contract; });
var y = d3.scale.linear().domain([0, ymax]).range([height, 0]);
上述方法的替代方法是附加一个组元素以放置条形并通过margin变量转换该组。这样可以避免在条形几何中使用边距变量。
无论如何,我已经碰到了你的小提琴,里面包含here的更新