有没有一种简单的方法可以在刻度之间对齐文本标签?
这是我的时间轴,刻度上方有标签:
我想把这些标签放在这里:
我最终得到了Lars Kotthoff 的建议之一。
每次call(axis)
我也会调整文本标签。
这是简化的代码:
function renderAxis() {
axisContainer
.transition().duration(300)
.call(axis) // draw the standart d3 axis
.call(adjustTextLabels); // adjusts text labels on the axis
}
function adjustTextLabels(selection) {
selection.selectAll('.major text')
.attr('transform', 'translate(' + daysToPixels(1) / 2 + ',0)');
}
// calculate the width of the days in the timeScale
function daysToPixels(days, timeScale) {
var d1 = new Date();
timeScale || (timeScale = Global.timeScale);
return timeScale(d3.time.day.offset(d1, days)) - timeScale(d1);
}
更新:
顺便说一句,这是我结束的日历演示:http: //bl.ocks.org/oluckyman/6199145
没有简单的(即内置的)方法可以做到这一点,但您仍然可以实现它。有几个选项。最直接的一种可能是使用该tickFormat
函数来指定在数字前/后具有合适数量的空格的格式。不过,这需要为每个应用程序手动调整。
或者,您可以在绘制标签元素后选择它们,并添加一个合适的transform
属性来相应地移动它们。同样,这必须手动调整。
您的第三个选项是有两个不同的轴,一个用于刻度,一个用于标签。这个想法是提供刻度的轴没有标签,另一个没有刻度。您需要适当地设置刻度值,但至少您不必猜测正确的偏移量。
您可能要考虑使用D3FC,它可以直接替换支持此功能的 D3 轴组件。
这是一个将 D3 轴替换d3.axisBottom
为 D3FC 等效项的示例fc.axisBottom
:
const axis = fc.axisBottom(linear)
.tickCenterLabel(true);
根据tickCenterLabel
要求将轴标签居中。
这是轴的样子tickCenterLabel = false
:
在这里tickCenterLabel = true
:
全面披露- 我是 D3FC 的维护者和贡献者
您可以通过使用axis.tickSize(major[[,minor],end])
和来做到这一点.tickSubdivide()
。您的刻度设置为与主要刻度对齐,但如果您将这些刻度的高度设置为 0,并为次刻度设置一些高度,并指定每对主要刻度之间有一个次刻度,您将结束在您的刻度之间添加刻度标签。您的代码如下所示:
var myAxis = d3.svg.axis()
.ticks(15)
.tickSubdivide(1)
.tickSize(0, 6, 0);
请注意,您需要明确设置结束大小。如果您只提供两个数字,它们将被解释为major
andend
并且minor
默认为 0。
这是一个小提琴。
已经有一些很好的回复,但只是再添加一个。注意使用text-anchor
.
相同的想法:通话后,选择文本,重新定位。
.call(xAxis)
.selectAll(".tick text")
.style("text-anchor", "start")
.attr("x", axisTextAdjust)
我经常通过堆叠多个轴来做到这一点,每个轴都有一个自定义的.tickFormat()
.
如果我在日期之间放置标签,我会经常做这样的事情:
@timeDaysAxisLabels = d3.svg.axis()
.scale(@timescale)
.orient('bottom')
.ticks(d3.time.hour.utc, 12) # I want ticks at noon, easiest to just get them ever 12 hours
.tickFormat((d) =>
# only draw labels at noon, between the date boundaries
if d.getUTCHours() == 12
# draw the label!
formatter = d3.time.format.utc('%a %d %b') # "Mon 12 Apr"
return formatter(d)
else
# not noon, don't draw anything
return null)
.tickSize(0)
.tickPadding(30)
我还将创建一个完全没有标签的单独轴,并且创建一个非零.tickSize()
来实际绘制刻度,但是上面的这个块将日期标签定位在“列”的中心。
svg.append("g")
.attr("class", "axis axis-years")
.attr("transform", "translate(0," + (height + 1) + ")")
.call(xAxis)
.selectAll("text")
.attr("x", "-1.8em")
.attr("y", ".00em")
.attr("transform", function (d) {
return "rotate(-90)"});