放大时 D3 轴标签变得太细粒度

2023-11-26

我正在尝试创建一个轴函数,其刻度/标签是动态的,这意味着它们会自动隐藏/显示。但最重要的是,我希望在某个缩放级别停止渲染更多刻度/标签。下面是一个示例:首先,轴显示年份,然后当您放大时,刻度线会变成月份,当您进一步放大时,它会显示日期(即 12 月 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 中看到的那样继续放大时出现的问题,但在缩放时它不会动态隐藏/显示刻度/标签。


我遇到的最接近的答案是@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; }]
]);

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

UPDATE:

我最终创建了自己在 .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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

放大时 D3 轴标签变得太细粒度 的相关文章