A.Nicolas
A.Nicolas

Reputation: 71

D3 graph example

I'm trying to adapt an example of a graph by Mike Bostock with d3.js. What I'm trying to do is changing the d3.csv with d3.json. I also adapt some part of the original code, but now my graph disappear and I don't have any error, I don't know what's going wrong.

The code :

 <!DOCTYPE html>

<head>
    <title> Graphique </title>
    <script src="d3.js" charset="utf-8"></script>
    <script src="d3.min.js" charset="utf-8"></script>
</head>

<body>

<svg width="960" height="500"></svg>
<script>
    var svg = d3.select("svg"),
        margin = {
            top: 20,
            right: 20,
            bottom: 30,
            left: 60
        },
        width = +svg.attr("width") - margin.left - margin.right,
        height = +svg.attr("height") - margin.top - margin.bottom,
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var parseDate = d3.timeParse("%Y%m%d"),
        formatDate = d3.timeFormat("%Y");

    var x = d3.scaleTime()
        .domain([new Date(1999, 0, 1), new Date(2003, 0, 0)])
        .range([0, width]);

    var y = d3.scaleLinear()
        .range([height, 0]);

    var xAxis = d3.axisBottom(x);

    var yAxis = d3.axisLeft(y);

    var area = d3.area()
        .curve(d3.curveStepAfter)
        .y0(y(0))
        .y1(function(d) {
            return y(d.NbCopie);
        });

    var areaPath = g.append("path")
        .attr("clip-path", "url(#clip)")
        .attr("fill", "steelblue");

    var yGroup = g.append("g");

    var xGroup = g.append("g")
        .attr("transform", "translate(0," + height + ")");

    var zoom = d3.zoom()
        .scaleExtent([1 / 4, 8])
        .translateExtent([
            [-width, -Infinity],
            [2 * width, Infinity]
        ])
        .on("zoom", zoomed);

    var zoomRect = svg.append("rect")
        .attr("width", width)
        .attr("height", height)
        .attr("fill", "none")
        .attr("pointer-events", "all")
        .call(zoom);

    g.append("clipPath")
        .attr("id", "clip")
        .append("rect")
        .attr("width", width)
        .attr("height", height);

    d3.json("data.json", function(d) {
        d.Date_Id = parseDate(d.Date_Id);
        d.NbCopie = +d.NbCopie;
        return d;
    }, function(error, data) {
        if (error) throw error;
        var xExtent = d3.extent(data, function(d) {
            return d.Date_Id;
        });
        zoom.translateExtent([
            [x(xExtent[0]), -Infinity],
            [x(xExtent[1]), Infinity]
        ])
        y.domain([0, d3.max(data, function(d) {
            return d.NbCopie;
        })]);
        yGroup.call(yAxis).select(".domain").remove();
        areaPath.datum(data);
        zoomRect.call(zoom.transform, d3.zoomIdentity);
    });

    function zoomed() {
        var xz = d3.event.transform.rescaleX(x);
        xGroup.call(xAxis.scale(xz));
        areaPath.attr("d", area.x(function(d) {
            return xz(d.Date_Id);
            }));
        }
    </script>
</body>

</html>

And there the json file:

[
{
    "ConsoPhot_Id": "10148",
    "idLotImport": 390,
    "Date_Id": 20170201,
    "Orga_Id": "203938",
    "NbTache": 153,
    "NbCopie": 798,
    "NbCopieBW": 488,
    "NbCopieCouleur": 310,
    "MtTotal": 13.69
},
{
    "ConsoPhot_Id": "10602",
    "idLotImport": 391,
    "Date_Id": 20161201,
    "Orga_Id": "203938",
    "NbTache": 153,
    "NbCopie": 909,
    "NbCopieBW": 779,
    "NbCopieCouleur": 130,
    "MtTotal": 7.93
},
{
    "ConsoPhot_Id": "10905",
    "idLotImport": 392,
    "Date_Id": 20161101,
    "Orga_Id": "203938",
    "NbTache": 115,
    "NbCopie": 515,
    "NbCopieBW": 409,
    "NbCopieCouleur": 106,
    "MtTotal": 5.6
},
{
    "ConsoPhot_Id": "11162",
    "idLotImport": 393,
    "Date_Id": 20161001,
    "Orga_Id": "203938",
    "NbTache": 233,
    "NbCopie": 1173,
    "NbCopieBW": 725,
    "NbCopieCouleur": 448,
    "MtTotal": 19.86
},
{
    "ConsoPhot_Id": "11745",
    "idLotImport": 394,
    "Date_Id": 20170101,
    "Orga_Id": "203938",
    "NbTache": 173,
    "NbCopie": 889,
    "NbCopieBW": 782,
    "NbCopieCouleur": 107,
    "MtTotal": 7.07
},
{
    "ConsoPhot_Id": "12144",
    "idLotImport": 435,
    "Date_Id": 20170301,
    "Orga_Id": "203938",
    "NbTache": 131,
    "NbCopie": 590,
    "NbCopieBW": 454,
    "NbCopieCouleur": 136,
    "MtTotal": 6.92
}
]

Upvotes: 1

Views: 173

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102219

(This is a duplicate. Funnily enough, I tried to close this question only to find out that none of my — several — answers about this problem was accepted or has an upvote, so the system didn't allow me to close this one)

The issue here is quite simple: unlike a d3.csv function, d3.json does not accept a row function.

In your case...

d3.json("data.json", function(d) {
            d.Date_Id = parseDate(d.Date_Id);
            d.NbCopie = +d.NbCopie;
            return d;
        }, function(error, data) {

... the function just after "data.json" and before function(error, data) is the row function.

Solution: Do simply:

d3.json("data.json", function(error, data) {

And move the row function to a forEach (inside the callback):

data.forEach(function(d) {
    d.Date_Id = parseDate(d.Date_Id);
    d.NbCopie = +d.NbCopie;
})

Upvotes: 3

Related Questions