d3.js轴标签不显示在响应条形图中

时间:2017-09-26 12:55:44

标签: css d3.js svg

我创建了codepen来证明我的问题。基本上,我的轴标签正在成功创建,并被添加到DOM但它们没有显示,因为它们被绘制在图表区域之外。

这是我的CSS:

.promo {
  fill: rgba(255,0,0,0.5);
}

.price {
  fill: $brand-primary;
}

.chart {
  height: 50vh;
  width: 100%;
  overflow: hidden;
}

.svg-container {
    display: inline-block;
    position: relative;
    width: 100%;
    padding-bottom: 100%; /* aspect ratio */
    vertical-align: top;
    overflow: hidden;
}
.svg-content-responsive {
    display: inline-block;
    position: absolute;
    top: 0;
    left: 0;
}

我的JS:

let height = $('.chart').height();
let width = $('.chart').width();

let chart = d3.select('.chart')
    .append("div")
    .classed("svg-container", true) //container class to make it responsive
    .append("svg")
    .attr('preserveAspectRatio','xMinYMax meet')
    .attr('viewBox','0 0 '+width +' '+height )
    .classed("svg-content-responsive", true)
    .append('g');
    //.attr("transform", "translate(50 0)");

let tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function(d) {
              let date = new Date(d[0]);
              let year = date.getFullYear();
              let allMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
              let month = allMonths[date.getMonth()];
              return `<strong>$${d[1]} Billion</strong><br>${year} - ${month}`;
            });

chart.call(tip);

let x = d3.scaleTime().range([0, width]);

let y = d3.scaleLinear().rangeRound([height, 0]);

d3.json("https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json", function(response) {
  let data = response.data;

  x.domain([new Date(data[0][0]), new Date(data[data.length-1][0])]);
  y.domain([0, d3.max(data, function(d) { return d[1]; })]);

  let barWidth = width / data.length;

  chart.append("g")
      .attr("class", "axis x")
      .attr("transform", "translate(0,"+(height)+")")
      .call(d3.axisBottom(x).ticks(10));

  chart.append("g")
      .attr("class", "axis y")
      .call(d3.axisLeft(y).ticks(10));
  chart.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Gross Domestic Product, USA");

  //here x is already the x axis time scale you have defined in your code
  var left = x(new Date("Jun 3 1980"));
  var right = x(new Date("Apr 22 2013")); //one more day
  var wid = right - left;
  chart.append("rect")
    .attr("x", left)
    .attr("width", wid)
    .attr('class', 'promo' )
    .attr("height", height);

  let bar = chart.selectAll('.bar')
                  .data(data)
                  .enter();

  bar.append('rect')
     .attr('class', 'price')
     .attr('x', function(d, i) {
        return (i*barWidth);
      })
     .attr('y', function(d) { return y(d[1]); })
     .attr("height", function(d) { return height - y(d[1]); })
     .attr("width", barWidth)
     .on('mouseover', tip.show)
     .on('mouseout', tip.hide);
});

我遇到的解决方案涉及具有特定像素大小的图表,并为这些图表添加边距,以便轴标签占据此空间。实际上,对于响应大小的图表(100%宽度和视口高度的50%),这种方法是不可能的。

如何根据需要显示标签?

1 个答案:

答案 0 :(得分:0)

我在上面的图表上几乎没有观察到。 SVG高度和x轴从相同位置开始。因此轴的可见性将被隐藏,因为轴刻度和文本来自svg视图框。您可以考虑transform属性并正确定位元素。 JSFiddle

x轴定位

chart.append("g")
      .attr("class", "axis x")
      .attr("transform", "translate(0,"+(height -20)+")")
      .call(d3.axisBottom(x).ticks(10));

矩形分组和定位

   var bar_g = chart.append("g")
   .attr('class','rectg')
   .attr("transform", "translate(0,"+(-20)+")");