D3JS使日期重复 [英] D3JS makes date duplicates

查看:64
本文介绍了D3JS使日期重复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个d3js代码:

I have this d3js code:

var tooltip = tooltipd3();
        var svg = d3.select("svg#svg-day"),
            margin = {
                top: 20,
                right: 30,
                bottom: 30,
                left: 25,
                padding: 15
            },
            width = 700 - margin.left - margin.right,
            height = 300 - margin.top - margin.bottom;

        // parse the periodo / time
        var parseTime = d3.timeParse("%Y-%m-%d");

        // set the ranges
        var x = d3.scaleTime().range([0, width - margin.padding]);
        var y = d3.scaleLinear().range([height, 0]);

        // define the area
        var area = d3.area()
            .x(function(d) {
                return x(d.periodo) + (margin.left + margin.padding);
            })
            .y0(height)
            .y1(function(d) {
                return y(d.guadagno);
            });

        // define the line
        var valueline = d3.line()
            .x(function(d) {
                return x(d.periodo) + (margin.left + margin.padding);
            })
            .y(function(d) {
                return y(d.guadagno);
            });

        var div = d3.select("svg#svg-day")
            .append("div") // declare the tooltip div 
            .attr("class", "tooltip") // apply the 'tooltip' class
            .style("opacity", 0);

        // get the data
        d3.csv(base_url() + 'graph/getStatementsDaily/', function(error, data) {
            if (error) throw error;
            $('.graph-loading').hide();
            // format the data
            data.forEach(function(d) {
                d.periodo = parseTime(d.periodo)
                d.guadagno = +d.guadagno;
            });

            // scale the range of the data
            x.domain(d3.extent(data, function(d) {
                return d.periodo;
            }));
            y.domain([0, d3.max(data, function(d) {
                return d.guadagno + ((d.guadagno / 100) * 10); // 10% in più sulla scala numerica
            })]);

            // add the area
            svg.append("path")
                .data([data])
                .attr("class", "area")
                .attr("d", area);

            // add the valueline path.
            svg.append("path")
                .data([data])
                .attr("class", "line")
                .attr("d", valueline);

            // Add the scatterplot
            svg.selectAll("dot")
                .data(data)
                .enter().append("circle")
                .attr("class", "dot")
                .attr("r", 3)
                .attr("cx", function(d) {
                    return x(d.periodo) + (margin.left + margin.padding);
                })
                .attr("cy", function(d) {
                    return y(d.guadagno);
                })
                .on('mouseover', function(d) {
                    var html = '<h5>' + d.guadagno + ' €</h5>';
                    tooltip.mouseover(html); // pass html content
                })
                .on('mousemove', tooltip.mousemove)
                .on('mouseout', tooltip.mouseout);

            // add the X Axis
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(" + (margin.left + margin.padding) + "," + (height) + ")")

                //HERE IS THE DATES CODE

             .call(d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")))

            // add the Y Axis
            svg.append("g")
                .attr("class", "y axis")
                .attr("transform", "translate (" + (margin.left + margin.padding) + " 0)")
                .call(d3.axisLeft(y));

        });

日期护理来自具有以下格式的CSV文件:

The dates care coming from a CSV file that has this format:

periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0

有很多日期的结果很好,但是有7个日期,我得到了重复的结果,如您在这里看到的:

The result is fine with lots of dates, but with 7 dates I get duplicates as you can see here:

这是为什么?以及我该如何解决?

Why is this?? And how do I fix it?

推荐答案

这让很多D3初学者感到困扰:会自动生成轴上的刻度,特别是在使用时间刻度时.在您的情况下,给定域中的日期间隔,它巧合地最终每天造成两个刻度.但请注意:这些刻度代表同一天的不同时间(小时)(如果删除了轴生成器中的tickFormat,则可以看到).

This is something that bothers a lot of people new to D3: the ticks in the axis, specially when using a time scale, are automatically generated. In your case, given the date interval in your domain, it coincidentally ended up creating two ticks for each day. But pay attention to this: those ticks represent different times (hours) in the same day (you can see that if you remove the tickFormat in the axis generator).

让我们看看您的代码生成了x轴:

Let's see your code generating the x axis:

var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
  d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
  .range([20, 480])
  .domain(d3.extent(data, function(d) {
    return d.periodo;
  }));

var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))(svg.append("g").attr("transform", "translate(0,50)"));

pre {
  display: none;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0</pre>

如您所见,每天有两个刻度(请记住,不同的时间).

As you can see, there are two ticks for each day (remember, for different hours).

让我们证明这是一个巧合:这是相同的代码,但是更改了2017-05-20的最后日期:

Let's show that this is a coincidence: This is the same code, but changing the last date for 2017-05-20:

var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
  d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
  .range([20, 480])
  .domain(d3.extent(data, function(d) {
    return d.periodo;
  }));

var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m"))(svg.append("g").attr("transform", "translate(0,50)"));

pre {
  display: none;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-20,0.0</pre>

返回您的代码.

解决方案非常简单:使用间隔.让我们设置每个刻度的时间间隔:

The solution is quite simple: using intervals. Let's set the interval for each tick:

d3.axisBottom(x).ticks(d3.timeDay)

这里只有相同的代码,只是更改:

Here is the same code with that change only:

var svg = d3.select("svg");
var data = d3.csvParse(d3.select("#csv").text());
var parseTime = d3.timeParse("%Y-%m-%d");
data.forEach(function(d) {
  d.periodo = parseTime(d.periodo)
});
var x = d3.scaleTime()
  .range([20, 480])
  .domain(d3.extent(data, function(d) {
    return d.periodo;
  }));

var axis = d3.axisBottom(x).tickFormat(d3.timeFormat("%d/%m")).ticks(d3.timeDay)(svg.append("g").attr("transform", "translate(0,50)"));

pre {
  display: none;
}

<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500"></svg>
<pre id="csv">periodo,guadagno
2017-05-08,0.0
2017-05-09,0.5385
2017-05-10,0.0
2017-05-11,0.0
2017-05-12,0.0
2017-05-13,0.5680
2017-05-14,0.0
2017-05-15,0.0</pre>

这篇关于D3JS使日期重复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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