41

有没有一种简单的方法可以在刻度之间对齐文本标签?

这是我的时间轴,刻度上方有标签:
在此处输入图像描述

我想把这些标签放在这里:
在此处输入图像描述

4

7 回答 7

52

我最终得到了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

在此处输入图像描述

于 2013-07-13T14:10:36.523 回答
7

没有简单的(即内置的)方法可以做到这一点,但您仍然可以实现它。有几个选项。最直接的一种可能是使用该tickFormat函数来指定在数字前/后具有合适数量的空格的格式。不过,这需要为每个应用程序手动调整。

或者,您可以在绘制标签元素后选择它们,并添加一个合适的transform属性来相应地移动它们。同样,这必须手动调整。

您的第三个选项是有两个不同的轴,一个用于刻度,一个用于标签。这个想法是提供刻度的轴没有标签,另一个没有刻度。您需要适当地设置刻度值,但至少您不必猜测正确的偏移量。

于 2013-07-09T09:31:19.003 回答
3

您可能要考虑使用D3FC,它可以直接替换支持此功能的 D3 轴组件。

这是一个将 D3 轴替换d3.axisBottom为 D3FC 等效项的示例fc.axisBottom

const axis = fc.axisBottom(linear)
  .tickCenterLabel(true);

根据tickCenterLabel要求将轴标签居中。

这是轴的样子tickCenterLabel = false

在此处输入图像描述

在这里tickCenterLabel = true

在此处输入图像描述

全面披露- 我是 D3FC 的维护者和贡献者

于 2019-05-09T15:16:49.170 回答
2

您可以通过使用axis.tickSize(major[[,minor],end])和来做到这一点.tickSubdivide()。您的刻度设置为与主要刻度对齐,但如果您将这些刻度的高度设置为 0,并为次刻度设置一些高度,并指定每对主要刻度之间有一个次刻度,您将结束在您的刻度之间添加刻度标签。您的代码如下所示:

var myAxis = d3.svg.axis()
    .ticks(15)
    .tickSubdivide(1)
    .tickSize(0, 6, 0);

请注意,您需要明确设置结束大小。如果您只提供两个数字,它们将被解释为majorandend并且minor默认为 0。

这是一个小提琴。

于 2013-07-09T15:02:52.750 回答
1

已经有一些很好的回复,但只是再添加一个。注意使用text-anchor.

相同的想法:通话后,选择文本,重新定位。

.call(xAxis)                
.selectAll(".tick text")
.style("text-anchor", "start")
.attr("x", axisTextAdjust)
于 2014-10-04T02:15:25.980 回答
0

我经常通过堆叠多个轴来做到这一点,每个轴都有一个自定义的.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()来实际绘制刻度,但是上面的这个块将日期标签定位在“列”的中心。

于 2014-03-17T23:37:43.607 回答
0
        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)"});
于 2017-02-13T10:28:58.103 回答