放大时,D3轴标签会变得太细

时间:2013-11-15 21:25:21

标签: javascript d3.js

我正在尝试创建一个轴功能,刻度/标签是动态的,这意味着它们会自动隐藏/显示。但最重要的是,我想在一些缩放级别停止渲染更多的刻度/标签。这是一个例子:首先,轴显示年份,然后当您放大时,刻度变为月份,当您进一步放大时,它会显示天数(I.E.,Dec 28)。除非我想限制d3,否则当缩放时间超过月份时,它不再渲染任何滴答,因为月份是我想要的最小单位。

我有几个例子,如果合并将是我想要的,但我无法弄清楚如何做到这一点。

另外:我添加了.tickFormat,因为我想显示每个刻度都有缩写的月份格式。

示例1: http://jsfiddle.net/GGYKL/

var xAxis = d3.svg.axis().scale(x)
    .tickFormat(d3.time.format('%b'))
    .orient("bottom");

此示例显示了在放大时刻度/标签如何正确显示和消失,但是当您继续放大时,它会分割月份并开始重复月份刻度/标签,我不想限制用户进行缩放英寸

示例2: http://jsfiddle.net/4kz7t/

var xAxis = d3.svg.axis().scale(x)
    .ticks(d3.time.months)
    .tickFormat(d3.time.format('%b'))
    .orient("bottom"),

此示例解决了当您继续放大时的问题,就像我们在示例1中看到的那样,但它在缩放时不会动态隐藏/显示刻度/标签。

2 个答案:

答案 0 :(得分:5)

我遇到的最接近的答案是@Lars Kotthoff建议的多尺度时间格式。我将自定义时间格式器编辑为:

http://jsfiddle.net/BdGv5/1/

var customTimeFormat = timeFormat([
    [d3.time.format("%Y"), function() { return true; }],
    [d3.time.format("%b"), function(d) { return d.getMonth(); }],
    [function(){return "";}, function(d) { return d.getDate() != 1; }]
]);

因此,在放大时仍会生成刻度本身,但标签将为空字符串。

更新:

我最终创建了自己在.ticks()中使用的函数。 Ticks将比例范围传递给您的函数t0和t1。我将图表宽度除以标签大小(和填充)以找到没有重叠的最大标签数量,如果发生重叠,则使用下划线删除每个其他标记。

http://jsfiddle.net/BdGv5/3/

function customTickFunction(t0, t1, dt)
    {

        var labelSize = 30; // largest label is 23 pixels ("May")
        var maxTotalLabels = Math.floor(width / labelSize);

        function step(date, offset)
        {
            date.setMonth(date.getMonth() + offset);
        }

        var time = d3.time.month.ceil(t0), times = [];

        while (time < t1) times.push(new Date(+time)), step(time, 1);

        if(times.length > maxTotalLabels)
            times = _.filter(times, function(d){
                return (d.getMonth() + 1) % 2;
            });

        return times;
    }

    var domain = xScale.domain();
    var xAxisMonthsFunction = d3.svg.axis().scale(xScale)
        .ticks(customTickFunction)
        .tickFormat(d3.time.format("%b"))
        .orient("bottom");

更新2:

http://jsfiddle.net/BdGv5/5/

让刻度调整超过1级,现在有4级(2,3,4,6)。

function customTickFunction(t0, t1, dt)
{

    var labelSize = 30; // largest label is 23 pixels ("May")
    var maxTotalLabels = Math.floor(width / labelSize);

    function step(date, offset)
    {
        date.setMonth(date.getMonth() + offset);
    }

    var time = d3.time.month.ceil(t0), times = [], monthFactors = [2,3,4,6];

    while (time < t1) times.push(new Date(+time)), step(time, 1);

    var i;
    for(i=1 ; times.length > maxTotalLabels ; i++)
        times = _.filter(times, function(d){
            return (d.getMonth()) % monthFactors[i] == 0;
        });

    return times;
}

答案 1 :(得分:-1)

删除.tickFormat,因为D3会自动动态更新刻度线。 您也可以限制刻度。

例如:

d3.svg.axis().scale(x)
.ticks(6) /*Number of Ticks you desire to display in x-axis scale*/
.orient("bottom")