如何在我的图表中显示数据?

时间:2017-01-04 20:37:07

标签: javascript d3.js

我正在尝试将我的数据显示在我的图表中,但是在我将Year和Miles列从字符串转换为整数后,我收到一条错误,指出我的数据是“NaN”。

我猜这是我的x_scale& y_scale ...?

<!DOCTYPE html>
<html lang="en">

<head>
    <description>
        <!--charts - avg vehicle trip per mile, source: http://nhts.ornl.gov/2009/pub/stt.pdf-->
    </description>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

    <link rel="stylesheet" href="/bootstrap-3.3.7-dist/css/bootstrap.min.css">

    <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>

</head>

<body>
    <script type="text/javascript">
        // global variables
        var dataset;

        d3.csv("avgVehicleTripLengthMiles.csv", function (error, data) {
            if (error) {
                console.log(error);
            } else {
                console.log(data);
            }

            // once loaded, data is copied to dataset because js is asynchronous
            dataset = data;

            createScatterplot();

        });

        /*
                function typeConv() {
                    // type conversion from string to integer
                    var typeConv = dataset.forEach(function (d) {
                        d["Year"] = +d["Year"];
                        d["Miles"] = +d["Miles"];
                        return d;
                    });
                }
        */
        function createScatterplot() {

            // TEST
            var typeConv = dataset.forEach(function (d) {
                d["Year"] = +d["Year"];
                d["Miles"] = +d["Miles"];
                return d;
            });

            var title = d3.select("body")
                .append("h4")
                .text("Avg. Vehicle Trip Length per Mile");

            // dimensions of canvas
            var padding = 30;

            var margin = {
                    top: 20,
                    right: 40,
                    bottom: 20,
                    left: 40
                },
                w = 800 - margin.left - margin.right,
                h = 400 - margin.top - margin.bottom;

            // create svg canvas
            var svg_canvas = d3.select("body")
                .append("svg")
                .attr("width", w + margin.left + margin.right)
                .attr("height", h + margin.top + margin.bottom);

            // create scale for axis
            var x_scale = d3.scaleLinear().domain([1969, 2009]).range([padding, w - padding * 2]);

            var y_scale =
                d3.scaleLinear().domain([0, 20]).range([h - padding, padding]);

            // r_scale created specifically for circles' radius to be mapped unto axes
            var r_scale =
                d3.scaleLinear().domain([0, d3.max(dataset, function (d) {
                    return d[1];
                })]).range([0, 20]);

            // define axis & ticks // .ticks(5) to x_axis and .ticks(1) to y_axis
            var x_axis = d3.axisBottom().scale(x_scale);

            var y_axis = d3.axisLeft().scale(y_scale);

            // create group, "g" element, to create x_axis and y_axis
            var x_group = svg_canvas.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0," + (h - padding) + ")")
                .call(x_axis);

            var y_group = svg_canvas.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(" + padding + ",0)")
                .call(y_axis);

            // create circles
            svg_canvas.selectAll("circle")
                .data(dataset)
                .enter()
                .append("circle")
                .attr("cx", function (d) {
                    return x_scale(d[0]);
                })
                .attr("cy", function (d) {
                    console.log(d); // TEST
                    return y_scale(d[1]);
                })
                .attr("cr", function (d) {
                    return r_scale(d[1]);
                });
        }
    </script>
</body>

</html>

2 个答案:

答案 0 :(得分:1)

编辑(新答案):

有几个问题,我会尝试逐一介绍它们。

为了测试,我不得不编制自己的数据。我的测试CSV文件看起来像这样(如果你的文件不同,你的最终答案可能会略有改变)

