d3.js如何向Marimekko图表添加文本

时间:2014-04-09 15:30:54

标签: javascript d3.js marimekko-chart

我正在尝试将文字添加到正在运行的Marimekko图表中。我知道向rect添加文本需要rect和text需要在一个组中。但是我用作基础的代码已经使用了一个组。这是我的主要问题,但我也想让x轴显示月份而不是%值。 对于marimekko图表,这个任务是不可能完成的吗?

<div id="chart">&nbsp;</div>
<div id="legend">&nbsp;</div>
<script>

var width = 800,
height = 500,
margin = 20;

var color = d3.scale.category10();

var x = d3.scale.linear()
.range([0, width - 3 * margin]);

var y = d3.scale.linear()
.range([0, height - 2 * margin]);

var n = d3.format(",d"),
p = d3.format("%");

var svg = d3.select("#chart") .append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 2 * margin + "," + margin + ")");

d3.json("/mydrupal/sites/default/d3_files/json/marimekko6.json", function(error,data) {
var offset = 0;

// Nest values by month. We assume each month + cause is unique.
var months = d3.nest()
  .key(function(d) { 
     return d.month; 
     })
  .entries(data);

// Compute the total sum, the per-month sum, and the per-cause offset.
// You can use reduce rather than reduceRight to reverse the ordering.
// We also record a reference to the parent cause for each month.
var sum = months.reduce(function(v, p) {
return (p.offset = v) + (p.sum = p.values.reduceRight(function(v, d) {
    d.parent = p;
    return (d.offset = v) + d.deaths;
    }, 0));
}, 0);

// Add x-axis ticks.
var xtick = svg.selectAll(".x")
  .data(x.ticks(10))
.enter().append("g")
  .attr("class", "x")
  .attr("transform", function(d) { 
     return "translate(" + x(d) + "," + y(1) + ")"; 
     });
xtick.append("line")
  .attr("y2", 6)
  .style("stroke", "#000");
xtick.append("text")
  .attr("y", 8)
  .attr("text-anchor", "middle")
  .attr("dy", ".71em")
  .text(p);

// Add y-axis ticks.
var ytick = svg.selectAll(".y")
  .data(y.ticks(10))
.enter().append("g")
  .attr("class", "y")
  .attr("transform", function(d) { 
     return "translate(0," + y(1 - d) + ")"; 
   });
ytick.append("line")
  .attr("x1", -6)
  .style("stroke", "#000");
ytick.append("text")
  .attr("x", -8)
  .attr("text-anchor", "end")
  .attr("dy", ".35em")
  .text(p);

// Add a group for each cause.
var months = svg.selectAll(".month")
  .data(months)
.enter().append("g")
  .attr("class", "month")
  .attr("xlink:title", function(d) { return d.key; })
  .attr("transform", function(d) { 
     return "translate(" + x(d.offset / sum) + ")"; 
   });

// Add a rect for each month.
 var causes = months.selectAll (".cause")
  .data(function(d) { return d.values; })
.enter().append("a")
  .attr("class", "month")
  .attr("xlink:title", function(d) { return d.cause + " " + d.parent.key + ": " + n(d.deaths); })
.append("rect")
  .attr("y", function(d) { 
     return y(d.offset / d.parent.sum); })
  .attr("height", function(d) { 
     return y(d.deaths / d.parent.sum); })
  .attr("width", function(d) { 
     return x(d.parent.sum / sum); })
  .style("fill", function(d) { 
     return color(d.cause); 
  });

});

</script>

1 个答案:

答案 0 :(得分:0)

如上所述:

<!--HTML-->
<p>Marimekko Chart see http://bl.ocks.org/mbostock/1005090</p>
<div id="chart">&nbsp;</div>

<!--CSS-->
<style type="text/css">body {
  font: 10px sans-serif;
}

rect {
stroke: #000;
}

.label {
  font-size: 12px;
  fill: white;
}

.label2 {
  font-size: 14px;
  fill: black;
}

svg {
  shape-rendering: crispEdges;
}

#chart {
margin-bottom: 20px;
}
</style>

<!--JavaScript-->
<script>

var width = 700,
height = 500,
margin = 20;

var color = d3.scale.category20();

var x = d3.scale.linear()
 .range([0, width - 3 * margin]);

var y = d3.scale.linear()
 .range([0, height - 2 * margin]);

var n = d3.format(",d"),
 p = d3.format("%");

var svg = d3.select("#chart") .append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + 2 * margin + "," + margin + ")");

d3.json("/mydrupal/sites/default/d3_files/json/marimekko6.json", function(error,data) {
var offset = 0;

// Nest values by month. We assume each month + cause is unique.
var months = d3.nest()
  .key(function(d) { 
     return d.month; 
     })
  .entries(data);

// Compute the total sum, the per-month sum, and the per-cause offset.
// You can use reduce rather than reduceRight to reverse the ordering.
// We also record a reference to the parent cause for each month.
var sum = months.reduce(function(v, p) {
return (p.offset = v) + (p.sum = p.values.reduceRight(function(v, d) {
    d.parent = p;
    return (d.offset = v) + d.deaths;
    }, 0));
}, 0);

// Add a group for each cause.
var months = svg.selectAll(".month")
  .data(months)
.enter().append("g")
  .attr("class", "month")
  .attr("xlink:title", function(d) { 
     return d.key; })
  .attr("transform", function(d) { 
     return "translate(" + x(d.offset / sum) + ")"; 
   });

// Add a rect for each month.
 var causes = months.selectAll (".cause")
  .data(function(d) { 
     return d.values; })
.enter().append("a")
  .attr("class", "month")
  .attr("xlink:title", function(d) { 
      return d.cause + " " + d.parent.key + ": " + n(d.deaths); });

causes.append("rect")
  .attr("y", function(d) { 
     return y(d.offset / d.parent.sum); })
  .attr("height", function(d) { 
     return y(d.deaths / d.parent.sum); })
  .attr("width", function(d) { 
     return x(d.parent.sum / sum); })
  .style("fill", function(d) { 
     return color(d.cause); 
  });

// http://stackoverflow.com/questions/17574621/text-on-each-bar-of-a-stacked-bar-chart-d3-js
causes.append("text")
      .text(function(d) { 
          return d.cause + " " + n(d.deaths);})
      .attr("x", 5)
      .attr("y", function(d) { 
          return (y(d.offset / d.parent.sum)+20); })
      .attr("class", "label")
;
causes.append("text")
      .text(function(d) { 
          return (" Total: " + d.parent.sum);}) // total
      .attr("x", 5)
      .attr("y", function(d) { 
            return 450 })
      .attr("class", "label2")
;
causes.append("text")
      .text(function(d) { 
          return d.parent.key;}) // month
      .attr("x", 5)
      .attr("y", function(d) { 
            return 480; })
      .attr("class", "label2")
;
});
</script>