2012-05-13 103 views
1

我目前正在尝试使用d3.js将此(mbostock.github.com/d3/ex/stack.html)垂直堆积条形图转换为水平堆叠条形图,但我没有运气。如果任何人有一个来自d3.js的横向堆叠条形图的例子,或者知道如何正确修改下面的代码,或者指向正确的方向,那将是一个很好的帮助。需要帮助使用d3.js创建堆积条形图

var margin = 20, 
width = 960, 
height = 500 - .5 - margin, 
mx = m, 
my = d3.max(data, function(d) { 
    return d3.max(d, function(d) { 
    return d.y0 + d.y; 
    }); 
}), 
mz = d3.max(data, function(d) { 
    return d3.max(d, function(d) { 
    return d.y; 
    }); 
}), 
x = function(d) { return d.x * width/mx; }, 
y0 = function(d) { return height - d.y0 * height/my; }, 
y1 = function(d) { return height - (d.y + d.y0) * height/my; }, 
y2 = function(d) { return d.y * height/mz; }; // or `my` to not rescale 

var vis = d3.select("#chart") 
.append("svg") 
.attr("width", width) 
.attr("height", height + margin); 

var layers = vis.selectAll("g.layer") 
.data(data) 
.enter().append("g") 
.style("fill", function(d, i) { return color(i/(n - 1)); }) 
.attr("class", "layer"); 

var bars = layers.selectAll("g.bar") 
.data(function(d) { return d; }) 
.enter().append("g") 
.attr("class", "bar") 
.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; }); 

bars.append("rect") 
.attr("width", x({x: .9})) 
.attr("x", 0) 
.attr("y", height) 
.attr("height", 0) 
.transition() 
.delay(function(d, i) { return i * 10; }) 
.attr("y", y1) 
.attr("height", function(d) { return y0(d) - y1(d); }); 

回答

-1

尝试弗兰克Guerino的例子: http://bl.ocks.org/2141479 - 水平条形图 和 http://bl.ocks.org/2354192 - 多D3从上到下和从下向上堆积条形图(不含d3.layout.stack) 结合水平代码克里米亚例子或多个D3自上而下的例子,你应该在你的轨道上。主要是你要寻找的是如何在水平设置中计算坐标。其余部分与其他堆栈示例相同。 此致敬礼!

+0

也看看这个:https://groups.google。 com/forum /#!searchin/d3-js/horizo​​ntal $ 20stack/d3-js/NnIK9weFbQg/gQhUQlNtdz4J – paxRoman

1

诀窍是:将它看作与垂直堆叠条形图几乎相同,但在堆叠之前将x和y值反转,然后再堆叠一次。请注意下面代码中的注释。

我的博客张贴这一点:http://datashaman.github.io/2014/01/26/horizontal-stacked-bar-chart-d3/

下面的代码演示的:http://bl.ocks.org/datashaman/8621955

的jsfiddle:http://jsfiddle.net/datashaman/rBfy5/2/

