D3可视化出错(堆积面积图)

时间:2014-06-25 21:29:09

标签: javascript d3.js

我尝试使用此模板(内部的d3代码): http://bl.ocks.org/mbostock/3885211#data.tsv 并使用我自己的数据更新数据。我遇到了一个问题,如下图所示: enter image description here

如何将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

1 个答案:

答案 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á,这就是你得到的:

stacked bar graph made after incorporating the changes from my answer