D3 JS-时间轴上的刻度间隔被月份边界弄乱了 [英] D3 JS - tick spacing on time axis gets messed up by month boundary

查看:62
本文介绍了D3 JS-时间轴上的刻度间隔被月份边界弄乱了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用d3.js,我发现在x轴上使用时间刻度时,主要刻度线在新的月份边界上被弄乱了.它似乎在新的月份上创建了一个新的刻度线,即使该刻度线与前一个刻度线过于接近也是如此.这样不仅会弄乱沿轴的均匀间距,还会使刻度线标签重叠并且看上去很丑.

Using d3.js, I found that when using a time scale for the x-axis, the major tick marks get messed up on a new month boundary. It appears to create a new tick mark on the new month even if that results in a tick too close to the previous tick. Not only does this mess up the even spacing along the axis, it also makes the tick labels overlap and look pretty ugly.

请参阅问题底部的演示以显示我的意思(向右滚动以查看问题区域).

See the demo at the bottom of the question to show what I mean (scroll to the right to see the problem area).

我是否需要自定义多尺度时间格式来处理这种情况?还是我在这里缺少某些选择? (这被认为是错误吗?)

Do I need a custom multi-scale time format to handle this case? Or is there some option I'm missing here? (And is this considered a bug?)

我尝试了自定义的多次格式,并且确实可以将多余的标签从六月"更改为其他标签,但是仍然显示在不应该使用的地方.问题在于根本不应该有一个勾号.它应该在刻度线之间保持相同的2天间隔,而实际上并非如此.我倾向于将其称为错误.

I tried out the custom multi-time format, and it does work to change the extra label from just "June" to match the others, but it still shows up where it shouldn't. The problem is that there shouldn't be a tick mark there at all; it should keep the same 2-day spacing between ticks that was always there, and it's not. I'm leaning toward calling this a bug.

这是一个发生这种情况的演示:

Here's a demo where this happens:

<!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      body {
        font: 12px Arial;
      }
      path {
        stroke: steelblue;
        stroke-width: 2;
        fill: none;
      }
      .axis path, .axis line {
        fill: none;
        stroke: grey;
        stroke-width: 1;
        shape-rendering: crispEdges;
      }
    </style>
    <body>
      <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.min.js"></script>
      <script type="text/javascript">
        var data = {
            "values" : [40, 80, 94, 95, 10, 81, 89, 70, 43, 56, 86, 72, 39, 38, 84, 5, 0, 38, 68, 16, 23, 6, 45, 7, 79, 59, 51, 33, 44, 18],
            "labels" : ["2013,05,07", "2013,05,08", "2013,05,09", "2013,05,10", "2013,05,11", "2013,05,12", "2013,05,13", "2013,05,14", "2013,05,15", "2013,05,16", "2013,05,17", "2013,05,18", "2013,05,19", "2013,05,20", "2013,05,21", "2013,05,22", "2013,05,23", "2013,05,24", "2013,05,25", "2013,05,26", "2013,05,27", "2013,05,28", "2013,05,29", "2013,05,30", "2013,05,31", "2013,06,01", "2013,06,02", "2013,06,03", "2013,06,04", "2013,06,05"]
        };
    
        var margin = { top : 15, right : 15, bottom : 40, left : 50 },
            width = 750 - margin.left - margin.right,
            height = 250 - margin.top - margin.bottom;
    
        // Parse dates
        data.parsedDates = [];
        data.labels.forEach(function(d) {
            var parsed = d3.time.format("%Y,%m,%d").parse(d);
            data.parsedDates.push(parsed);
        });
    
        var x = d3.time.scale()
            .range([0, width])
            .domain(d3.extent(data.parsedDates));
    
        var y = d3.scale.linear()
            .range([height, 0])
            .domain(d3.extent(data.values));
    
        var xAxis = d3.svg.axis().scale(x)
            .ticks(8).tickSize(5, 0, 0);
    
        var line = d3.svg.line()
            .x(function(d,i) {
                return x(data.parsedDates[i]); })
            .y(function(d,i) {
                return y(d); });
    
        // Create chart
        var svg = d3.select("body")
            .append("svg")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
            .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
        // Graph points
        svg.append("path")
          .datum(data)
          .attr("class", "line")
          .attr("d", function(d) { return line(d.values) });
    
        // Add the X Axis
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
      </script>
    </body>

推荐答案

似乎对于当前D3版本(答案日期为5.12.0),手动日期选择是唯一可能的解决方案(PS解决方案提到

Seems that manual dates selection is the only possible solution for current D3 version, 5.12.0 as for answer date (P.S. solution mentioned here):

const xValues = data.filter((d, i) => i % interval === 0).map(d => d.date);

const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat('%b %d'))
// .ticks(d3.timeDay.every(interval))
.tickValues(xValues);

这篇关于D3 JS-时间轴上的刻度间隔被月份边界弄乱了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