<!doctype html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <style> 
     .bar { 
     } 
     .axis path, 
     .axis line { 
      fill: none; 
      stroke: black; 
      shape-rendering: crispEdges; 
     } 
     .axis text { 
      font-family: sans-serif; 
      font-size: 11px; 
     } 

     #tooltip { 
      position: absolute; 
      text-align: center; 
      width: 40px; 
      height: auto; 
      padding: 10px; 
      background-color: white; 
      -webkit-border-radius: 10px; 
      -moz-border-radius: 10px; 
      border-radius: 10px; 
      -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
      pointer-events: none; 
     } 

     #tooltip.hidden { 
      display: none; 
     } 

     #tooltip p { 
      margin: 0; 
      font-family: sans-serif; 
      font-size: 16px; 
      line-height: 20px; 
     } 
     </style> 
    </head> 
    <body> 
     <script src="http://d3js.org/d3.v3.min.js"></script> 

     <div id="tooltip" class="hidden"> 
      <p><span id="value">100</span></p> 
     </div> 

     <script> 
     var margins = { 
       top: 12, 
       left: 48, 
       right: 24, 
       bottom: 24 
      }, 
      legendPanel = { 
       width: 240 
      }, 
      width = 700 - margins.left - margins.right - legendPanel.width, 
      height = 100 - margins.top - margins.bottom, 
      dataset = [ 
       { 
        data: [ 
         { month: 'Aug', count: 123 }, 
         { month: 'Sep', count: 234 }, 
         { month: 'Oct', count: 345 } 
        ], 
        name: 'Series #1' 
       }, 
       { 
        data: [ 
         { month: 'Aug', count: 235 }, 
         { month: 'Sep', count: 267 }, 
         { month: 'Oct', count: 573 } 
        ], 
        name: 'Series #2' 
       } 

      ], 
      series = dataset.map(function(d) { return d.name; }), 
      dataset = dataset.map(function(d) { 
       return d.data.map(function(o, i) { 
        // Structure it so that your numeric 
        // axis (the stacked amount) is y 
        return { 
         y: o.count, 
         x: o.month 
        }; 
       }); 
      }), 
      stack = d3.layout.stack(); 

     stack(dataset); 

     var dataset = dataset.map(function(group) { 
      return group.map(function(d) { 
       // Invert the x and y values, and y0 becomes x0 
       return { 
        x: d.y, 
        y: d.x, 
        x0: d.y0 
       }; 
      }); 
     }), 
     svg = d3.select('body') 
      .append('svg') 
       .attr('width', width + margins.left + margins.right + legendPanel.width) 
       .attr('height', height + margins.top + margins.bottom) 
      .append('g') 
       .attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'), 
     xMax = d3.max(dataset, function(group) { 
      return d3.max(group, function(d) { 
       return d.x + d.x0; 
      }); 
     }), 
     xScale = d3.scale.linear() 
      .domain([0, xMax]) 
      .range([0, width]), 
     months = dataset[0].map(function(d) { return d.y; }), 
     _ = console.log(months), 
     yScale = d3.scale.ordinal() 
      .domain(months) 
      .rangeRoundBands([0, height], .1), 
     xAxis = d3.svg.axis() 
      .scale(xScale) 
      .orient('bottom'), 
     yAxis = d3.svg.axis() 
      .scale(yScale) 
      .orient('left'), 
     colours = d3.scale.category10(), 
     groups = svg.selectAll('g') 
      .data(dataset) 
      .enter() 
      .append('g') 
       .style('fill', function(d, i) { 
        return colours(i); 
       }), 
     rects = groups.selectAll('rect') 
      .data(function(d) { return d; }) 
      .enter() 
       .append('rect') 
        .attr('x', function(d) { return xScale(d.x0); }) 
        .attr('y', function(d, i) { return yScale(d.y); }) 
        .attr('height', function(d) { return yScale.rangeBand(); }) 
        .attr('width', function(d) { return xScale(d.x); }) 
        .on('mouseover', function(d) { 
         var xPos = parseFloat(d3.select(this).attr('x'))/2 + width/2; 
         var yPos = parseFloat(d3.select(this).attr('y')) + yScale.rangeBand()/2; 

         d3.select('#tooltip') 
          .style('left', xPos + 'px') 
          .style('top', yPos + 'px') 
          .select('#value') 
          .text(d.x); 

         d3.select('#tooltip').classed('hidden', false); 
        }) 
        .on('mouseout', function() { 
         d3.select('#tooltip').classed('hidden', true); 
        }) 

     svg.append('g') 
      .attr('class', 'axis') 
      .attr('transform', 'translate(0,' + height + ')') 
      .call(xAxis); 

     svg.append('g') 
      .attr('class', 'axis') 
      .call(yAxis); 

     svg.append('rect') 
      .attr('fill', 'yellow') 
      .attr('width', 160) 
      .attr('height', 30 * dataset.length) 
      .attr('x', width + margins.left) 
      .attr('y', 0); 

     series.forEach(function(s, i) { 
      svg.append('text') 
       .attr('fill', 'black') 
       .attr('x', width + margins.left + 8) 
       .attr('y', i * 24 + 24) 
       .text(s); 
      svg.append('rect') 
       .attr('fill', colours(i)) 
       .attr('width', 60) 
       .attr('height', 20) 
       .attr('x', width + margins.left + 90) 
       .attr('y', i * 24 + 6); 
     }); 
    </script> 
</body> 
</html> 
+0

如何在此图表上进行排序 –