首页 > 解决方案 > D3 V4如何强制堆叠条的标签对小条可见?请回复我真的很努力

问题描述

完成工作,非常有帮助。

标签: d3.js

解决方案


由于 g 元素在 DOM 中创建的顺序,标签被隐藏,因为稍后创建的元素将与之前创建的元素重叠。这意味着 SPV/ASSETBACKED 的橙色矩形将隐藏 INSOLVENCIES 组标签。

一个解决方案是为您的标签创建新的 g 元素,因此它们始终出现在您的矩形之上。请参阅下面的片段。

现在,如果您的值很小,那么在放置标签的位置总是会遇到挑战。该片段将它们放在栏的中间,但您可能需要使用它

var data = [{
      "health": "JAN",
      "INSOLVENCIES": 1,
      "SPV/ASSETBACKED": 67,
      "OPERATINGCOMPANIES": 13,
      "Bank": 15
    }, {
      "health": "FEB",
      "INSOLVENCIES": 60,
      "SPV/ASSETBACKED": 9,
      "OPERATINGCOMPANIES": 20,
      "Bank": 5
    }, {
      "health": "MAR",
      "INSOLVENCIES": 40,
      "SPV/ASSETBACKED": 22,
      "OPERATINGCOMPANIES": 21,
      "Bank": 99
    }, {
      "health": "APR",
      "INSOLVENCIES": 60,
      "SPV/ASSETBACKED": 1,
      "OPERATINGCOMPANIES": 99,
      "Bank": 90
    }, {
      "health": "MAY",
      "INSOLVENCIES": 2,
      "SPV/ASSETBACKED": 27,
      "OPERATINGCOMPANIES": 43,
      "Bank": 82
    }, {
      "health": "JUN",
      "INSOLVENCIES": 17,
      "SPV/ASSETBACKED": 52,
      "OPERATINGCOMPANIES": 79,
      "Bank": 9
    }, {
      "health": "JUL",
      "INSOLVENCIES": 37,
      "SPV/ASSETBACKED": 24,
      "OPERATINGCOMPANIES": 35,
      "Bank": 51
    }, {
      "health": "AUG",
      "INSOLVENCIES": 16,
      "SPV/ASSETBACKED": 17,
      "OPERATINGCOMPANIES": 53,
      "Bank": 38
    }, {
      "health": "SEP",
      "INSOLVENCIES": 15,
      "SPV/ASSETBACKED": 32,
      "OPERATINGCOMPANIES": 5,
      "Bank": 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 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", "stack").style("fill",
        function(d, i) {
          return color(i);
        });
    
    var layer2 = svg.selectAll(".stack2").data(dataStackLayout).enter()
      .append("g")
    	.attr("class", "stack")
      .style("fill", "black");

    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())
      .on("mouseover", function(d) {
        div.transition()
          .duration(200)
          .style("opacity", .9);
        div.html("Total : " + (d.y + d.y0))
          .style("left", (d3.event.pageX) + "px")
          .style("top", (d3.event.pageY - 28) + "px");
      })
      .on("mouseout", function(d) {
        div.transition()
          .duration(500)
          .style("opacity", 0);
      });

    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", "black");


    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("x", width + 32)
      .attr("y", 10)
      .attr("dy", ".35em")
      .style("text-anchor", "start")
      .text(function(d, i) {
        return xData[i];
      });
svg {
      font: 10px sans-serif;
      shape-rendering: crispEdges;
    }

    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
    }

    path.domain {
      stroke: none;
    }

    .y .tick line {
      stroke: #ddd;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

<div id="ashu" style="width: 700px; height:400px;"></div>


推荐阅读