我在Google上找到了一个垂直堆栈条形图示例 - http://bl.ocks.org/juan-cb/43f10523858abf6053ae 我想在水平堆积条形图中转换它。我做了改变,但有些事情是错的。图表不正确。我认为所有的栏都是重叠的。
请帮我解决这个问题。代码被复制。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
position: center;
}
text{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.toolTip {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
position: absolute;
display: none;
width: auto;
height: auto;
background: none repeat scroll 0 0 white;
border: 0 none;
border-radius: 8px 8px 8px 8px;
box-shadow: -3px 3px 15px #888888;
color: black;
font: 12px sans-serif;
padding: 5px;
text-align: center;
}
.legend {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 60%;
}
text {
font: 10px sans-serif;
}
.axis text {
font: 10px sans-serif;
}
.axis path{
fill: none;
stroke: #000;
}
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
</style>
<body>
<div class="barGraph" id='stacked-bar'></div>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.7.0/d3-legend.min.js"></script>
<script>
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
init();
function init(){
var dataset = [{
"goodRating": 27,
"avgRating": 21,
"badRating": 16,
"rooms": "0.01"
},
{
"goodRating": 26,
"avgRating": 22,
"badRating": 31,
"rooms": "0.02"
},
{
"goodRating": 100,
"avgRating": 0,
"badRating": 0,
"rooms": "1"
}];
var groupSpacing = 6;
var margin = {top: 10, right: 10, bottom: 60, left: 100},
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var y = d3.scaleBand()
.range([height, 0]);
var x = d3.scaleLinear()
.range([0, width], .1,.3);
// var colorRange = d3.scale.category20();
var color = d3.scaleOrdinal(d3.schemeCategory20);
var xAxis = d3.axisBottom(x).tickFormat(dataset.rooms),
yAxis = d3.axisLeft(y);
var svg = d3.select("#stacked-bar").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 + ")");
var divTooltip = d3.select("body").append("div").attr("class", "toolTip");
color.domain(d3.keys(dataset[0]).filter(function(key) { return key !== "rooms"; }));
dataset.forEach(function(d) {
var y0 = 0;
var y1 = 0;
d.values = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.values[d.values.length - 1].y1;
});
y.domain(dataset.map(function(d) { return d.rooms; }));
x.domain([0, d3.max(dataset, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".5em")
.attr("transform", "rotate(-65)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 9)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Satisfaction %");
var bar = svg.selectAll(".rooms")
.data(dataset)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + y(d.rooms) + ",0)"; });
svg.selectAll(".x.axis .tick text")
.call(wrap, y.bandwidth());
var bar_enter = bar.selectAll("rect")
.data(function(d) { return d.values; })
.enter();
bar_enter.append("rect")
.attr("height", y.bandwidth())
.attr("x", function(d) { return x(d.y1); })
.attr("width", function(d) { return x(d.y1) - x(d.y0) })
.style("fill", function(d) { return color(d.name); });
bar_enter.append("text")
.text(function(d) { return d3.format(".2s")(d.y1-d.y0)+"%"; })
.attr("x", function(d) { return x(d.y1)+(x(d.y0) - x(d.y1))/2; })
.attr("y", y.bandwidth()/3)
.style("fill", '#ffffff');
bar.on("mousemove", function(d){
divTooltip.style("left", d3.event.pageX+10+"px");
divTooltip.style("top", d3.event.pageY-25+"px");
divTooltip.style("display", "inline-block");
var elements = document.querySelectorAll(':hover');
l = elements.length
l = l-1
element = elements[l].__data__
value = element.y1 - element.y0
divTooltip.html("Room No : "+(d.rooms)+"<br>"+element.name+" : "+value+"%");
});
bar.on("mouseout", function(d){
divTooltip.style("display", "none");
});
}
</script>
</body>
此致 Pinki Sharma
答案 0 :(得分:1)
一些小事丢失/不正确:
包含条形图的组(stack path --local-bin
)被错误地转换(我猜你在从垂直堆叠变为水平时错过了这一点),即下一行
<g>
从左侧转换条形组,y位置为0,因此重叠。我已将此改为:
.attr("transform", function(d) { return "translate(" + y(d.rooms) + ",0)"; });
the rects&#39; x 值已从.attr("transform", function(d) { return "translate(0, " + y(d.rooms) + ")"; });
更改为x(d.y1)
(可能是拼写错误)
x(d.y0)
scaleBand()缺少轴填充。我已添加(请查看docs以获取更多信息)
bar_enter.append("rect")
.attr("height", y.bandwidth())
.attr("x", function(d) { return x(d.y0); })
重置边距以适应SVG尺寸:
var y = d3.scaleBand()
.rangeRound([height, 0]).padding(0.1);
结合上述所有内容,这里是您的代码集的一个分支:
HORIZONTAL STACKED BAR CHART DEMO
希望这有帮助。