使用d3在d3中绘制成组线。组
我正在使用一个整齐的长数据结构,它有三列:Date、ID、Num_Orders。
date ID num_orders
"2018-08-22" 1 3
"2018-08-23" 7 1
"2018-08-23" 10 1
"2018-08-23" 17 1
"2018-08-23" 19 1
.
.
.
我想使用D3.js为每个ID绘制一条线,将date和num_order分别作为x轴和y轴。我使用this作为我正在做的事情的模型,但是在该代码中,作者使用的是nest()
函数,该函数在D3的V6中不再使用;现在使用的方法是group()
。所以我现在的代码是:
const margin = { top: 10, right: 30, bottom: 30, left: 60 };
const width = 1000 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;
const svg = d3.select('#my_dataviz')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform',
`translate(${margin.left}, ${margin.top})`);
d3.json("./data.json")
.then( function(data) {
const grouped_data = d3.group(data, d => d.ID);
parseDate = d3.timeParse('%Y-%m-%d')
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => parseDate(d.date)))
.range([0, width]);
svg.append('g')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.num_orders)])
.range([height, 0]);
svg.append('g')
.call(d3.axisLeft(yScale));
const myColor = d3.scaleOrdinal()
.domain(grouped_data.keys())
.range(d3.schemeSet3);
svg.selectAll('.line')
.data(grouped_data)
.enter()
.append('path')
.attr('fill', 'none')
.attr('stroke', d => myColor(d.keys))
.attr('stroke-width', 1.5)
.attr('d', function(d){
return d3.line()
.x(d => xScale(d.date))
.y(d => yScale(d.num_orders))
(d.values);
});
} )
到目前为止,我可以显示带有勾号的轴,但是没有显示任何线条,这让我认为问题出在最后的svg.selectAll('.line')
语句中。我是D3的新手,所以对这个问题的任何指导都是非常感谢的。(如果您对我的代码有任何总体建议,我也欢迎。)
解决方案
d3.line()仅接受数组,而d.Values()是迭代器。 通过将其转换为数组,问题就解决了。
请注意,我删除了代码片段上的parseDate,因为我将数据生成为日期。 您很可能需要保留parseDate
const margin = { top: 10, right: 30, bottom: 30, left: 60 };
const width = 1000 - margin.left - margin.right;
const height = 600 - margin.top - margin.bottom;
var x = d3.timeDays(new Date(2020, 06, 01), new Date(2020, 10, 30));
var y = Array.from({length: x.length}, Math.random).map(n => Math.floor(n * 10) + 5);
var data = x.map((v, i) => {
return {
"date": v,
"id": Math.floor(Math.random() * (10 + 1)),
"num_orders": y[i]
};
});
const svg = d3.select('#my_dataviz')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform',
`translate(${margin.left}, ${margin.top})`);
const grouped_data = d3.group(data, d => d.id);
parseDate = d3.timeParse('%Y-%m-%d');
const xScale = d3.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, width]);
svg.append('g')
.attr('transform', `translate(0, ${height})`)
.call(d3.axisBottom(xScale));
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.num_orders)])
.range([height, 0]);
svg.append('g')
.call(d3.axisLeft(yScale));
const myColor = d3.scaleOrdinal()
.domain(grouped_data.keys())
.range(d3.schemeSet3);
const line = d3.line()
.x(d => { return xScale(d.date); })
.y(d => yScale(d.num_orders));
svg.selectAll('.line')
.data(grouped_data)
.enter()
.append('path')
.attr('fill', 'none')
.attr('stroke', d => myColor(d[0]))
.attr('stroke-width', 1.5)
.attr('d', (d) => line(Array.from(d.values())[1]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.5.0/d3.min.js"></script>
<div id="my_dataviz"></div>
相关文章