使用CSV将数据嵌套在D3中后,制作组条形图 [英] Make a Group Bar Chart after nesting data in D3 using CSV

查看:37
本文介绍了使用CSV将数据嵌套在D3中后,制作组条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对D3并不真正熟悉,并且在嵌套特定数据后创建组条形图的概念很麻烦.我试图创建的分组条形图本质上应该看起来像这样.条形分隔的条形应该指示学生宿舍,每个颜色条将指示学生人数.我的问题是,如何才能将嵌套数据中的值用作学生学年的高低,如何将数据除以学生宿舍,如果您注意到我的控制台仅输出具有该值的学年,如果该学年不在学生宿舍中,则不会输出0值.我只是在努力理解D3,我想知道如何使用嵌套数据创建分组的条形图.

I am not really familiar with D3 and I am struggling with the concept of creating a group bar chart after I nested the specific data. The grouped bar chart I am trying to create essentially should look this. The cluster of bars that are separated should indicate the residence hall and each color bar would indicate the school years of the amount of students in the residence hall. My issue is how would I get the value within the nested data to essentially be used as the height of a bar of the student's school year, how would I go around dividing the data by residence hall, and if you notice my console outputs only that school years that have a value, it doesn't output a value of 0 if the school year is not in the residence hall. I am just struggling to understand D3 and i want to know how to use the nested data to create the grouped bar graph.

这只是我希望条形图外观的一般概述.这些值显然会有所不同,只是一般的SketchUp.

This is just a general overview of how I want the bar chart to look. The values will obviously be different, just a general SketchUp.

这是使用d3.nest()之后数据的控制台输出.如果您注意到,则没有键大二".显示值为0.我不知道在输出到图形时这是否有所不同.

This is the console output of the data after using d3.nest(). If you notice, there isn't a key of "Sophomore" showing value 0. I do not know if that makes a difference when outputting into the graph.

0:
key: "Davis Hall"
    values: Array(3)
         0: {key: "Freshman", value: 1}
         1: {key: "Junior", value: 2}
         2: {key: "Senior", value: 2}
         length: 3
     __proto__: Array(0)
__proto__: Object
1:
key: "Jameson Hall"
   values: Array(3)
       0: {key: "Sophomore", value: 1}
       1: {key: "Junior", value: 3}
       2: {key: "Senior", value: 1}
       length: 3
   __proto__: Array(0)
__proto__: Object

下面是我如何使用D3.Nest嵌套CSV数据并使用计数

Below is how I nested my CSV data using D3.Nest and I used the count

d3.csv("./data/studentresidences.csv", function(data){
    var studentBuildings = d3.nest()
        .key(function(r) { return r.Residence; })
        .key(function(s) { return s.Schoolyear; })
        .rollup(function(a) { return a.length; })
        .entries(data)
        console.log(studentBuildings);
});

这是CSV

Name, Residence, ID, Schoolyear, Major
Bill Thornton, Jameson Hall, 11123, Sophomore, Mathematics
Savannah Lipscombe, Davis Hall, 11231, Freshman, Biology
Jay Price, Jameson Hall, 12222, Senior, Business
Hassan Abdullah, Jameson Hall, 11111, Junior, Mechanical Engineering
Jo Park, Davis Hall, 22123, Junior, Political Science
Arnold Allen, Jameson Hall, 12314, Junior, Psychology
Anthony Daniels, Davis Hall,15125, Senior, Aerospace Engineering
Josephine Alvarez, Davis Hall,11512, Junior, Chemistry
Cynthia Blackman, Davis Hall,66142, Senior, Computer Science
Sophie Aspen, Jameson Hall,111221, Junior, English

推荐答案

请考虑以下内容.您的开始不错,但是您需要两个X轴.一个将每个居住区的总区域划分为相等的地点,另一个将占据该居住区的区域划分为每年.

Consider the following. Your start was good, but you need to have two x-axes. One divides the total domain up into equal spots per residence, and one that takes that residence area and divides it per year.

您可以轻松地使用 x.bandwidth()来获取该区域的大小.

You can easily use x.bandwidth() to get the size of that area.

const dataString = `Name, Residence, ID, Schoolyear, Major
Bill Thornton, Davis Hall, 11123, Sophomore, Mathematics
Savannah Lipscombe, Jameson Hall, 11231, Freshman, Biology
Jay Price, Davis Hall, 12222, Senior, Business
Hassan Abdullah, Arthur Hall, 11111, Junior, Mechanical Engineering
John Doe, Arthur Hall, 11112, Junior, Mechanical Engineering
Jo Park, Reed Hall, 22123, Freshman, Political Science`.replace(/, /g, ",");

const unique = array => array.filter((v, i) => array.indexOf(v) === i);

const data = d3.csvParse(dataString);
const years = unique(data.map(d => d.Schoolyear));

var groupedData = d3.nest()
  .key(d => d.Residence)
  .key(d => d.Schoolyear)
  .rollup(v => v.length)
  .entries(data)
console.log(groupedData);

const svg = d3.select("svg"),
  margin = {
    top: 35,
    left: 35,
    bottom: 0,
    right: 0
  },
  width = +svg.attr("width") - margin.left - margin.right,
  height = +svg.attr("height") - margin.top - margin.bottom;

const x = d3.scaleBand()
  .range([margin.left, width - margin.right])
  // The residences
  .domain(groupedData.map(d => d.key))
  .padding(0.1);

const subX = d3.scaleBand()
  .range([0, x.bandwidth()])
  .domain(years)
  .padding(0.05);

// Calculate the nested max
const max = d3.max(
  groupedData,
  d => d3.max(d.values, e => e.value)
);
const y = d3.scaleLinear()
  .domain([0, max])
  .range([height - margin.bottom, margin.top]);

const z = d3.scaleOrdinal()
  .range(["steelblue", "darkorange", "lightblue"])
  .domain(years);

const xAxis = svg.append("g")
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .attr("class", "x-axis")

const yAxis = svg.append("g")
  .attr("transform", `translate(${margin.left},0)`)
  .attr("class", "y-axis")

svg.selectAll(".y-axis")
  .call(d3.axisLeft(y)
    .ticks(null, "s"))

const bargroups = svg.selectAll("g.bargroup")
  .data(groupedData, d => d.key)

bargroups.exit().remove()

const bars = bargroups.enter()
  .append("g")
  .classed("bargroup", true)
  .merge(bargroups)
  .attr("transform", d => `translate(${x(d.key)}, 0)`)
  .selectAll("rect")
  .data(d => d.values, e => e.key);

bars.exit().remove()

bars.enter()
  .append("rect")
  .attr("width", subX.bandwidth())
  .merge(bars)
  .attr("x", d => subX(d.key))
  .attr("y", d => y(d.value))
  .attr("height", d => height - y(d.value))
  .attr("fill", d => z(d.key))

// Draw the main axis labels
xAxis
  .call(d3.axisBottom(x)
    .tickSize(0)
    .tickPadding(24));

// For every tick, add the year labels
xAxis.selectAll(".tick")
  .each(function() {
    d3.select(this)
      .selectAll(".year-tick")
      .data(years)
      .enter()
      .append("text")
      .classed("year-tick", true)
      .attr("fill", "currentColor")
      .attr("text-anchor", "middle")
      .attr("y", (d, i) => i % 2 === 0 ? 3 : 12)
      .attr("dy", "0.71em")
      .attr("x", d => subX(d) - (x.bandwidth() / 2))
      .attr("dx", d => subX.bandwidth() / 2)
      .text(d => d);
  });

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="700" height="300"></svg>

这篇关于使用CSV将数据嵌套在D3中后,制作组条形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