我试图拆分一些D3 Graph Y Axis垂直彩色线条。您可以在下面的图像中看到当前外观及其外观:
我到目前为止所尝试的是为 g 元素设置背景颜色,因此该行不会显示在该特定区域但是它不起作用;我无法设置background-color: gray;
的背景颜色。
为了更好地了解HTML标记,您可以在下面的图片中看到彩色线条用D3 foreignObjects
表示,它们位于 > 文本值。
有没有人知道如何分割这些彩色线条?
更新
在我的案例中仍然不起作用。我尝试先渲染彩色线条然后再渲染文本值。这是我的代码:
//Add colored lines
this.graph.append("foreignObject")
.attr("id", "legendBackground" + segmentId)
.attr("class", "legendBackground")
.attr("height", this.graphHeight)
.attr("width", "2")
.attr("y", 0)
.attr('x', xOffset + 11)
.style('background-color', (d) => this.colors(segmentId));
this.updateLegend();
//Add text values
var yScale = this.getYScale(domain);
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(value)
.tickFormat(d3.format(".1f"))
.tickPadding(this.isSmallScreen ? 6 : 12)
.orient("left");
/** If there is already an xAxis then update this one, do not redraw from scratch */
if (!this.graph.select(".y.axis" + (secondary ? "2" : "")).empty()) {
var t0 = this.graph.select(".y.axis" + (secondary ? "2" : ""))
.attr("transform", "translate(" + (secondary ? ( this.primaryAxis.width + this.padding.left + this.secondaryAxis.width + this.axisSpacing ) : ( this.primaryAxis.width + this.padding.left )) + ",0)")
.transition()
.call(yAxis);
} else {
var t0 = this.graph.insert("svg:g",":first-child")
.attr("class", secondary ? "y axis2" : "y axis")
.attr("transform", "translate(" + (secondary ? ( this.primaryAxis.width + this.padding.left + this.secondaryAxis.width + this.axisSpacing ) : ( this.primaryAxis.width + this.padding.left )) + ",0)")
.transition()
.call(yAxis);
}
//Add colored lines
this.graph.append("foreignObject")
.attr("id", "legendBackground" + segmentId)
.attr("class", "legendBackground")
.attr("height", this.graphHeight)
.attr("width", "2")
.attr("y", 0)
.attr('x', xOffset + 11)
.style('background-color', (d) => this.colors(segmentId));
this.updateLegend();
//Add text values
var yScale = this.getYScale(domain);
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(value)
.tickFormat(d3.format(".1f"))
.tickPadding(this.isSmallScreen ? 6 : 12)
.orient("left");
/** If there is already an xAxis then update this one, do not redraw from scratch */
if (!this.graph.select(".y.axis" + (secondary ? "2" : "")).empty()) {
var t0 = this.graph.select(".y.axis" + (secondary ? "2" : ""))
.attr("transform", "translate(" + (secondary ? ( this.primaryAxis.width + this.padding.left + this.secondaryAxis.width + this.axisSpacing ) : ( this.primaryAxis.width + this.padding.left )) + ",0)")
.transition()
.call(yAxis);
} else {
var t0 = this.graph.insert("svg:g",":first-child")
.attr("class", secondary ? "y axis2" : "y axis")
.attr("transform", "translate(" + (secondary ? ( this.primaryAxis.width + this.padding.left + this.secondaryAxis.width + this.axisSpacing ) : ( this.primaryAxis.width + this.padding.left )) + ",0)")
.transition()
.call(yAxis);
}
答案 0 :(得分:0)
你有两个问题:
您无法设置<g>
元素的样式。组只是容器元素。
您的foreignObject
不在文本下面,它们实际上位于 文本上。在SVG中,后来被绘制的人保持在最顶层。因此,如果您检查DOM,底部的元素将在后面绘制并位于顶部“图层”,而顶部的元素将首先绘制并位于底部的“图层”中。
尽管如此,更简单的方法是选择所有.tick
组并在之前插入矩形(即,在文本下)。当然,要实现这一点,请记住在(再次,它意味着在)轴之前绘制行,就像在下面的演示中一样。
以下是演示:
var svg = d3.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 300);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var lines = svg.selectAll("foo")
.data([1,1])
.enter()
.append("line")
.attr("y1", 0)
.attr("y2", 500)
.attr("x1", (d,i)=>100 + i*8)
.attr("x2", (d,i)=>100 + i*8)
.attr("stroke-width", 2)
.attr("stroke", (d,i)=>color(i));
var scale = d3.scalePoint()
.domain(d3.range(62,78,2))
.range([10,290]);
var gY = svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(126,0)").call(d3.axisLeft(scale).tickFormat(d=>d3.format(".1f")(d)));
d3.selectAll(".tick").each(function(d,i){
var tick = d3.select(this),
text = tick.select("text"),
bBox = text.node().getBBox();
tick.insert("rect", ":first-child")
.attr("x", bBox.x - 3)
.attr("y", bBox.y - 3)
.attr("height", bBox.height + 6)
.attr("width", bBox.width + 6)
.style("fill", "white");
});
.tick text{
font-size: 14px;
}
.axis path, .axis line{
stroke: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
PS:我借用了代码,用于在this answer的刻度中插入矩形。