拆分D3图形Y轴垂直彩色线条

时间:2017-03-03 10:52:58

标签: javascript html css d3.js

我试图拆分一些D3 Graph Y Axis垂直彩色线条。您可以在下面的图像中看到当前外观及其外观:

enter image description here

我到目前为止所尝试的是为 g 元素设置背景颜色,因此该行不会显示在该特定区域但是它不起作用;我无法设置background-color: gray;的背景颜色。

为了更好地了解HTML标记,您可以在下面的图片中看到彩色线条D3 foreignObjects表示,它们位于 > 文本值

enter image description here

有没有人知道如何分割这些彩色线条?

更新

在我的案例中仍然不起作用。我尝试先渲染彩色线条然后再渲染文本值。这是我的代码:

//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); }

1 个答案:

答案 0 :(得分:0)

你有两个问题:

  1. 您无法设置<g>元素的样式。组只是容器元素。

  2. 您的foreignObject不在文本下面,它们实际上位于 文本上。在SVG中,后来被绘制的人保持在最顶层。因此,如果您检查DOM,底部的元素将在后面绘制并位于顶部“图层”,而顶部的元素将首先绘制并位于底部的“图层”中。

  3. 尽管如此,更简单的方法是选择所有.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的刻度中插入矩形。