错误:<path>属性d:预期数量 - 尝试使用D3

时间:2017-03-16 17:02:16

标签: javascript d3.js

我正在尝试使用D3构建多线图。我从HTML表中提取数据,然后尝试构建图表。我不断收到错误,但似乎无法弄清楚如何将其转换为数字并且不再出现NaN错误。

这是我的代码:

        function plantVolumes() {

        //draw plant volumes table
        plantView = "<h4>Plant Volumes</h4><table id='dataTable' class='plantVolumeTable'><thead id='plantTableHead'><tr><th>Month Start Date</th><th>Volume Type</th><th>Volume</th><th>Unit</th><th class='hidden'>Volume Src</th></tr></thead><tbody>";
        for(i=0;i<plantData1.length;i++) {

            if(plantData1["MergeKey_lvl00"][i] == mergeKey) {
                //get volume type
                for(var j=0;j<plantData2.length;j++) {
                    if(plantData2["VolumeTypeId"][j] == plantData1["VolumeTypeId"][i]) {
                        var volumeType = plantData2["VolumeType"][j];
                        var volumeUnit = plantData2["Unit"][j];
                    }
                }
                //draw rows 
                plantView += "<tr><td>" + plantData1["MonthStartDate"][i] + "</td><td>" + volumeType + "</td><td>" + plantData1["Volume"][i] + "</td><td>" + volumeUnit + "</td><td class='hidden'>" + plantData1["Volume_src"][i] + "</td></tr>";  
            }
        }
        plantView += "</tbody></table>";

        $("#plantVolumesTableDiv").html(plantView);
        document.getElementById("plantViews").style.display = "block";

        initializeDataTable();
        //end draw plant volumes table

        //DRAW LINE CHART                   
        //set dimensions of canvas
        var margin = {top:30, right:20, bottom:30, left:50},
            width = 600 - margin.left - margin.right,
            height = 270 - margin.top - margin.bottom;

        //parse the date
        var parseDate = d3.time.format("%Y %b %d").parse;

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

        //define the axes
        var xAxis = d3.svg.axis().scale(x)
            .orient("bottom").ticks(12);
        var yAxis = d3.svg.axis().scale(y)
            .orient("left").ticks(5);

        //define the line
        var volumeLine = d3.svg.line()
            //.x( (d) => x(d.MonthStartDate) )
            .x(function(d) { return x(d.MonthStartDate); })
            .y(function(d) { return y(d.Volume); });

        //add svg to canvas
        var svg = d3.select("#volumeChart")
            //.data(data)
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
            .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        //get volume table data
        var data = $(".plantVolumeTable tbody").children().map(function() {
            var children = $(this).children();

            return {
                MonthStartDate: children.eq(0).text(),
                VolumeType: children.eq(1).text(),
                Volume: children.eq(2).text()
            };
        }).get();

        data.forEach(function(d) {
            d.MonthStartDate = d.MonthStartDate;
            //d.VolumeType = d.VolumeType;
            d.Volume = +d.Volume;
        });

        //console.log(data);

        //scale the range of data
        x.domain(d3.extent(data, function(d) { return d.MonthStartDate; }));
        y.domain([0, d3.max(data, function(d) { return d.Volume; })]);

        //nest data
        var dataNest = d3.nest()
            .key(function(d) { return d.VolumeType; })
            .entries(data);
        console.log(dataNest);
        //loop through volume types / key
        dataNest.forEach(function(d) {

            svg.append("path")
                .attr("class", "line")
                .attr("d", volumeLine(d.values));
        });

        //add the x axis
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
        //add the y axis
        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);
    }

对我做错了什么或错过什么的想法?

1 个答案:

答案 0 :(得分:1)

我稍微修改了你的代码。您需要在两个位置,行和域部分中解析日期。此外,您需要修复parseDate,使其成为表格的正确格式。

这是我修改后的代码:

        function plantVolumes() {

        //draw plant volumes table
        plantView = "<h4>Plant Volumes</h4><table id='dataTable' class='plantVolumeTable'><thead id='plantTableHead'><tr><th>Month Start Date</th><th>Volume Type</th><th>Volume</th><th>Unit</th><th class='hidden'>Volume Src</th></tr></thead><tbody>";
        for(i=0;i<plantData1.length;i++) {

            if(plantData1["MergeKey_lvl00"][i] == mergeKey) {
                //get volume type
                for(var j=0;j<plantData2.length;j++) {
                    if(plantData2["VolumeTypeId"][j] == plantData1["VolumeTypeId"][i]) {
                        var volumeType = plantData2["VolumeType"][j];
                        var volumeUnit = plantData2["Unit"][j];
                    }
                }
                //draw rows 
                plantView += "<tr><td>" + plantData1["MonthStartDate"][i] + "</td><td>" + volumeType + "</td><td>" + plantData1["Volume"][i] + "</td><td>" + volumeUnit + "</td><td class='hidden'>" + plantData1["Volume_src"][i] + "</td></tr>";  
            }
        }
        plantView += "</tbody></table>";

        $("#plantVolumesTableDiv").html(plantView);
        document.getElementById("plantViews").style.display = "block";

        initializeDataTable();
        //end draw plant volumes table

        //DRAW LINE CHART                   
        //set dimensions of canvas
        var margin = {top:30, right:20, bottom:30, left:50},
            width = 600 - margin.left - margin.right,
            height = 270 - margin.top - margin.bottom;

        //parse the date
        var parseDate = d3.time.format("%Y-%m-%d").parse;

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

        //define the axes
        var xAxis = d3.svg.axis().scale(x)
            .orient("bottom").ticks(12);
        var yAxis = d3.svg.axis().scale(y)
            .orient("left").ticks(5);

        //define the line
        var volumeLine = d3.svg.line()
            .x(function(d) { return x(parseDate(d.MonthStartDate)); })
            .y(function(d) { return y(d.Volume); });

        //add svg to canvas
        var svg = d3.select("#volumeChart")
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
            .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        //get volume table data
        var data = $(".plantVolumeTable tbody").children().map(function() {
            var children = $(this).children();

            return {
                MonthStartDate: children.eq(0).text(),
                Volume: children.eq(2).text(),
                VolumeType: children.eq(1).text()
            };
        }).get();

        data.forEach(function(d) {
            d.MonthStartDate = d.MonthStartDate;
            d.VolumeType = d.VolumeType;
            d.Volume = +d.Volume;
        });

        //scale the domain of data
        x.domain(d3.extent(data, function(d) { return parseDate(d.MonthStartDate); }));
        y.domain([0, d3.max(data, function(d) { return d.Volume; })]);

        //nest data
        var dataNest = d3.nest()
            .key(function(d) { return d.VolumeType; })
            .entries(data);
        //loop through volume types / key
        dataNest.forEach(function(d) {

            svg.append("path")
                .attr("class", "line " + function(d) {return d.VolumeType;})
                .attr("d", volumeLine(d.values));
        });

        //add the x axis
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
        //add the y axis
        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis);   

    }