错误:<rect>属性y:预期长度,“NaN”

时间:2017-10-04 06:23:24

标签: javascript d3.js

我正在尝试按照此示例here获取D3堆叠图表。我在本地进行了测试,效果很好。 我已经调整了代码以匹配我的csv数据集,但不幸的是我遇到了y和height属性计算的问题:

  • 错误:属性y:预期长度,“NaN”。
  • 错误:属性高度:预期长度,“NaN”。

这是我改编的源代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Enterprise Elements Analysis - In/Out of Scope</title>
    <script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
    <style type="text/css">
        svg {
            font: 10px sans-serif;
            shape-rendering: crispEdges;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: #000;
        }

        path.domain {
            stroke: none;
        }

        .y .tick line {
            stroke: #ddd;
        }
  </style>
</head>
<body>
<script type="text/javascript">
// Our D3 code will go here
var ratData = [];

d3.csv("./etcounts.csv", function(d) {
    return {
        type: d.type,
        in_scope: +d.in_scope,
        out_scope: +d.out_scope
    };
}, function(error, rows) {
    data = rows;
    console.log(data);
    createVisualization();
});

function createVisualization() {
    // Setup svg using with margins
    var margin = {bottom: 75, left: 15, right: 85};
    var w = 200 - margin.left - margin.right;
    var h = 175 - margin.bottom;

    // get length of Array
    var arrayLength = data.length; // length of dataset
    var x_axisLength = 100; // length of x-axis in our layout
    var y_axisLength = 100; // length of y-axis in our layout

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

    // set up the properties for stack
    var stack = d3.stack()
        .keys(["In Scope", "Out Scope"])
        .order(d3.stackOrderDescending)
        .offset(d3.stackOffsetNone);

    // transpose your data using stack
    var series = stack(data);

    // view the stack
    console.log(series);

    // setup the Y scale
    var yScale = d3.scaleLinear()
        .domain([0, d3.max(series, function(d) {
            return d3.max(d, function(d) {
                return d[1];
            }); 
        })])
        .range([h, 0]);

    // Set some colors into an array
    var colors = ["#dfd6d6", "#d85f41"]; // choose colors

    // Create groups for each series, rect elements for each segment 
    var groups = svg.selectAll("g.type")
        .data(series)
        .enter().append("g")
        .attr("class", "type")
        .style("fill", function(d, i) {
            return colors[i]; // color the rectangles
        });

    // Create the rectangles
    var rect = groups.selectAll("rect")
        .data(function(d) {
            return d;
        })
        .enter()
        .append("rect")
        .attr("x", function(d,i) {
            return i * (x_axisLength/arrayLength) + 30; // Set x coordinate of rectangle to index of data value (i) *25
        })
        .attr("y", function(d) {
            return yScale(d[1]); // set base of rectangle
        })
        .attr("height", function(d) {
            return yScale(d[0]) - yScale(d[1]); // set height of rectangle
        })
        .attr("width", (x_axisLength/arrayLength) - 1) // set width of rectangle
        .on("mouseover", function() {
            tooltip.style("display", null); // hide tooltip
        })
        .on("mousemove", function(d) {
            var xPosition = d3.mouse(this)[0] - 15;
            var yPosition = d3.mouse(this)[1] - 25;
            tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
            tooltip.select("text").text(d.data.city + ": " + (d[1] - d[0])); // populate tooltip
        })
        .on("mouseout", function() {
            tooltip.style("display", "none");
        });

    // Draw legend
    var legend = svg.selectAll(".legend")
        .data(colors)
        .enter().append("g")
        .attr("class", "legend")
        .attr("transform", function(d, i) { return "translate(" + i * 50 + ", 110)"; });

    legend.append("rect")
        .attr("x", w - 70)
        .attr("width", 18)
        .attr("height", 18)
        .style("fill", function(d, i) {return colors.slice().reverse()[i];});

    legend.append("text")
        .attr("x", w - 49)
        .attr("y", 9)
        .attr("dy", ".35em")
        .style("text-anchor", "start")
        .text(function(d, i) { 
        switch (i) {
            case 0: return "In";
            case 1: return "Out";
        }
    });

    // Prep the tooltip bits, initial display is hidden
    var tooltip = svg.append("g")
        .attr("class", "tooltip")
        .style("display", "none");

    tooltip.append("text")
        .attr("x", 15)
        .attr("dy", "1.2em")
        .style("text-anchor", "middle")
        .attr("font-size", "12px");

    // Create y-axis
    svg.append("line")
        .attr("x1", 30)
        .attr("y1", 0)
        .attr("x2", 30)
        .attr("y2", 100)
        .attr("stroke-width", 2)
        .attr("stroke", "black");

    // y-axis label
    svg.append("text")
        .attr("class", "y label")
        .attr("text-anchor", "middle")
        .text("Elements")
        .attr("transform", "translate(20, 50) rotate(-90)")
        .attr("font-size", "14px")
        .attr("font-family", "'Open Sans', sans-serif");

    // Create x-axis
    svg.append("line")
        .attr("x1", 30)
        .attr("y1", 100)
        .attr("x2", 130)
        .attr("y2", 100)
        .attr("stroke-width", 2)
        .attr("stroke", "black");
}

</script>
</body>
</html>

我的数据集(etcounts.csv)在这里:

type,in_scope,out_scope
ERKRS,1,1
KKBER,6,5
KOKRS,1,31
BUKRS,78,143
VKORG,23,13
BWKEY,51,6
EKORG,5,6
WERKS,51,65
LGORT,9,180
SPART,9,3
VTWEG,2,0
PERSA,47,73

不幸的是我的D3 / JS技能还不尽如人意,但我很感激任何帮助。谢谢 - 约翰

1 个答案:

答案 0 :(得分:1)

而不是

var stack = d3.stack()
    .keys(["In Scope", "Out Scope"]) <-- there is no key as such
    .order(d3.stackOrderDescending)
    .offset(d3.stackOffsetNone);
应该是:

var stack = d3.stack()
    .keys(["in_scope", "out_scope"])
    .order(d3.stackOrderDescending)
    .offset(d3.stackOffsetNone);

原因:您的CSV "In Scope", "Out Scope"中没有密钥 应该是"in_scope", "out_scope"

修改

对于工具提示:

tooltip.select("text").text(d.data.city + ": " + (d[1] - d[0]));

应该是

tooltip.select("text").text(d.data.type + ": " + (d[1] - d[0]));

原因:您的CSV中没有data.city

工作代码here