d3 двухуровневая вложенная привязка данных - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь сгруппировать гистограмму.

Основным значением для представления в виде столбца является «значение», то есть число, которое я случайно создал. Значение представления делится на категории - пол / возраст / образование, и каждая категория делится на подкатегории.

Вот так выглядят все данные в csv:

cate,cate_val,value
gender,male,100
gender,female,200
age,10~20,35
age,20~30,45
age,30~40,75
age,40~50,90
age,50~60,55
edu,primary,85
edu,middle,120
edu,high,95

Я использовал nest (), чтобы сделать данные двухуровневыми и связать данные с прямоугольными, как показано ниже.

Я мог видеть, что d.key (cate_val) хорошо связан. Но проблема возникает у. Я попытался использовать d.values ​​вместо d.value, потому что значение - это имя столбца, но оно тоже не сработало. Я предположил, что мне не хватало, как получить доступ к значениям в двухуровневых вложенных данных? Я исследовал таким образом, но не мог понять, почему мой код был неправильным.

Точное сообщение об ошибке таково: Неожиданное значение NaN синтаксический анализ y атрибут.

Может ли кто-нибудь дать какие-либо идеи, чего здесь не хватает, почему значения (d.value) не связаны?

Спасибо,

<!doctype html>
<html>
<meta charset = "utf-8">

<head>
</head>

<body>
<div id = "graph">

<script src='https://d3js.org/d3.v4.min.js'></script> 
<script>

var margin = {top: 60, right: 100, bottom: 20, left: 80},
    width = 850 - margin.left - margin.right, 
    height = 370 - margin.top - margin.bottom; 

var x0 = d3.scaleBand()
            .rangeRound([0, width])
            .paddingInner(0.1);

var x1 = d3.scaleBand()
            .padding(0.05);

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

var z = d3.scaleOrdinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

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

d3.csv("practice.csv", function(error, data) {

    if (error) throw error;

    data.forEach(function(d) {
        d.cate = d.cate;
        d.cate_val = d.cate_val;
        d.value = +d.value;
    })

    var nest = d3.nest()
                .key(function(d) { return d.cate; })
                .key(function(d) { return d.cate_val; })
                .entries(data); 

    x0.domain(nest.map(function(d) { return d.key; }));
    x1.domain(data.map(function(d) { return d.cate_val; }))
        .rangeRound([0, x0.bandwidth()]);  
    y.domain([0, d3.max(nest, function(d) { return d.value; })]); 

    var category = svg.selectAll("g")
                    .data(nest)
                    .enter()
                    .append("g")

    category.selectAll("rect")
            .data(function(d) { return d.values; })
            .enter()
            .append("rect")
            .attr("x", function(d) { return x1(d.key); })
            .attr("y", function(d) { return y(d.value); })
            .attr("width", x1.bandwidth())
            .attr("height", function(d) { return height - y(d.value); }) 
            .attr("fill", function(d) { return z(d.key); });

})

</script>

</body>
</html>
...