javascript - 饼图未使用 d3.js 显示为响应式

标签 javascript css twitter-bootstrap d3.js responsive-design

我正在使用 d3.js 绘制动画饼图。饼图工作正常,但未显示为响应式。饼图的尺寸不随屏幕尺寸的变化而调整。 我尝试了使用 d3.js 的 Bootstrap,但是图表无法呈现为响应式。

代码如下:

Javascript:

var w = 583,
h = 500,
r = Math.min(w, h) / 2,
data = [{"label":"Yes:", "percentage":yes_percentage, "value":30}, {"label":"No:", "percentage":no_percentage, "value":70}],   // Data with label-value pairs
data2 = data.map(function(d) { return d.value})
color = d3.scale.category20(),
arc = d3.svg.arc().outerRadius(r),
donut = d3.layout.pie();

var vis = d3.select("#chart-1")
    .append("div")
    .classed("svg-container", true) //container class to make it responsive
    .append("svg")  // Place the chart in 'pie-chart-div'
    .attr("preserveAspectRatio", "xMinYMin meet")
    .attr("viewBox", "0 0 600 400")
    .classed("svg-content-responsive", true)
    .data([data])
    .text("hello")
    .attr("width", w)
    .attr("height", h);

var arcs = vis.selectAll("g.arc")
    .data(donut(data2))
  .enter().append("g")
    .attr("class", "arc")
    .attr("transform", "translate(" + r + "," + r + ")");

var paths = arcs.append("path")
    .attr("fill", function(d, i) { return color(i); });

var labels = arcs.append("text")
      .attr("transform", function(d) { d.innerRadius = 140; return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".85em")
      .text(function(d, i) { return data[i].label+"\n"+data[i].percentage; });


paths.transition()
    .ease("bounce")
    .duration(2000)
    .attrTween("d", tweenPie);

paths.transition()
    .ease("elastic")
    .delay(function(d, i) { return 2000 + i * 50; })
    .duration(750)
    .attrTween("d", tweenDonut);

function tweenPie(b) {
  b.innerRadius = 0;
  var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
  return function(t) {
    return arc(i(t));
  };
}

function tweenDonut(b) {
  b.innerRadius = r * .6;
  var i = d3.interpolate({innerRadius: 0}, b);
  return function(t) {
    return arc(i(t));
  };
}

CSS:

.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: 10px;
    left: 0;
}
.chart-style {
    float:left;
    margin:68px 0 0 0
}

HTML:

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="css/bootstrap.min.css">

  <script src="http://d3js.org/d3.v3.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>   
  <script src="js/jquery.min.js"></script>
  <script src="js/bootstrap.min.js"></script>

<div class="container"> <!-- Bootstrap container -->
    <div id="chart-1" class="chart-style"></div>
</div>


为什么图表没有以响应格式显示?

最佳答案

这里有几个问题:

1.) 首先,您要静态调整 svg 的大小元素:

  .attr("width", w)
  .attr("height", h);

这需要是一个百分比:

  .attr("width", '100%')
  .attr("height", '100%');

2.) 当你从 svg 走上树时所有父容器还必须具有百分比大小的宽度。 <div id="chart-1"没有,所以添加:

 .chart-style {
   float: left;
   margin: 68px 0 0 0;
   width: 100%;
 }

另外,你还有一个奇怪的.data调用没有意义的 svg 并产生损坏的 DOM。

运行代码:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link  data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <script data-semver="2.2.4" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
    <script data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>
    <style>
    .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: 10px;
      left: 0;
    }
    
    .chart-style {
      float: left;
      margin: 68px 0 0 0;
      width: 100%;
    }
  </style>
  </head>

  <body>
    <div class="container">
      <div id="chart-1" class="chart-style"></div>
    </div>
    <script>
    var w = 583,
      h = 500,
      r = Math.min(w, h) / 2,
      data = [{
        "label": "Yes:",
        "percentage": 25,
        "value": 30
      }, {
        "label": "No:",
        "percentage": 75,
        "value": 70
      }], // Data with label-value pairs
      data2 = data.map(function(d) {
        return d.value
      })
    color = d3.scale.category20(),
      arc = d3.svg.arc().outerRadius(r),
      donut = d3.layout.pie();

    var vis = d3.select("#chart-1")
      .append("div")
      .classed("svg-container", true) //container class to make it responsive
      .append("svg") // Place the chart in 'pie-chart-div'
      .attr("preserveAspectRatio", "xMinYMin meet")
      .attr("viewBox", "0 0 600 500")
      .classed("svg-content-responsive", true)
      //.data([data])
      //.text("hello")
      .attr("width", '100%')
      .attr("height", '100%');

    var arcs = vis.selectAll("g.arc")
      .data(donut(data2))
      .enter().append("g")
      .attr("class", "arc")
      .attr("transform", "translate(" + r + "," + r + ")");

    var paths = arcs.append("path")
      .attr("fill", function(d, i) {
        return color(i);
      });

    var labels = arcs.append("text")
      .attr("transform", function(d) {
        d.innerRadius = 140;
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".85em")
      .text(function(d, i) {
        return data[i].label + "\n" + data[i].percentage;
      });


    paths.transition()
      .ease("bounce")
      .duration(2000)
      .attrTween("d", tweenPie);

    paths.transition()
      .ease("elastic")
      .delay(function(d, i) {
        return 2000 + i * 50;
      })
      .duration(750)
      .attrTween("d", tweenDonut);

    function tweenPie(b) {
      b.innerRadius = 0;
      var i = d3.interpolate({
        startAngle: 0,
        endAngle: 0
      }, b);
      return function(t) {
        return arc(i(t));
      };
    }

    function tweenDonut(b) {
      b.innerRadius = r * .6;
      var i = d3.interpolate({
        innerRadius: 0
      }, b);
      return function(t) {
        return arc(i(t));
      };
    }
  </script>
  </body>

</html>

关于javascript - 饼图未使用 d3.js 显示为响应式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41039145/

相关文章:

javascript - nightwatch.js - 滚动直到元素可见

javascript - 你能检测用户是否处于 Chrome 的访客模式吗?

php - 显示 php css 属性的最有效方法

javascript - 固定位置在 IE 10 与 Bootstrap Modal 中的 Chrome 和 Firefox 中表现不同

html - 我应该在实际元素开发中使用基础吗?

javascript - 使用 .affix 和固定导航栏的侧边栏偏移

javascript - 使用 GitLab API 和 Node.js 下载 GitLab 存储库存档

javascript - AngularJS - 如果我不提交,如何保持原始值

css - 推特 Bootstrap : using submit form as drop down menu items?

javascript - 单选按钮和下拉菜单的对齐方式