D3JS使日期重复

时间:2017-05-22 11:23:10

标签: d3.js

我有这个d3js代码:

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文件:

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个日期我得到重复,你可以在这里看到:

enter image description here

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

1 个答案:

答案 0 :(得分:4)

这是困扰很多D3新手的人:轴上的刻度,特别是在使用时标时,会自动生成。在您的情况下,根据您域中的日期间隔,它恰巧最终会为每天创建两个刻度。但请注意:这些刻度表示同一天的不同次(小时)(如果删除轴生成器中的tickFormat,则可以看到)。

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

&#13;
&#13;
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)"));
&#13;
pre {
  display: none;
}
&#13;
<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>
&#13;
&#13;
&#13;

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

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

&#13;
&#13;
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)"));
&#13;
pre {
  display: none;
}
&#13;
<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>
&#13;
&#13;
&#13;

返回您的代码。

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

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

以下是仅与此更改相同的代码:

&#13;
&#13;
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)"));
&#13;
pre {
  display: none;
}
&#13;
<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>
&#13;
&#13;
&#13;