我正在慢慢地学习如何使用 D3,但已经在我的第一个图表中我无法弄清楚为什么 x 轴位于顶部而不是底部。我已经设置了 orient('bottom') 并通过左边距和顶部边距进行了翻译,并且它相对于翻译正确定位,但它出现在条形图的顶部。任何人都可以看到问题是什么?该代码看起来与一堆示例相似,所以我不确定为什么它不能正常工作。
// Ordinal scale to transform data to fit width of the chart
// -- NOTE: ordinal is equivalent to an ordered list
xScale = d3.scale.ordinal()
.domain(d3.range(0, data.length))
.rangeBands([0, config.width],
config.rangeBandPadding,
config.rangeBandOuterPadding);
// Quantitative linear scale to transform data to fit height of the chart
// -- NOTE: quantitative is equivalent to an unordered list
yScale = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, config.height]);
// Create the <svg> canvas with chart group
svg = D3Service.getSvgCanvas($element[0],
config.outerWidth,
config.outerHeight,
config.margin)
// Add data bars to the chart and remap to scale to fit chart dimensions
// -- NOTE: Select all rects (that don't exist yet), bind the data to the selection, append
// the bound selections within a chart group and apply scaled dimensions, and finally add
// events to capture user interactions with the chart and transitions to animate the chart
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('width', xScale.rangeBand())
.attr('height', 0) // initialized to zero to allow for translation
.attr('x', function (d, i) {
return xScale(i);
})
.attr('y', config.height) // why???
// Bind events to the chart
.on('mouseover', function (d) {
})
.on('mouseout', function (d) {
})
.on('click', function (d) {
});
// Perform transitions on data bars as they are added to the chart
svg.selectAll('rect')
.transition()
.attr('y', function (d) {
return config.height - yScale(d);
})
.attr('height', function (d) {
return yScale(d);
})
.delay(function (d, i) {
return i * config.transitionDelayFactor;
})
.duration(500)
.ease('bounce');
// Uses range of xScale domain and filters the data bars to figure who to add a tick to
// does a number have a zero remainder and get a number every 5th bar
// From the range of
xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(data.length);
xGuide = d3.select('svg')
.append('g')
.attr('class', 'axes x-axis')
.call(xAxis)
.attr('transform',
D3Service.getTranslation(config.margin.left, config.margin.top));
yGuideScale = d3.scale.linear().domain([0, d3.max(data)])
.range([config.height, 0]);
yAxis = d3.svg.axis().scale(yGuideScale)
.orient('left').ticks(10)
yGuide = d3.select('svg')
.append('g')
.attr('class', 'axes y-axis')
.call(yAxis)
.attr('transform',
D3Service.getTranslation(config.margin.top, config.margin.left));
Run Code Online (Sandbox Code Playgroud)
乍一看,在查看您的代码时,我会说这是因为您没有定位包含 x 轴的“g”元素。因此,您选择 svg 元素,然后在 svg 中但在图表顶部添加一个“g”元素,然后添加轴,然后在轴上执行看起来像平移的操作,它包含在 g元素。
您需要将 g 元素翻译到图表的底部:
.append("g")
.attr("transform", "translate(0, height-offset)")
.(rest of your code)
Run Code Online (Sandbox Code Playgroud)
如果我没记错的话,新的 svg 元素会与以前的元素重叠,从 svg 原点开始,即左上角。由于您的 translate 函数可能对轴本身做了一些事情(我认为 call(xAxis) 返回您的轴元素,因此 translate 函数适用于轴元素),但不适用于分组元素,我认为这就是为什么“g”元素只停留在左上角。
编辑
轴的 orient 功能定义了文本相对于轴线的放置位置。更多信息可以在这里找到
我希望这是有道理的 :-)。