我尝试创建一个水平单个堆叠条,用作从零件到整个图形。有点像饼图,但是一个酒吧。我以前能够创建一个正常的垂直和堆积条形图,但我没有遇到同样的问题,而且根本没有显示矩形元素。
我删除了y轴,因为标签将通过图例或附加文字。
这是我得到的错误:
d3.min.js:2未捕获的TypeError:无法将undefined或null转换为 宾语 在切片() 在Function.n.range(d3.min.js:2) 在抽奖(singlestackedsharebar.html:94) 在d3.min.js:2 在对象。 (d3.min.js:2) 在k.call(d3.min.js:2) 在XMLHttpRequest.e(d3.min.js:2)
我认为当我创建堆栈和系列时会出现问题。当我记录该系列时,似乎下一个数组并没有像以前那样添加它们。
这里是完整的代码:
function draw(data) {
// Turns all the strings in the csv into integer values.
data.forEach(function(d) {
d.Total = +d.Total;
});
var width = document.getElementById('barchart').offsetWidth,
height = document.getElementById('barchart').offsetHeight;
var margin = {
top: 50,
right: 200,
bottom: 140,
left: 260
};
var svg = d3.select('#barchart')
.append('svg')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', '0 0 ' + width + ' ' + height)
.append('g');
width = width - margin.left - margin.right,
height = height - margin.top - margin.bottom;
svg.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Create x and y scale.
var xScale = d3.scaleLinear()
.range([0, width]);
var yScale = d3.scaleBand()
.range([0, height])
.padding(0.1);
// Create domains.
xScale.domain([0, d3.max(data, function(d) {
return d.Total;
})]);
// Create axes.
var x_axis = svg.append('g')
.attr('class', 'axis')
.attr('padding', 1)
.attr('transform', 'translate(' + 0 + ',' + height + ')')
.call(d3.axisBottom(xScale)
.ticks(10, 's'));
// Choose which columns to have as keys with slice method.
var keys = data.map(function(d) {
return d.Type;
});
// Create stack of the data with keys.
var stack = d3.stack([data])
.keys(["Total"]);
console.log(keys);
// Create series of the data.
var series = stack(data);
console.log(series);
// Create color scale with colorbrewer or pass in array of colors.
var colorScale = d3.scaleOrdinal()
.domain([0, 12])
.range(colorbrewer.Oranges[12]);
// Append rectangles.
var bars = svg.append('g')
.selectAll('g')
.data(series)
.enter()
.append('g')
.attr('fill', function(d) {
return colorScale(d.key);
})
.selectAll('rect')
.data(function(d) {
return data.d;
})
.enter()
.append('rect')
.attr('x', function(d, i) {
return xScale(d[0]);
})
.attr('width', function(d, i) {
return xScale(d[1]) - xScale(d[0]);
});
};
<body>
d3.csv('https://raw.githubusercontent.com/dieterholger/dieterholger.github.io/master/data/disputeshare.csv', draw);
</body>
答案 0 :(得分:2)
你这里有很多问题。首先是次要的:
y
和height
属性; 但到目前为止,这里最重要的问题是堆栈生成器。您根本无法将堆栈生成器与您拥有的数据一起使用,即......
[
{2015: "1528", 2016: "1187", Type: "Disputed Settlement Criteria/Bet Instructions", Total: 2715},
{2015: "999", 2016: "676", Type: "Price Dispute", Total: 1675},
{2015: "571", 2016: "299", Type: "Late Bets", Total: 870}
//etc...
];
...用于创建单个栏。最重要的是,您的keys
方法是错误的。
您应该做的是在其上创建一个包含单个对象的数组:
var newData = [{}];
data.forEach(function(d) {
newData[0][d.Type] = d.Total
});
使用这个新数组的堆栈生成器。
以下是使用您的代码作为基础并应用我提到的所有更改的演示。另外,我改变了演示的SVG的高度和宽度:
function draw(data) {
// Turns all the strings in the csv into integer values.
data.forEach(function(d) {
d.Total = +d.Total;
});
var width = 500,
height = 100;
var margin = {
top: 10,
right: 10,
bottom: 30,
left: 10
};
var svg = d3.select('body')
.append('svg')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', '0 0 ' + width + ' ' + height)
.append('g');
width = width - margin.left - margin.right,
height = height - margin.top - margin.bottom;
svg.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Create x and y scale.
var xScale = d3.scaleLinear()
.range([0, width]);
var yScale = d3.scaleBand()
.range([0, height])
.padding(0.1);
// Create domains.
xScale.domain([0, d3.sum(data, function(d) {
return d.Total;
})]);
// Create axes.
var x_axis = svg.append('g')
.attr('class', 'axis')
.attr('padding', 1)
.attr('transform', 'translate(' + 0 + ',' + height + ')')
.call(d3.axisBottom(xScale)
.ticks(10, 's'));
// Choose which columns to have as keys with slice method.
var keys = data.map(function(d) {
return d.Type;
});
var newData = [{}];
data.forEach(function(d) {
newData[0][d.Type] = d.Total
});
// Create stack of the data with keys.
var stack = d3.stack()
.keys(keys);
// Create series of the data.
var series = stack(newData);
// Create color scale with colorbrewer or pass in array of colors.
var colorScale = d3.scaleOrdinal()
.domain([0, 12])
.range(d3.schemeCategory10);
// Append rectangles.
var bars = svg.selectAll(null)
.data(series)
.enter()
.append('g')
.attr('fill', function(d) {
return colorScale(d.key);
})
.selectAll('rect')
.data(function(d) {
return d;
})
.enter()
.append('rect')
.attr('x', function(d, i) {
return xScale(d[0]);
})
.attr('width', function(d, i) {
return xScale(d[1]) - xScale(d[0]);
})
.attr("height", yScale.bandwidth());
};
d3.csv('https://raw.githubusercontent.com/dieterholger/dieterholger.github.io/master/data/disputeshare.csv', draw);
<script src="https://d3js.org/d3.v4.min.js"></script>