我尝试了不同的方法来在每个栏中提供文本标签的背景,以使其更加可见。但是我无法为堆栈条中的每个文本标签添加背景,也无法将每个条的总数添加为背景,因此我想将其附加到每个堆栈条上方,作为[总计:250]。
在下图中,您可以看到灰色矩形区域,我尝试将其设置为文本背景,但失败了。我是D3.js的新手,真的很难实现它。请帮我解决这个问题。
<html>
<head>
<script src="https://d3js.org/d3.v3.min.js" type="text/javascript"></script>
<style>
.textRect {
fill: white;
stroke: none;
}
text {
font-family: Helvetica, Arial, sans-serif;
font-weight: bold;
font-size: 12px;
}
</style>
</head>
<body style="width: 98%; background-color: white">
<div id="ashu" style="width: 700px; height:400px; padding-top: 50px;"></div>
<script>
var data = [{
"health": "JAN",
"val1": 1,
"val2": 67,
"val3": 13,
"val4": 15
}, {
"health": "FEB",
"val1": 60,
"val2": 9,
"val3": 20,
"val4": 5
}, {
"health": "MAR",
"val1": 40,
"val2": 22,
"val3": 21,
"val4": 99
}, {
"health": "APR",
"val1": 60,
"val2": 1,
"val3": 99,
"val4": 90
}, {
"health": "MAY",
"val1": 2,
"val2": 27,
"val3": 43,
"val4": 82
}, {
"health": "JUN",
"val1": 17,
"val2": 52,
"val3": 79,
"val4": 9
}, {
"health": "JUL",
"val1": 37,
"val2": 24,
"val3": 35,
"val4": 51
}, {
"health": "AUG",
"val1": 16,
"val2": 17,
"val3": 53,
"val4": 38
}, {
"health": "SEP",
"val1": 15,
"val2": 32,
"val3": 5,
"val4": 31
}];
let xData = d3.keys(data[0]);
const yData = xData.shift();
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var margin = {
top: 20,
right: 50,
bottom: 30,
left: 50
},
width = 400,
height = 300,
padding = 100;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var y_axis = d3.svg.axis().scale(y).orient("left").ticks(6).innerTickSize(-width)
.tickPadding(10);
var svg = d3.select("#ashu").append("svg").attr("width",
"100%").attr("height",
"100%").append("g").attr(
"transform",
"translate(" + margin.left + "," + margin.top + ")");
var dataIntermediate = xData.map(function(c) {
return data.map(function(d, yData) {
return {
x: d[Object.keys(d)[0]],
y: d[c]
};
});
});
var chu = 0;
var totals = d3.nest()
.key(function(d) {
return d.health;
})
.rollup(function(d) {
return d3.sum(d, function(g) {
return g.val1 + g["val2"] + g.val3 + g.val4;
});
})
.entries(data);
var dataStackLayout = d3.layout.stack()(dataIntermediate);
x.domain(dataStackLayout[0].map(function(d) {
return d.x;
}));
var total = 0;
var maximumY = d3.max(dataStackLayout[dataStackLayout.length - 1], function(d) {
return (d.y + d.y0);
});
y.domain([0, maximumY]).nice();
var layer1 = svg.selectAll(".stack1").data(dataStackLayout).enter()
.append("g").attr("class", "stack1").style("fill",
function(d, i) {
return color(i);
});
layer1.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x(d.x);
})
.attr("y", function(d) {
return y(d.y + d.y0);
})
.attr("height", function(d) {
return y(d.y0) - y(d.y + d.y0);
})
.attr("width", x.rangeBand());
var layer2 = svg.selectAll(".stack2").data(dataStackLayout).enter()
.append("g")
.attr("class", "stack2")
.style("fill", "black");
layer2.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "textRect")
.attr("x", function(d, i) {
return x(d.x) + (x.rangeBand()) / 2 - (this.getBBox().width / 2);
})
.attr("y", function(d) {
return y(d.y0 + (d.y / 2)) - (this.getBBox().height / 2);
}).attr("height", function(d) {
return d.y0 / 2 - (this.getBBox().width / 2);
})
.attr("width", function(d) {
return d.y0 / 2 - (this.getBBox().height / 2);
})
.style("opacity", "0.6")
.style("fill", "grey");
var textLabel = layer2.selectAll("text")
.data(function(d) {
return d;
})
.enter()
.append("text")
.text(function(d) {
return d.y;
})
.attr("x", function(d, i) {
return x(d.x) + (x.rangeBand()) / 2;
})
.attr("y", function(d) {
return y(d.y0 + (d.y / 2));
})
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.style("fill", "white");
/* var bbox = textLabel.each(function() {
return this.getBBox();// get bounding box of text field and store it in texts array
});
console.log(bbox);
var paddingLeftRight = 18; // adjust the padding values depending on font and font size
var paddingTopBottom = 5;
var rectLabel = layer2.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "textRect")
.attr("x", function(d) { d.x.x - d.x.width/2 - paddingLeftRight/2; })
.attr("y", function(d) { d.y.y - d.y.height + paddingTopBottom/2; })
.attr("width", function(d) { return d.y.width + paddingLeftRight; })
.attr("height", function(d) { return d.y.height + paddingTopBottom; }).style("fill", "#ccc")
.style("fill-opacity", ".3")
.style("stroke", "#666")
.style("stroke-width", "1.5px");
*/
svg.append("g").attr("class", "axis").attr("transform",
"translate(0," + height + ")").call(xAxis);
svg.append("g").attr("class", "y axis").attr("transform", "translate(0,0)").call(y_axis);
var legend = svg.selectAll(".legend")
.data(color.domain().slice())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
return "translate(0," + Math.abs((i - 8) * 20) + ")";
});
legend.append("rect")
.attr("x", width + 10)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("class", "legendText")
.attr("x", width + 32)
.attr("y", 10)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d, i) {
return xData[i];
});
</script>
</body>
</html>