如何创建水平条形堆栈并以不同方式对齐标签

时间:2014-10-02 18:57:48

标签: javascript graphics d3.js

我需要使用D3.js创建一个带有以下布局的图表

D3 Stackbar

正如您所看到的,我将标签正确对齐(分别是条形图的左右角)是困难的。

据我所知......



var cxNext, data, height, labelScale, margin, parentHeight, parentWidth, percentScale, svg, width, xScale;

parentWidth = document.body.clientWidth;

parentHeight = document.body.clientHeight;

margin = {
  top: 0,
  right: 0,
  bottom: 0,
  left: 0
};

width = parentWidth - margin.left - margin.right;

height = 700 - margin.top - margin.bottom;

data = [{
  label: "PRODUCT 1",
  percent: 0.5
}, {
  label: "PRODUCT 2",
  percent: 0.5
}];

xScale = d3.scale.linear().range([0, width]).domain([0, 100]);

labelScale = d3.scale.ordinal().domain(data.map(function(p) {
  return p.label;
})).rangeRoundBands([0, width]);

cxNext = 0;

data.forEach(function(d) {
  d.cx = cxNext;
  return cxNext = xScale(d.percent * 100);
});

percentScale = d3.scale.ordinal().domain(data.map(function(d) {
  return d.percent * 100 + "%";
})).rangeRoundBands([0, width]);

svg = d3.select("#chart").append("svg").attr({
  width: width + margin.left + margin.right,
  height: height + margin.top + margin.bottom
});

svg.selectAll(".bar").data(data).enter().append("rect").attr({
  "class": "bar",
  width: function(d) {
    return xScale(d.percent * 100);
  },
  height: height,
  x: function(d) {
    return d.cx;
  },
  y: function(d) {
    return 0;
  },
  fill: function(d, i) {
    return "rgb(0, " + ((i + 10) * 15) + ", 0)";
  }
});

svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + (height - 40) + ")").call(d3.svg.axis().scale(labelScale));


/*
svg.append("g")
    .attr("class", "x axis percent")
    .attr("transform", "translate(0," + (height-65) + ")")
    .call d3.svg.axis().scale(percentScale)
 */

.bar:hover { fill: green; }

.axis {
  font: 12px sans-serif;
  fill: white;
  font-weight: bold;
}
.percent { font: 20px sans-serif; }
.axis path, .axis line { fill: none; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

如果您只有两个条形图,那很简单 - 您需要做的就是设置坐标和文本锚点,具体取决于它是第一个还是第二个标签:

svg.selectAll("text").data(data).enter().append("text").attr({
  x: function(d, i) {
    return i == 1 ? d.cx + 10 : xScale(d.percent * 100) - 10;
  },
  "text-anchor": function(d, i) {
    return i == 1 ? "start" : "end";
  },
  y: height - 10
}).text(function(d) { return d.label ; });

完整演示here