首页 > 解决方案 > 如果刻度在图表内,如何在 d3js 中的轴刻度标签后面添加 svg 矩形作为背景

问题描述

我已经使用 d3 绘制了一个图表。然后将轴标签放在里面现在想要的是标签似乎不跨越刻度线。但它的标签背景应该是白色的。为此,我发现在 svg 中添加矩形仅适用。如果刻度在图表内,如何在 d3js 中的轴刻度标签后面添加 svg 矩形作为背景。

在此处输入图像描述

这是现有代码

<!DOCTYPE html>
<html>

<head>
  <meta name="description" content="With 0 removal">
  <title>
    D3.js | D3.axis.tickSizeInner() Function
  </title>

  <script type="text/javascript" src="https://d3js.org/d3.v5.min.js">
  </script>

  <style>
    svg text {
      fill: green;
      font: 15px sans-serif;
      text-anchor: center;
    }
  </style>
</head>

<body>
  <script>
    var width = 400,
      height = 400;
    const margin = 5;
    const padding = 5;
    const adj = 30;
    var svg = d3.select("body")
      .append("svg")
      .attr("preserveAspectRatio", "xMinYMin meet")
      .attr("viewBox", "-" +
        adj + " -" +
        adj + " " +
        (width + adj * 3) + " " +
        (height + adj * 3))
      .style("padding", padding)
      .style("margin", margin)
      .attr("width", width)
      .attr("height", height);

    var xscale = d3.scaleLinear()
      .domain([0, 10])
      .range([0, width]);
    var yscale = d3.scaleLinear()
      .domain([0, 1])
      .range([height, 0]);

    var x_axis = d3.axisBottom(xscale)
      .tickSizeInner(-(height))
      .tickSizeOuter(0);


    svg.append("g")
      .classed('axis axis-x', true)
      .attr("transform", "translate(0, " + height + ")")
      .call(x_axis)
      .selectAll(".tick text")
      .attr("transform", "translate(0,-20)");

    svg.select('.axis-x')
      .selectAll('.tick')
      .each(function(d) {
        console.log(d)
        if (Number(d) === 0) {
          d3.select(this).remove();
        }
      })





    var y_axis = d3.axisLeft(yscale)
      .tickSize(-width);

    svg.append("g")
      .classed('axis axis-y', true)
      .call(y_axis)
      .selectAll(".tick text")
      .attr("transform", "translate(30,0)");

    svg.select('.axis-y')
      .selectAll('.tick')
      .each(function(d) {
        console.log(d)
        if (Number(d) === 0) {
          d3.select(this).remove();
        }
      })
  </script>
</body>

</html>

JSBIN 的链接 https://jsbin.com/locosun/1/edit?html,output

标签: javascriptsvgd3.jschartsdata-visualization

解决方案


以下代码将为刻度标签添加白色背景:

    svg.select('.axis-y')
      .selectAll('g.tick')
      .insert('rect', 'text')
      .attr('x', 3)
      .attr('y', -10)
      .attr('width', 30)
      .attr('height', 20)
      .style('fill', 'white')
    
    svg.select('.axis-x')
      .selectAll('g.tick')
      .insert('rect', 'text')
      .attr('x', -15)
      .attr('y', -20)
      .attr('width', 30)
      .attr('height', 18)
      .style('fill', 'white')

<!DOCTYPE html>
<html>

<head>
  <meta name="description" content="With 0 removal">
  <title>
    D3.js | D3.axis.tickSizeInner() Function
  </title>

  <script type="text/javascript" src="https://d3js.org/d3.v5.min.js">
  </script>

  <style>
    svg text {
      fill: green;
      font: 15px sans-serif;
      text-anchor: center;
    }
  </style>
</head>

<body>
  <script>
    var width = 400,
      height = 400;
    const margin = 5;
    const padding = 5;
    const adj = 30;
    var svg = d3.select("body")
      .append("svg")
      .attr("preserveAspectRatio", "xMinYMin meet")
      .attr("viewBox", "-" +
        adj + " -" +
        adj + " " +
        (width + adj * 3) + " " +
        (height + adj * 3))
      .style("padding", padding)
      .style("margin", margin)
      .attr("width", width)
      .attr("height", height);

    var xscale = d3.scaleLinear()
      .domain([0, 10])
      .range([0, width]);
    var yscale = d3.scaleLinear()
      .domain([0, 1])
      .range([height, 0]);

    var x_axis = d3.axisBottom(xscale)
      .tickSizeInner(-(height))
      .tickSizeOuter(0);


    svg.append("g")
      .classed('axis axis-x', true)
      .attr("transform", "translate(0, " + height + ")")
      .call(x_axis)
      .selectAll(".tick text")
      .attr("transform", "translate(0,-20)");

    svg.select('.axis-x')
      .selectAll('.tick')
      .each(function(d) {
        console.log(d)
        if (Number(d) === 0) {
          d3.select(this).remove();
        }
      })





    var y_axis = d3.axisLeft(yscale)
      .tickSize(-width);

    svg.append("g")
      .classed('axis axis-y', true)
      .call(y_axis)
      .selectAll(".tick text")
      .attr("transform", "translate(30,0)");

    svg.select('.axis-y')
      .selectAll('.tick')
      .each(function(d) {
        console.log(d)
        if (Number(d) === 0) {
          d3.select(this).remove();
        }
      })

svg.select('.axis-y')
  .selectAll('g.tick')
  .insert('rect', 'text')
  .attr('x', 3)
  .attr('y', -10)
  .attr('width', 30)
  .attr('height', 20)
  .style('fill', 'white')

svg.select('.axis-x')
  .selectAll('g.tick')
  .insert('rect', 'text')
  .attr('x', -15)
  .attr('y', -20)
  .attr('width', 30)
  .attr('height', 18)
  .style('fill', 'white')

  </script>
</body>

</html>


推荐阅读