我尝试使用这个模板(里面有 d3 代码): http://bl.ocks.org/mbostock/3885211#data.tsv 并用我自己的数据更新数据。我遇到了一个问题,如图所示:
如何正确设置数据的轴?
y
轴应从 0 到所有列总和的最大值。
x
轴应从 1 到 27。
我的代码是:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.browser text {
text-anchor: end;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.rangeRound([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(".s"));
//
var area = d3.svg.area()
.x(function(d) { return x(d.User_ID); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
//
var stack = d3.layout.stack()
.values(function(d) { return d.values; });
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 + ")");
d3.csv("aggData.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "User_ID"; }));
function User_ID(d) {
d.User_ID = +d.User_ID;
return d;
}
var browsers = stack(color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {User_ID: d.User_ID, y: d[name] / 100};
})
};
}));
y.domain([0, d3.max(data, function(d) { return 40 })]);
var browser = svg.selectAll(".browser")
.data(browsers)
.enter().append("g")
.attr("class", "browser");
browser.append("path")
.attr("class", "area")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d) { return color(d.name); });
/*
browser.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.User_ID) + "," + y(d.value.y0 + d.value.y / 2) + ")"; })
.attr("x", -6)
.attr("dy", ".35em")
.text(function(d) { return d.name; });
*/
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
我的 TSV 数据是:
User_ID RegisteredUsers SuperUsers Executives
1 477 2238 981
2 189 1829 1324
3 894 27 2242
4 285 1773 1157
5 1291 64 2295
6 284 769 2653
7 1241 559 1210
8 759 920 1398
9 872 36 2320
10 352 1804 905
11 309 2358 778
12 1013 36 2183
13 928 441 22
14 2658 735 1189
15 1040 1353 1005
16 1427 746 1612
17 749 101 2246
18 925 41 2298
19 106 64 3231
20 619 203 2070
21 391 2203 728
22 755 139 2263
23 696 248 2080
24 1883 0 1785
25 1028 123 1866
26 626 286 2070
27 1128 145 1864
(每行的键是User_ID
)
最佳答案
正如您在问题中指出的,您的主要问题是设置域。 x
域非常简单,您只想找到 User_ID
的最大值:
x.domain(d3.extent(data, function(d){ return +d.User_ID; }));
y
域更为复杂。与您链接到的示例不同,您的值的域不是 [0, 1]
——这是 d3.scale.linear()
的默认值。 。但是,您可以直接根据输入数据计算域,这就是您在问题中询问的内容。唯一的问题是,对于每个对象(表中的行),您需要获取最大列:
y.domain([0, d3.max(data, function(d){
// return the maximum value of any column
return d3.max(color.domain().map(function(n){ return +d[n]; }));
})
]);
您需要做的唯一其他更改是停止通过除以 100 来标准化数据:
var browsers = stack(color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {User_ID: d.User_ID, y: +d[name]}; // previously y: d[name]/100
})
};
}));
还有中提琴,这就是你得到的:
关于javascript - D3 可视化中的错误(堆积面积图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24418910/