我是d3.js的新手,并且我有一个示例CSV文件
import {
select,
csv,
scaleLinear,
max,
scaleBand,
axisLeft,
axisBottom}
from 'd3';
const svg = select('svg');
const width = +svg.attr('width');
const height = +svg.attr('height');
const render = data =>{
const margin = { top: 20, right: 40, bottom: 20, left: 100 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const ChinaFilter = data.filter(function(d){
return d.country.match ('China');
});
const IndonesiaFilter = data.filter(function(d){
return d.country.match ('Indonesia');
});
const RussiaFilter = data.filter(function(d){
return d.country.match ('Russia');
});
var Filter = [ChinaFilter.length,IndonesiaFilter.length,RussiaFilter.length];
var countryFilter = ['China','Indonesia','Russia'];
const xScale = scaleLinear()
.domain([0, max(Filter)])
.range([0, innerWidth]);
const yScale = scaleBand()
.domain(countryFilter)
.range([0, innerHeight])
.padding(0.1);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
g.append('g').call(axisLeft(yScale));
g.append('g').call(axisBottom(xScale))
.attr('transform', `translate(0,${innerHeight})`);
g.selectAll('rect').data(data)
.enter().append('rect')
.attr('y', yScale(countryFilter))
.attr('width', xScale(Filter))
.attr('height', yScale.bandwidth());
};
csv('data.csv').then(data => {
render(data);
});
完成并显示x轴和y轴后,无法创建和显示对应的条并显示该条。这是完整的代码
{{1}}
实际结果[1]:https://i.stack.imgur.com/rFJNU.png
以条形图格式显示的预期产出应为(China,3)(Indonesia,3)(Russia,4)
答案 0 :(得分:0)
您的代码中有几个问题,主要是data
数组。如果这是您的CSV:
country, year
China 1,1998-12-1
China 2,1999-12-1
China 3,2000-12-1
Indonesia 1,1999-12-1
Indonesia 2,1999-12-1
Indonesia 3,1998-12-1
Russia 1,1999-12-1
Russia 2,1998-12-1
Russia 3,1999-12-1
Russia 4,1998-12-1
这意味着您的data
是一个包含10个对象的数组,因此我们希望在条形图中看到10条。事实并非如此。由于您只想显示每个国家的记录数,所以我们创建一个正确的数据数组,这里命名为correctData
:
var countryFilter = ['China', 'Indonesia', 'Russia'];
var correctData = countryFilter.map(function(d) {
return {
country: d,
length: data.filter(function(e) {
return e.country.match(d);
}).length
}
});
然后,我们更改比例:
const xScale = d3.scaleLinear()
.domain([0, d3.max(correctData, function(d) {
return d.length
})])
.range([0, innerWidth]);
const yScale = d3.scaleBand()
.domain(correctData.map(function(d) {
return d.country
}))
.range([0, innerHeight])
.padding(0.1);
最后,使用基准创建条形:
g.selectAll('rect').data(correctData)
.enter().append('rect')
.attr('y', function(d) {
return yScale(d.country)
})
.attr('width', function(d) {
return xScale(d.length)
})
.attr('height', yScale.bandwidth());
一些最终的考虑因素:我不清楚您为什么混用var
和const
。另外,请避免在CSV中留空格。
这是您所做的更改的代码:
const csv = `country, year
China 1,1998-12-1
China 2,1999-12-1
China 3,2000-12-1
Indonesia 1,1999-12-1
Indonesia 2,1999-12-1
Indonesia 3,1998-12-1
Russia 1,1999-12-1
Russia 2,1998-12-1
Russia 3,1999-12-1
Russia 4,1998-12-1`;
const data = d3.csvParse(csv);
const svg = d3.select('svg');
const width = +svg.attr('width');
const height = +svg.attr('height');
const render = data => {
const margin = {
top: 20,
right: 40,
bottom: 20,
left: 100
};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
var countryFilter = ['China', 'Indonesia', 'Russia'];
var correctData = countryFilter.map(function(d) {
return {
country: d,
length: data.filter(function(e) {
return e.country.match(d);
}).length
}
});
const xScale = d3.scaleLinear()
.domain([0, d3.max(correctData, function(d) {
return d.length
})])
.range([0, innerWidth]);
const yScale = d3.scaleBand()
.domain(correctData.map(function(d) {
return d.country
}))
.range([0, innerHeight])
.padding(0.1);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
g.append('g').call(d3.axisLeft(yScale));
g.append('g').call(d3.axisBottom(xScale))
.attr('transform', `translate(0,${innerHeight})`);
g.selectAll('rect').data(correctData)
.enter().append('rect')
.attr('y', function(d) {
return yScale(d.country)
})
.attr('width', function(d) {
return xScale(d.length)
})
.attr('height', yScale.bandwidth());
};
render(data);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="200"></svg>