Year,Miles
2006,5.0
2007,7.2
2008,19.3
  1. 正如@altocumulus在上面的评论中指出的那样,您的.attr()调用引用了不存在的索引,这可能是问题的一部分。

  2. 圈子的半径属性为r,而不是cr

  3. 我通过不调用r的函数来简化代码,而是执行静态值。你可能想要进一步发挥这个作用。

  4. 代码的重大变化部分是

    svg_canvas.selectAll("circle")
                .data(dataset)
                .enter()
                .append("circle")
                .attr("cx", function (d) {
                    return x_scale(d["Year"]);
                })
                .attr("cy", function (d) {
                    return y_scale(d["Miles"]);
                })
                .attr("r", function (d) {
                    return 5;
                    //return r_scale(d[1]);
                });
    

    例如,您仍然遇到x轴与数字相似而不是日期的问题,使2006看起来像2,006。我在这里没有解决这个问题。

    最后,我觉得你通过D3代码尝试处理边距和填充而无缘无故地使代码变得复杂,当这些最终意味着Javascript上下文中的类似内容时。我建议通过CSS完成大部分边距/填充,这将简化您的代码。另一个不必要的并发症的例子在下面的答案中。

    FIDDLE

    旧(不完整,不正确)答案:

    Array.forEach()的返回值为undefined,因此无法分配。

            dataset.forEach(function (d) {
                //d["Year"] = +d["Year"];
                d["Miles"] = +d["Miles"];
                // NOT NEEDED: return d;
            });
    

    如果您需要将转换后的数组分开,请使用Array.map()

答案 1 :(得分:0)

// global variables
    var dataset;

    d3.csv("avgVehicleTripLengthMiles.csv", function (error, data) {
        if (error) {
            console.log(error);
        } else {
            console.log(data);
        }

        // once loaded, data is copied to dataset because js is asynchronous
        dataset = data;

        createScatterplot();

    });

    function createScatterplot() {

        // TEST
        var typeConv = dataset.forEach(function (d) {
            // d["Year"] = +d["Year"];
            d["Miles"] = +d["Miles"];
            // return d;
        });

        var title = d3.select("body")
            .append("h4")
            .text("Avg. Vehicle Trip Length per Mile");

        // dimensions of canvas
        var padding = 30;

        var margin = {
                top: 20,
                right: 40,
                bottom: 20,
                left: 40
            },
            w = 800 - margin.left - margin.right,
            h = 400 - margin.top - margin.bottom;

        // create svg canvas
        var svg_canvas = d3.select("body")
            .append("svg")
            .attr("width", w + margin.left + margin.right)
            .attr("height", h + margin.top + margin.bottom);

        // create scale for axis
        var x_scale = d3.scaleLinear().domain([1965, 2009]).range([padding, w - padding * 2]);

        var y_scale =
            d3.scaleLinear().domain([0, 20]).range([h - padding, padding]);

        // r_scale created specifically for circles' radius to be mapped unto axes
        var r_scale =
            d3.scaleLinear().domain([0, d3.max(dataset, function (d) {
                return d[1];
            })]).range([0, 20]);

        // define axis & ticks // .ticks(5) to x_axis and .ticks(1) to y_axis
        var x_axis = d3.axisBottom().scale(x_scale);

        var y_axis = d3.axisLeft().scale(y_scale);

        // create group, "g" element, to create x_axis and y_axis
        var x_group = svg_canvas.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(0," + (h - padding) + ")")
            .call(x_axis);

        var y_group = svg_canvas.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(" + padding + ",0)")
            .call(y_axis);

        // create & color circles
        svg_canvas.selectAll("circle")
            .data(dataset)
            .enter()
            .append("circle")
            .attr("cx", function (d) {
                return x_scale(d["Year"]);
            })
            .attr("cy", function (d) {
                return y_scale(d["Miles"]);
            })
            .attr("r", function (d) {
                return 5;
            })
            .style("fill", function (d) {
                if (d["Trip Purpose"] === "All Purposes") {
                    return "pink";
                } else if (d["Trip Purpose"] === "To or From Work") {
                    return "red";
                } else if (d["Trip Purpose"] === "Shopping") {
                    return "blue";
                } else if (d["Trip Purpose"] === "Other Family/Personal Errands") {
                    return "green";
                } else if (d["Trip Purpose"] === "Social and Recreational") {
                    return "gray";
                };
            });

        // create text label for x-axis
        svg_canvas.append("text")
            .attr("x", w / 2)
            .attr("y", h + margin.top + 20)
            .style("text-anchor", "middle")
            .text("Year");

        // create text label for y-axis
        svg_canvas.append("text")
            .attr("transform", "rotate(-90)")
            .attr("x", (0 - margin.left / 2))
            .attr("y", (h/2))
            .style("text-anchor", "middle")
            .text("Miles");