我尝试使用此模板(内部的d3代码):
http://bl.ocks.org/mbostock/3885211#data.tsv
并使用我自己的数据更新数据。我遇到了一个问题,如下图所示:
如何将Axis正确设置为数据?
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
)
答案 0 :(得分:1)
正如您在问题中指出的那样,您的主要问题是设置域名。 x
域非常简单,您只想查找User_ID
s的最大值:
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
})
};
}));
和violá,这就是你得到的: