d3 js时间轴略微偏离/倾斜/移动

时间:2017-10-05 11:45:47

标签: javascript datetime d3.js

我有一个x轴基于d3.time.scale的图表(我正在使用v3)。刻度线略微向左移动,就像移动了标尺一样。

enter image description here (黄色标尺不是图纸的一部分)

以下是主要代码段:

<script type="text/javascript">

        function daydiff(sooner, later) {
            return Math.round((later-sooner)/(1000*60*60*24));
        }

        var margin = {top: 5, right: 20, bottom: 20, left: 20};

        d3.json("pagecount-total.json",function(error,rawdata) {

            // prepare Data
            var data = [];
            var v;
            var now = new Date();
            var totalcount = 0;
            var recentcount = 0;
            var count = 0;

            for(var key in rawdata) {
                var isostring = key.substring(0, 4) + '-' + key.substring(4, 6) + '-' + key.substring(6, 8);
                v = rawdata[key];
                count = v['count'];
                d = new Date(isostring);
                totalcount += count;

                if (daydiff(d,now)<90) recentcount+=count;

                data.push({date: d, count: v['count'], usercount: v['usercount']});
            }
            console.table(data);
            console.log('counts',totalcount,recentcount);

            d3.select('#totalcount').text(totalcount);
            d3.select('#recentcount').text(recentcount);


            // set up chart object
            var chart = d3.select("#chart");
            var width = parseInt(chart.style('width')) - margin.left - margin.right;
            var height = parseInt(chart.style('height')) - margin.top - margin.bottom;

            // scales and ranges
            var x = d3.time.scale().range([0,width]);
            var y = d3.scale.linear().range([height,0]);
            //var y2 = d3.scale.linear().range([height,0]);

            // later on we set the bar width to be the size of one day. Hence the domain needs to be half
            // a day longer on both ends to match the size of a bar.

            var dateextend = d3.extent(data, function(d) { return d.date });

            var newstart = new Date();
            newstart.setTime( dateextend[0].getTime() - (0 * 86400000) );

            var newend = new Date();
            newend.setTime( dateextend[1].getTime() + (1 * 86400000) );

            console.log('newstart',newstart);

            // the domains
            x.domain([newstart,newend]);
            //x.domain(dateextend);
            y.domain([0, d3.max(data, function(d) {return d.count})]);

            var numdays = daydiff(dateextend[0],dateextend[1])+1;
            console.log('numdays',numdays);

            xAxis = d3.svg.axis().scale(x)
                    .orient("bottom")
                    //.ticks(Math.max(width/70, 1))
                    .ticks(5)
                    .tickFormat(tickFormatDE);

            yAxis = d3.svg.axis().scale(y)
                    .orient("left")
                    .ticks((Math.max(height/50, 1)))


            // set up basic group for bars  and axis

            var g = chart.append("g")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            g.selectAll('.bar')
                    .data(data)
                    .enter()
                    .append('rect')
                    .attr('class','bar');

            g.selectAll('.bar2')
                    .data(data)
                    .enter()
                    .append('rect')
                    .attr('class','bar2');

            g.append("g").attr("class", "axis xaxis");
            g.append("g").attr("class", "axis yaxis");


            // Draw whenever a resize event occours
            d3.select(window).on('resize', draw);

            // And do a first draw
            draw();

            function draw() {

                var width = parseInt(chart.style('width')) - margin.left - margin.right;
                var height = parseInt(chart.style('height')) - margin.top - margin.bottom;

                var barwidth = width/numdays;
                if (barwidth == Infinity) barwidth=width;
                console.log('width',width,'barwidth',barwidth);

                // Update the range of the scale with new width/height
                x.range([0, width]);
                y.range([height, 0]);

                g.selectAll('.bar')
                        .attr('x',function(d) {return x(d.date)-0*barwidth})
                        .attr('width',barwidth  )
                        .attr('y',function(d){return y(d.count)})
                        .attr('height',function(d){return height-y(d.count)});

                g.selectAll('.bar2')
                        .attr('x',function(d) {return x(d.date)-0.0*barwidth})
                        .attr('width',barwidth  )
                        .attr('y',function(d){return y(d.usercount)})
                        .attr('height',function(d){return height-y(d.usercount)});
                // Update the axis and text with the new scale

                chart.select('.xaxis')
                        .attr("transform", "translate(0," + height + ")")
                        .call(xAxis);

                chart.select('.yaxis')
                        .attr("transform", "translate("+(-0*barwidth)+",0)")
                        .call(yAxis);
            }
        });



    </script>

所有细节都在这里:

http://bl.ocks.org/jhb/df33bbba4cec6e6eec30df0e4a8a3cb4

造成这种情况的原因是什么,以及如何修复?

1 个答案:

答案 0 :(得分:0)

如果我正确理解您的问题,我相信您可以实现所需的输出,将日期转换为UTC。

在这里,我以变量名zoneDate

创建新日期
zoneDate = new Date(isostring);

然后将其转换为UTC:

d = new Date(zoneDate.getUTCFullYear(), zoneDate.getUTCMonth(), zoneDate.getUTCDate(),
    zoneDate.getUTCHours(), zoneDate.getUTCMinutes(), zoneDate.getUTCSeconds());

以下是更新的bl.ocks:http://bl.ocks.org/anonymous/a09478a0949c9857c8e7c47e887980cf/512643a99f2ace85ee62415a112359119b854c45