D3-堆叠条形图-仅使用特定列CSV-计算不同元素

D3-堆叠条形图-仅使用特定列CSV-计算不同元素,csv,d3.js,Csv,D3.js,我正试图找出如何使用D3,我有两个问题。一个问题本质上是使用CSV文件某些列中的数据。此外,在本例中,我在CSV中真正需要的唯一信息是居住栏、学年栏和专业栏。我正在努力使用提供的csv,基本上让我的程序只读取这些列,而忽略名称列和ID列。第二个问题是能够计算每列中不同专业的数量,即我的条形图高度,条形图由特定组划分。例如,如果我看一个宿舍,我会看到在宿舍里,有一个明显的8个专业在宿舍里。因此,8将是最高的标准,分组将是学年。在本例中,有3名大二学生、2名大一学生、1名大四学生和2名大四学生。因此

我正试图找出如何使用D3,我有两个问题。一个问题本质上是使用CSV文件某些列中的数据。此外,在本例中,我在CSV中真正需要的唯一信息是居住栏、学年栏和专业栏。我正在努力使用提供的csv,基本上让我的程序只读取这些列,而忽略名称列和ID列。第二个问题是能够计算每列中不同专业的数量,即我的条形图高度,条形图由特定组划分。例如,如果我看一个宿舍,我会看到在宿舍里,有一个明显的8个专业在宿舍里。因此,8将是最高的标准,分组将是学年。在本例中,有3名大二学生、2名大一学生、1名大四学生和2名大四学生。因此,单栏将相应地分为4类。我假设要计算不同专业的数量,我会使用d3.nest()然后在使用d3.stack()之后做堆叠条形图

d3.csv("/data/students.csv").then(function(data) {
  console.log(data);
});
CSV: 基本上你是在大学里,你有不同学年的不同学生,不同专业的学生住在特定的大楼里

Name, Residence, ID, School Year, 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
Jo Park, Reed Hall, 22123, Freshman, Political Science
根据,
d3.nest
d3.stack
不能很好地协同工作。相反,您可以使用vanilla JavaScript将数据处理为以下格式:

[ { Residence: string, [year]: number; } ]
比如说

[ { Residence: "Davis Hall", "Sophomore": 1, "Freshman": 2 } ]
然后,堆叠条形图如下所示

您的数据中也有一些空格,这些空格是真的在那里还是为了可读性而放在那里?无论如何我都把它们拿走了

const dataString=`姓名、住所、身份证、学年、专业
比尔·桑顿,戴维斯·霍尔,11123,二年级,数学
Savannah Lipscombe,詹姆逊大厅,11231,生物系大一新生
杰伊·普莱斯,戴维斯大厅,12222,高级商务
Hassan Abdullah,Arthur Hall,11111,大三,机械工程
乔·帕克,里德·霍尔,22123,大一,政治学“.替换(/,/g,”,”);
const unique=array=>array.filter((v,i)=>array.indexOf(v)==i);
const data=d3.csvParse(数据串);
const years=unique(data.map(d=>d[“学年]);
const-residences=unique(data.map(d=>d.Residence));
const svg=d3。选择(“svg”),
保证金={
排名:35,
左:35,
底部:0,
右:0
},
宽度=+svg.attr(“宽度”)-margin.left-margin.right,
高度=+svg.attr(“高度”)-margin.top-margin.bottom;
const countedData=residences.map(r=>{
常数结果={
住所:r
};
年份。forEach(年份=>{
结果[年度]=[];
});
data.filter(d=>d.Residence==r)
.forEach(d=>{
结果[d[“学年]]推动(d专业);
});
年份。forEach(年份=>{
结果[年]=唯一(结果[年])长度;
});
返回结果;
});
console.log(countedData);
常量x=d3.scaleBand()
.范围([margin.left,width-margin.right])
.域名(住宅)
.填充(0.1)
常数y=d3.scaleLinear()
.domain([0,d3.max(countedData,d=>d3.sum(years.map(y=>d[y]))))
.范围([高度-边距.底部,边距.顶部]);
常数z=d3.scaleOrdinal()
.range([“钢蓝色”、“深蓝色”、“浅蓝色”])
.域名(年);
const xAxis=svg.append(“g”)
.attr(“transform”,`translate(0,${height-margin.bottom})`)
.attr(“类”、“x轴”)
const yAxis=svg.append(“g”)
.attr(“transform”,translate(${margin.left},0)`)
.attr(“类”、“y轴”)
svg.selectAll(“.y轴”)
.呼叫(d3.左(y)
.ticks(空,“s”))
svg.selectAll(“.x轴”)
.call(d3.axisBottom(x)
.滴答器(0))
const stackedData=d3.stack().keys(年)(countedData);
控制台日志(stackedData);
const group=svg.selectAll(“g.layer”)
.data(stackedData,d=>d.key)
group.exit().remove()
group.enter()
.附加(“g”)
.classed(“层”,真)
.attr(“填充”,d=>z(d.key));
const bar=svg.selectAll(“g.layer”)
.selectAll(“rect”)
.数据(d=>d,e=>e.data.Residence);
bar.exit().remove()
输入()
.append(“rect”)
.attr(“宽度”,x.带宽())
.合并(条)
.attr(“x”,d=>x(d.data.Residence))
.attr(“y”,d=>y(d[1]))
.attr(“高度”,d=>y(d[0])-y(d[1])

这是否回答了您的问题?