javascript - 如何让线条在 d3.js 多折线图上呈现?
问题描述
我目前正在学习 d3,并且很难获得多折线图来呈现路径。在这种情况下,轴都是可见的,但是我无法弄清楚为什么实际的线条没有出现。我怀疑问题出在我对 scaleOrdinal 的使用(或误用)上。我已经成功地制作了具有相似数据的单折线图。
谁能帮我确定为什么我的行没有出现在这个例子中?
<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const width = 1000;
const height = 500;
const margin = 100;
const data = [
{"Name":"Argentina","Year":"2000","Spend":3266633317},
{"Name":"Argentina","Year":"2001","Spend":3183591796},
{"Name":"Argentina","Year":"2002","Spend":1114172483},
{"Name":"Argentina","Year":"2003","Spend":1374873734},
{"Name":"Argentina","Year":"2004","Spend":1465809188},
{"Name":"Argentina","Year":"2005","Spend":1699579152},
{"Name":"Argentina","Year":"2006","Spend":1847553130},
{"Name":"Argentina","Year":"2007","Spend":2296448242},
{"Name":"Argentina","Year":"2008","Spend":2788980205},
{"Name":"Argentina","Year":"2009","Spend":2981852290},
{"Name":"Argentina","Year":"2010","Spend":3475348407},
{"Name":"Argentina","Year":"2011","Spend":4051930105},
{"Name":"Argentina","Year":"2012","Spend":4563217859},
{"Name":"Argentina","Year":"2013","Spend":5137974301},
{"Name":"Argentina","Year":"2014","Spend":4979442724},
{"Name":"Argentina","Year":"2015","Spend":5482616701},
{"Name":"Argentina","Year":"2016","Spend":4509647660},
{"Name":"Argentina","Year":"2017","Spend":5459643672},
{"Name":"Argentina","Year":"2018","Spend":4144991771},
{"Name":"Armenia","Year":"2000","Spend":68052142},
{"Name":"Armenia","Year":"2001","Spend":66247626},
{"Name":"Armenia","Year":"2002","Spend":64106406},
{"Name":"Armenia","Year":"2003","Spend":76587999},
{"Name":"Armenia","Year":"2004","Spend":98070488},
{"Name":"Armenia","Year":"2005","Spend":140738103},
{"Name":"Armenia","Year":"2006","Spend":188189116},
{"Name":"Armenia","Year":"2007","Spend":280108688},
{"Name":"Armenia","Year":"2008","Spend":395994365},
{"Name":"Armenia","Year":"2009","Spend":359499344},
{"Name":"Armenia","Year":"2010","Spend":395011508},
{"Name":"Armenia","Year":"2011","Spend":390871434},
{"Name":"Armenia","Year":"2012","Spend":380571679},
{"Name":"Armenia","Year":"2013","Spend":444551860},
{"Name":"Armenia","Year":"2014","Spend":457807022},
{"Name":"Armenia","Year":"2015","Spend":447379808},
{"Name":"Armenia","Year":"2016","Spend":431396219},
{"Name":"Armenia","Year":"2017","Spend":443610413},
{"Name":"Armenia","Year":"2018","Spend":608854650},
{"Name":"Australia","Year":"2000","Spend":7273760313},
{"Name":"Australia","Year":"2001","Spend":7043145895},
{"Name":"Australia","Year":"2002","Spend":7946766202},
{"Name":"Australia","Year":"2003","Spend":9926649415},
{"Name":"Australia","Year":"2004","Spend":11995219710},
{"Name":"Australia","Year":"2005","Spend":13237798499},
{"Name":"Australia","Year":"2006","Spend":14239779513},
{"Name":"Australia","Year":"2007","Spend":17186440962},
{"Name":"Australia","Year":"2008","Spend":18633092318},
{"Name":"Australia","Year":"2009","Spend":18960138513},
{"Name":"Australia","Year":"2010","Spend":23217692816},
{"Name":"Australia","Year":"2011","Spend":26597198655},
{"Name":"Australia","Year":"2012","Spend":26216580848},
{"Name":"Australia","Year":"2013","Spend":24825262589},
{"Name":"Australia","Year":"2014","Spend":25783708714},
{"Name":"Australia","Year":"2015","Spend":24045569111},
{"Name":"Australia","Year":"2016","Spend":26382947050},
{"Name":"Australia","Year":"2017","Spend":27691112417},
{"Name":"Australia","Year":"2018","Spend":26711834225}
];
const scaleX = d3
.scaleLinear()
.domain(d3.extent(data, d => d.Year))
.range([margin, width - margin]);
const scaleY = d3
.scaleLinear()
.domain(d3.extent(data, d => d.Spend))
.range([height - margin, margin])
.nice();
const colorScale = d3
.scaleOrdinal(d3.schemeCategory10)
.domain(data.map(item => item.Name).reduce((a,b) => a.indexOf(b) !== -1 ? a : [...a, b], []));
const line = d3
.line()
.x(d => scaleX(d.Year))
.y(d => scaleY(d.Spend));
const xAxis = d3.axisBottom(scaleX);
const yAxis = d3.axisLeft(scaleY);
const svg = d3
.select("body")
.append("svg")
.attr("height", height)
.attr("width", width);
const axes = svg
.append("g")
.attr("class", "axes");
axes.append("g")
.call(xAxis)
.attr("transform", `translate(${[0, height - margin]})`);
axes.append("g")
.call(yAxis)
.attr("transform", `translate(${[margin, 0]})`);
svg.selectAll("path.dataset")
.data(data).join("path")
.attr("class", "dataset")
.attr("d", line)
.attr("stroke", colorScale)
</script>
解决方案
你的数据结构还没有准备好。你看,你正在处理每个对象,就好像它们是线生成器的可迭代对象,但显然它们不是。
一个简单的解决方案是按国家分组:
const groups = d3.groups(data, d => d.Name);
然后,只需执行以下操作:
svg.selectAll("path.dataset")
.data(groups)
.join("path")
.attr("class", "dataset")
.attr("d", d => line(d[1]))
//etc...
这是您的代码进行了这 2 项更改:
path {
fill: none;
}
<script src="https://d3js.org/d3.v6.min.js"></script>
<script>
const width = 1000;
const height = 500;
const margin = 100;
const data = [{
"Name": "Argentina",
"Year": "2000",
"Spend": 3266633317
},
{
"Name": "Argentina",
"Year": "2001",
"Spend": 3183591796
},
{
"Name": "Argentina",
"Year": "2002",
"Spend": 1114172483
},
{
"Name": "Argentina",
"Year": "2003",
"Spend": 1374873734
},
{
"Name": "Argentina",
"Year": "2004",
"Spend": 1465809188
},
{
"Name": "Argentina",
"Year": "2005",
"Spend": 1699579152
},
{
"Name": "Argentina",
"Year": "2006",
"Spend": 1847553130
},
{
"Name": "Argentina",
"Year": "2007",
"Spend": 2296448242
},
{
"Name": "Argentina",
"Year": "2008",
"Spend": 2788980205
},
{
"Name": "Argentina",
"Year": "2009",
"Spend": 2981852290
},
{
"Name": "Argentina",
"Year": "2010",
"Spend": 3475348407
},
{
"Name": "Argentina",
"Year": "2011",
"Spend": 4051930105
},
{
"Name": "Argentina",
"Year": "2012",
"Spend": 4563217859
},
{
"Name": "Argentina",
"Year": "2013",
"Spend": 5137974301
},
{
"Name": "Argentina",
"Year": "2014",
"Spend": 4979442724
},
{
"Name": "Argentina",
"Year": "2015",
"Spend": 5482616701
},
{
"Name": "Argentina",
"Year": "2016",
"Spend": 4509647660
},
{
"Name": "Argentina",
"Year": "2017",
"Spend": 5459643672
},
{
"Name": "Argentina",
"Year": "2018",
"Spend": 4144991771
},
{
"Name": "Armenia",
"Year": "2000",
"Spend": 68052142
},
{
"Name": "Armenia",
"Year": "2001",
"Spend": 66247626
},
{
"Name": "Armenia",
"Year": "2002",
"Spend": 64106406
},
{
"Name": "Armenia",
"Year": "2003",
"Spend": 76587999
},
{
"Name": "Armenia",
"Year": "2004",
"Spend": 98070488
},
{
"Name": "Armenia",
"Year": "2005",
"Spend": 140738103
},
{
"Name": "Armenia",
"Year": "2006",
"Spend": 188189116
},
{
"Name": "Armenia",
"Year": "2007",
"Spend": 280108688
},
{
"Name": "Armenia",
"Year": "2008",
"Spend": 395994365
},
{
"Name": "Armenia",
"Year": "2009",
"Spend": 359499344
},
{
"Name": "Armenia",
"Year": "2010",
"Spend": 395011508
},
{
"Name": "Armenia",
"Year": "2011",
"Spend": 390871434
},
{
"Name": "Armenia",
"Year": "2012",
"Spend": 380571679
},
{
"Name": "Armenia",
"Year": "2013",
"Spend": 444551860
},
{
"Name": "Armenia",
"Year": "2014",
"Spend": 457807022
},
{
"Name": "Armenia",
"Year": "2015",
"Spend": 447379808
},
{
"Name": "Armenia",
"Year": "2016",
"Spend": 431396219
},
{
"Name": "Armenia",
"Year": "2017",
"Spend": 443610413
},
{
"Name": "Armenia",
"Year": "2018",
"Spend": 608854650
},
{
"Name": "Australia",
"Year": "2000",
"Spend": 7273760313
},
{
"Name": "Australia",
"Year": "2001",
"Spend": 7043145895
},
{
"Name": "Australia",
"Year": "2002",
"Spend": 7946766202
},
{
"Name": "Australia",
"Year": "2003",
"Spend": 9926649415
},
{
"Name": "Australia",
"Year": "2004",
"Spend": 11995219710
},
{
"Name": "Australia",
"Year": "2005",
"Spend": 13237798499
},
{
"Name": "Australia",
"Year": "2006",
"Spend": 14239779513
},
{
"Name": "Australia",
"Year": "2007",
"Spend": 17186440962
},
{
"Name": "Australia",
"Year": "2008",
"Spend": 18633092318
},
{
"Name": "Australia",
"Year": "2009",
"Spend": 18960138513
},
{
"Name": "Australia",
"Year": "2010",
"Spend": 23217692816
},
{
"Name": "Australia",
"Year": "2011",
"Spend": 26597198655
},
{
"Name": "Australia",
"Year": "2012",
"Spend": 26216580848
},
{
"Name": "Australia",
"Year": "2013",
"Spend": 24825262589
},
{
"Name": "Australia",
"Year": "2014",
"Spend": 25783708714
},
{
"Name": "Australia",
"Year": "2015",
"Spend": 24045569111
},
{
"Name": "Australia",
"Year": "2016",
"Spend": 26382947050
},
{
"Name": "Australia",
"Year": "2017",
"Spend": 27691112417
},
{
"Name": "Australia",
"Year": "2018",
"Spend": 26711834225
}
];
const groups = d3.groups(data, d => d.Name);
const scaleX = d3
.scaleLinear()
.domain(d3.extent(data, d => d.Year))
.range([margin, width - margin]);
const scaleY = d3
.scaleLinear()
.domain(d3.extent(data, d => d.Spend))
.range([height - margin, margin])
.nice();
const colorScale = d3
.scaleOrdinal(d3.schemeCategory10)
.domain(data.map(item => item.Name).reduce((a, b) => a.indexOf(b) !== -1 ? a : [...a, b], []));
const line = d3
.line()
.x(d => scaleX(d.Year))
.y(d => scaleY(d.Spend));
const xAxis = d3.axisBottom(scaleX);
const yAxis = d3.axisLeft(scaleY);
const svg = d3
.select("body")
.append("svg")
.attr("height", height)
.attr("width", width);
const axes = svg
.append("g")
.attr("class", "axes");
axes.append("g")
.call(xAxis)
.attr("transform", `translate(${[0, height - margin]})`);
axes.append("g")
.call(yAxis)
.attr("transform", `translate(${[margin, 0]})`);
svg.selectAll("path.dataset")
.data(groups)
.join("path")
.attr("class", "dataset")
.attr("d", d => line(d[1]))
.attr("stroke", colorScale)
</script>
推荐阅读
- css - 元素选择器
tag is ignored in scss
- php - 提交表单时如何检查 CSRF 令牌
- powershell - 关闭窗口后,ExecutionPolicy 重置回未定义
- haskell - 使用 ($) 进行评估和类型检查的顺序
- java - 为什么我不能用初始容量初始化匿名字符串数组?
- java - 我不明白为什么第二次排序的运行时间比第一次慢?
- scala - 具有 scala 未来的 Akka http 路由
- c# - 如何读取 txt 文件并将其显示为控制台应用程序中的表格?
- docker - 有条件地在 Dockerfile 中公开端口
- wcf - 如何诊断来自 Web API 的慢速 HTTPS 请求