【问题标题】:Split D3 Graph Y Axis vertical color lines拆分 D3 图形 Y 轴垂直颜色线
【发布时间】:2017-07-23 10:47:12
【问题描述】:

我正在尝试拆分一些 D3 Graph Y 轴垂直彩色线。您可以在下图中看到当前的外观和外观:

到目前为止,我尝试的是为该 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);
}

【问题讨论】:

    标签: javascript html css d3.js


    【解决方案1】:

    你有两个问题:

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

    2. 您的foreignObjects 不在文本下方,它们实际上位于文本之上。在 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借用了用于在刻度中插入矩形的代码。

    【讨论】:

    • 此时,调试代码的唯一方法是提供MCVE
    • 我解决了这个问题。这是 d3 版本的东西。谢谢你的回答。
    猜你喜欢
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    相关资源
    最近更新 更多