Javascript d3.js-如何为堆叠条形图进行数据映射和过滤
我正在d3.js中实现一个堆叠条形图。它适用于多年来城市中各种类别(人群类别)的人口。虽然我在一些参考资料的帮助下取得了一些成果,但我没有得到我想要的确切结果 我想我在数据映射和过滤函数,以及在颜色域中分配它们方面遇到了一些问题 任何帮助都将不胜感激 这是我的密码:-Javascript d3.js-如何为堆叠条形图进行数据映射和过滤,javascript,d3.js,Javascript,D3.js,我正在d3.js中实现一个堆叠条形图。它适用于多年来城市中各种类别(人群类别)的人口。虽然我在一些参考资料的帮助下取得了一些成果,但我没有得到我想要的确切结果 我想我在数据映射和过滤函数,以及在颜色域中分配它们方面遇到了一些问题 任何帮助都将不胜感激 这是我的密码:- <!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .ax
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js">
</script>
<script>
var margin = {
top: 20, right: 20, bottom: 30, left: 40}
,
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
yAxMin_PA = 0,
yAxMax_PA = 1500;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.domain([yAxMin_PA, yAxMax_PA])
.range([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var svg = d3.select("body").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 + ")");
var data = {
"bars": [
{
"year": 2004,
"population": [
{
"category": 1,
"strength": 31
}
,
{
"category": 2,
"strength": 21
}
,
{
"category": 3,
"strength": 41
}
]
}
,
{
"year": 2005,
"population": [
{
"category": 1,
"strength": 23
}
,
{
"category": 2,
"strength": 43
}
,
{
"category": 3,
"strength": 33
}
]
}
,
{
"year": 2006,
"population": [
{
"category": 1,
"strength": 29
}
,
{
"category": 2,
"strength": 41
}
,
{
"category": 3,
"strength": 55
}
,
{
"category": 4,
"strength": 69
}
,
{
"category": 5,
"strength": 89
}
,
{
"category": 6,
"strength": 75
}
]
}
,
{
"year": 2007,
"population": [
{
"category": 1,
"strength": 49
}
,
{
"category": 2,
"strength": 43
}
,
{
"category": 3,
"strength": 25
}
]
}
,
{
"year": 2008,
"population": [
{
"category": 1,
"strength": 20
}
,
{
"category": 2,
"strength": 43
}
,
{
"category": 3,
"strength": 55
}
]
}
]
}
;
x.domain(data.bars.map(function(d) {
return d.year;
}
));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Population");
for (k = 0; k < data.bars.length; k++) {
var state = svg.append("g")
.attr("class", "g")
.attr("transform", function (d) {
return "translate(" + x(data.bars[k].year) + ",0)";
});
state.selectAll("rect")
.data(data.bars[k].population)
.enter().append("rect")
//.attr("width", x.rangeBand())
.attr("class", "rect_grp" + k)
.attr("id", function (d, i) {
return "rect" + i;
})
.attr("width", function () {
return x.rangeBand();
})
.attr("y", function (d, i) { /*console.log("hiii");*/
if (i != 0) {
var prevHgt = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("height"); // Select height of previous rectangle
var ylimit = d3.select(".rect_grp" + k + "#rect" + (i - 1)).attr("y"); // Select y of previous rectangle
console.log("prevHgt=>" + prevHgt);
return ((parseFloat(ylimit)) - (parseFloat(prevHgt)));
} else {
return y(d.strength);
}
})
.attr("height", function (d, i) {
return (Math.round(y(yAxMin_PA)) - Math.round(y(d.strength)));
})
.style("fill", function (d, i) {
console.log(i);
return color(i);
});
身体{
字体:10px无衬线;
}
.轴线路径,
.轴线{
填充:无;
行程:#000;
形状渲染:边缘清晰;
}
.酒吧{
填充:钢蓝;
}
.x轴路径{
显示:无;
}
var保证金={
顶部:20,右侧:20,底部:30,左侧:40}
,
宽度=960-margin.left-margin.right,
高度=500-页边距.顶部-页边距.底部,
yAxMin_PA=0,
yAxMax_PA=1500;
var x=d3.scale.ordinal()
.rangeRoundBands([0,宽度],.1);
变量y=d3.scale.linear()
.domain([yAxMin\u PA,yAxMax\u PA])
.范围([高度,0]);
var color=d3.scale.category20();
var xAxis=d3.svg.axis()
.比例(x)
.东方(“底部”);
var yAxis=d3.svg.axis()
.比例(y)
.东方(“左”)
.tick格式(d3格式(“.2s”);
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
风险值数据={
“酒吧”:[
{
“年份”:2004年,
“人口”:[
{
"类别":一,,
“实力”:31
}
,
{
“类别”:2,
“实力”:21
}
,
{
“类别”:3,
“实力”:41
}
]
}
,
{
“年份”:2005年,
“人口”:[
{
"类别":一,,
“实力”:23
}
,
{
“类别”:2,
“力量”:43
}
,
{
“类别”:3,
“实力”:33
}
]
}
,
{
“年份”:2006年,
“人口”:[
{
"类别":一,,
“力量”:29
}
,
{
“类别”:2,
“实力”:41
}
,
{
“类别”:3,
“力量”:55
}
,
{
“类别”:4,
“力量”:69
}
,
{
“类别”:5,
“力量”:89
}
,
{
“类别”:6,
“强度”:75
}
]
}
,
{
“年份”:2007年,
“人口”:[
{
"类别":一,,
“力量”:49
}
,
{
“类别”:2,
“力量”:43
}
,
{
“类别”:3,
“强度”:25
}
]
}
,
{
“年份”:2008年,
“人口”:[
{
"类别":一,,
“实力”:20
}
,
{
“类别”:2,
“力量”:43
}
,
{
“类别”:3,
“力量”:55
}
]
}
]
}
;
x、 域(data.bars.map)(函数(d){
返回d.year;
}
));
svg.append(“g”)
.attr(“类”、“x轴”)
.attr(“变换”、“平移(0)”、“高度+”)
.呼叫(xAxis);
svg.append(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis)
.append(“文本”)
.attr(“变换”、“旋转(-90)”)
.attr(“y”,6)
.attr(“dy”,“.71em”)
.style(“文本锚定”、“结束”)
.文本(“人口”);
对于(k=0;k”+prevHgt);
返回((parseFloat(ylimit))-(parseFloat(prevHgt));
}否则{
返回y(d.强度);
}
})
.attr(“高度”,函数(d,i){
返回(数学圆(y(yAxMin_PA))-数学圆(y(d.strength));
})
.样式(“填充”,功能(d,i){
控制台日志(i);
返回颜色(i);
});
}
我发现给人们举个例子是很有用的,而不是让他们自己运行。请参见此处: 在157号线附近,上面写着
d.population.forEach (function(d){
color.domain(d3.keys(d).filter(function(name) {
return name;
}
名称
始终是的“类别”
或的“强度”
。这是因为您的数据是如何安排的。我想你想要的是你的数据
{year: 2008,
population: {
category1: 20,
category2: 43,
category3: 55}
}
如果您这样放置数据,您将不得不搞乱如何准确地设置
color
实例的域,因为forEach
只在数组上工作,我们现在已经将数据设置为在对象中。类似于color.domain(d3.keys(d.population))
。把我的例子放在支流上,试着做几件事。查看d3.keys()
文档了解它是如何工作的。那么您的问题是什么?你想要实现什么?你目前的解决方案有哪些不足之处?我没有得到颜色域中的类别。对于eg-我需要每年颜色域中的所有类别(例如2004年,我们有三类人“类别”:1,“类别”:2,“类别”:3)。如果运行此代码,您将看到问题。您
{year: 2008,
population: {
category1: 20,
category2: 43,
category3: 55}
}