【问题标题】:D3js line chart error "attribute d: Expected number, "M49,NaNZ"."D3js 折线图错误“属性 d:预期数字,”M49,NaNZ“。”
【发布时间】:2017-08-22 23:14:30
【问题描述】:

我正在尝试使用 d3js 图表获取折线图。下面是代码。这是以下错误,我得到“属性 d:预期数字,”M49,NaNZ”。”我将 x 轴解析为名称,将 y 轴解析为计数。在绘制未将数据作为数字获取的线路路径时,代码中似乎有问题。

var margin = {
    top: 30,
    right: 20,
    bottom: 30,
    left: 50
};
var width = 600 - margin.left - margin.right;
var height = 270 - margin.top - margin.bottom;



var x =  d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

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

var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(5);

var yAxis = d3.svg.axis().scale(y)
    .orient("left").ticks(5);

var valueline = d3.svg.line()
    .x(function (d) {
      return x(d.name);
    })
    .y(function (d) {
      return y(d.count);
    });

var svg = d3.select("body")
    .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Get the data
var data = [{
                "name": "Seasonal Pop",
                "code": "SEASONAL_POP",
                "children": [{
                    "name": "SEASONAL_LYQ1",
                    "code": "SEASONAL_LYQ1",
                    "count": 1200
                }, {
                    "name": "SEASONAL_LYQ2",
                    "code": "SEASONAL_LYQ2",
                    "count": 2000
                }, {
                    "name": "SEASONAL_LYQ3",
                    "code": "SEASONAL_LYQ3",
                    "count": 1060
                }, {
                    "name": "SEASONAL_LYQ4",
                    "code": "SEASONAL_LYQ4",
                    "count": 2300
                }, {
                    "name": "SEASONAL_CYQ1",
                    "code": "SEASONAL_CYQ1",
                    "count": 1300
                }, {
                    "name": "SEASONAL_CYQ2",
                    "code": "SEASONAL_CYQ2",
                    "count": 3400
                }, {
                    "name": "SEASONAL_CYQ3",
                    "code": "SEASONAL_CYQ3",
                    "count": 4500
                }, {
                    "name": "SEASONAL_CYQ4",
                    "code": "SEASONAL_CYQ4",
                    "count": 5500
                }]
            }];

data.forEach(function (d) {
    d.name = +d.date ;
    d.count = +d.count;
});

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

svg.append("path") // Add the valueline path.
.attr("d", valueline(data));

svg.append("g") // Add the X Axis
.attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g") // Add the Y Axis
.attr("class", "y axis")
    .call(yAxis);
body {
    font: 12px Arial;
}
path {
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}
.axis path, .axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body></body>

【问题讨论】:

    标签: d3.js linechart


    【解决方案1】:

    这里的主要问题是您访问数据不正确。您的数据是一个包含一个元素的数组。该元素包含一个具有name、code 和children 的对象。因此,当您将整个对象传递给 valueline() 时,它不会起作用,因为 valueline 会寻找不存在的值。

    此外,您似乎正在尝试访问 date 不存在于 d.name = +d.date 的属性

    您真正想要绘制的数据在data[0].children 中。我已经从数据中设置了 x 轴域,但是如果您想控制序数比例的顺序,通常最好使用类似 x.domain(['SEASONAL_CYQ3', 'SEASONAL_CYQ4',...]) 的内容来明确设置域

    这是一个工作示例。它需要一点样式,但我已经在轴上开始了一些文本样式以开始它。

    此外,如果您刚刚开始使用 d3 v4,则值得升级以使用它。

       var margin = {
        top: 30,
        right: 20,
        bottom: 80,
        left: 50
    };
    var width = 600 - margin.left - margin.right;
    var height = 270 - margin.top - margin.bottom;
    
    
    
    var x =  d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);
    
    var y = d3.scale.linear().range([height, 0]);
    
    var xAxis = d3.svg.axis().scale(x)
        .orient("bottom").ticks(5);
    
    var yAxis = d3.svg.axis().scale(y)
        .orient("left").ticks(5);
    
    var valueline = d3.svg.line()
        .x(function (d) {
          return x(d.name);
        })
        .y(function (d) {
          return y(d.count);
        });
    
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    
    // Get the data
    var data = [{
                    "name": "Seasonal Pop",
                    "code": "SEASONAL_POP",
                    "children": [{
                        "name": "SEASONAL_LYQ1",
                        "code": "SEASONAL_LYQ1",
                        "count": 1200
                    }, {
                        "name": "SEASONAL_LYQ2",
                        "code": "SEASONAL_LYQ2",
                        "count": 2000
                    }, {
                        "name": "SEASONAL_LYQ3",
                        "code": "SEASONAL_LYQ3",
                        "count": 1060
                    }, {
                        "name": "SEASONAL_LYQ4",
                        "code": "SEASONAL_LYQ4",
                        "count": 2300
                    }, {
                        "name": "SEASONAL_CYQ1",
                        "code": "SEASONAL_CYQ1",
                        "count": 1300
                    }, {
                        "name": "SEASONAL_CYQ2",
                        "code": "SEASONAL_CYQ2",
                        "count": 3400
                    }, {
                        "name": "SEASONAL_CYQ3",
                        "code": "SEASONAL_CYQ3",
                        "count": 4500
                    }, {
                        "name": "SEASONAL_CYQ4",
                        "code": "SEASONAL_CYQ4",
                        "count": 5500
                    }]
                }];
    
    x.domain(data[0].children.map(d => d.name))
    y.domain([0, d3.max(data[0].children, function (d) {
        return d.count;
        })]);
    
    console.log("xed", x(data[0].children[0].name))
    
    
    svg.append("path") // Add the valueline path.
    .attr("d", valueline(data[0].children))
    
    svg.append("g") // Add the X Axis
    .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .selectAll("text")
        .attr("y", 0)
        .attr("x", 9)
        .attr('font-size', '10px')
        .attr("dy", ".35em")
        .attr("transform", "rotate(90)")
        .style("text-anchor", "start");
    
    svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
        .call(yAxis)
        .selectAll('text')
        .attr('font-size', '10px')
    body {
        font: 12px Arial;
    }
    path {
        stroke: steelblue;
        stroke-width: 2;
        fill: none;
    }
    .axis path, .axis line {
        fill: none;
        stroke: grey;
        stroke-width: 1;
        shape-rendering: crispEdges;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <body></body>

    【讨论】:

    • 谢谢马克 :)
    猜你喜欢
    • 2021-11-27
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 2020-04-20
    • 2018-07-23
    • 2021-12-20
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多