toolkit/javascript/d3/examples/marimekko/marimekko.html
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 <!DOCTYPE html>
       
     2 <html>
       
     3   <head>
       
     4     <title>Marimekko Chart</title>
       
     5     <script type="text/javascript" src="../../d3.js"></script>
       
     6     <script type="text/javascript" src="../../d3.layout.js"></script>
       
     7     <style type="text/css">
       
     8 
       
     9 body {
       
    10   font: 10px sans-serif;
       
    11 }
       
    12 
       
    13 rect {
       
    14   stroke: #000;
       
    15 }
       
    16 
       
    17 svg {
       
    18   shape-rendering: crispEdges;
       
    19 }
       
    20 
       
    21     </style>
       
    22   </head>
       
    23   <body>
       
    24     <script type="text/javascript">
       
    25 
       
    26 var w = 960,
       
    27     h = 500,
       
    28     m = 20,
       
    29     x = d3.scale.linear().range([0, w - 3 * m]),
       
    30     y = d3.scale.linear().range([0, h - 2 * m]),
       
    31     z = d3.scale.category10(),
       
    32     n = d3.format(",d"),
       
    33     p = d3.format("%");
       
    34 
       
    35 var svg = d3.select("body").append("svg:svg")
       
    36     .attr("width", w)
       
    37     .attr("height", h)
       
    38   .append("svg:g")
       
    39     .attr("transform", "translate(" + 2 * m + "," + m + ")");
       
    40 
       
    41 d3.json("marimekko.json", function(data) {
       
    42   var offset = 0;
       
    43 
       
    44   // Nest values by segment. We assume each segment+market is unique.
       
    45   var segments = d3.nest()
       
    46       .key(function(d) { return d.segment; })
       
    47       .entries(data);
       
    48 
       
    49   // Compute the total sum, the per-segment sum, and the per-market offset.
       
    50   // You can use reduce rather than reduceRight to reverse the ordering.
       
    51   // We also record a reference to the parent segment for each market.
       
    52   var sum = segments.reduce(function(v, p) {
       
    53     return (p.offset = v) + (p.sum = p.values.reduceRight(function(v, d) {
       
    54       d.parent = p;
       
    55       return (d.offset = v) + d.value;
       
    56     }, 0));
       
    57   }, 0);
       
    58 
       
    59   // Add x-axis ticks.
       
    60   var xtick = svg.selectAll(".x")
       
    61       .data(x.ticks(10))
       
    62     .enter().append("svg:g")
       
    63       .attr("class", "x")
       
    64       .attr("transform", function(d) { return "translate(" + x(d) + "," + y(1) + ")"; });
       
    65 
       
    66   xtick.append("svg:line")
       
    67       .attr("y2", 6)
       
    68       .style("stroke", "#000");
       
    69 
       
    70   xtick.append("svg:text")
       
    71       .attr("y", 8)
       
    72       .attr("text-anchor", "middle")
       
    73       .attr("dy", ".71em")
       
    74       .text(p);
       
    75 
       
    76   // Add y-axis ticks.
       
    77   var ytick = svg.selectAll(".y")
       
    78       .data(y.ticks(10))
       
    79     .enter().append("svg:g")
       
    80       .attr("class", "y")
       
    81       .attr("transform", function(d) { return "translate(0," + y(1 - d) + ")"; });
       
    82 
       
    83   ytick.append("svg:line")
       
    84       .attr("x1", -6)
       
    85       .style("stroke", "#000");
       
    86 
       
    87   ytick.append("svg:text")
       
    88       .attr("x", -8)
       
    89       .attr("text-anchor", "end")
       
    90       .attr("dy", ".35em")
       
    91       .text(p);
       
    92 
       
    93   // Add a group for each segment.
       
    94   var segments = svg.selectAll(".segment")
       
    95       .data(segments)
       
    96     .enter().append("svg:g")
       
    97       .attr("class", "segment")
       
    98       .attr("xlink:title", function(d) { return d.key; })
       
    99       .attr("transform", function(d) { return "translate(" + x(d.offset / sum) + ")"; });
       
   100 
       
   101   // Add a rect for each market.
       
   102   var markets = segments.selectAll(".market")
       
   103       .data(function(d) { return d.values; })
       
   104     .enter().append("svg:a")
       
   105       .attr("class", "market")
       
   106       .attr("xlink:title", function(d) { return d.market + " " + d.parent.key + ": " + n(d.value); })
       
   107     .append("svg:rect")
       
   108       .attr("y", function(d) { return y(d.offset / d.parent.sum); })
       
   109       .attr("height", function(d) { return y(d.value / d.parent.sum); })
       
   110       .attr("width", function(d) { return x(d.parent.sum / sum); })
       
   111       .style("fill", function(d) { return z(d.market); });
       
   112 });
       
   113 
       
   114     </script>
       
   115   </body>
       
   116 </html>