【问题标题】:How to make a chord responsive如何使和弦响应
【发布时间】:2016-05-04 10:28:00
【问题描述】:

我正在尝试为一个项目开发 d3js 和弦。我可以渲染图表,但我有一些问题要让它在网页中响应。 简而言之,我想将我的图表绑定到一个与引导模板连接的 div 'chartContainer'。

这是一段代码:

<div class="row">
    <div class="col-xs-12">
        <div id="chartContainer">

          <div id="tooltip"></div>
          <!--<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
          <script src="js/d3.min.js" charset="utf-8"></script>
          <script src="js/underscore.js"></script>
          <script src="js/mapper.js"></script>
          <script>
            //*******************************************************************
            //  CREATE MATRIX AND MAP
            //*******************************************************************



            d3.csv('trade-a.csv', function (error, data) {
              var mpr = chordMpr(data);

              mpr
                .addValuesToMap('seller')
                .addValuesToMap('buyer')
                .setFilter(function (row, a, b) {
                  return (row.seller === a.name && row.buyer === b.name) ||
                         (row.seller === b.name && row.buyer === a.name)
                })
                .setAccessor(function (recs, a, b) {
                  if (!recs[0]) return 0;
                    return recs[0].seller === a.name ? +recs[0].flow1 : +recs[0].flow2; 
                });
              drawChords(mpr.getMatrix(), mpr.getMap());
            });
            //*******************************************************************
            //  DRAW THE CHORD DIAGRAM
            //*******************************************************************


            function drawChords (matrix, mmap) {
              var w = 980, h = 800, r1 = h / 2, r0 = r1 - 110;

              //Qui i settaggi della scala dei colori vedere anche https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors
              var fill = d3.scale.ordinal()
                  .range(['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928']);

              var chord = d3.layout.chord()
                  .padding(.02)
                  .sortSubgroups(d3.descending)
                  .sortChords(d3.descending);

              var arc = d3.svg.arc()
                  .innerRadius(r0)
                  .outerRadius(r0 + 20);

              var svg = d3.select("body").append("svg:svg")
                  .attr("width", w)
                  .attr("height", h)
                .append("svg:g")
                  .attr("id", "circle")
                  .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

                  svg.append("circle")
                      .attr("r", r0 + 20);

              var rdr = chordRdr(matrix, mmap);
              chord.matrix(matrix);

              var g = svg.selectAll("g.group")
                  .data(chord.groups())
                .enter().append("svg:g")
                  .attr("class", "group")
                  .on("mouseover", mouseover)
                  .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });

              g.append("svg:path")
                  .style("stroke", "black")
                  .style("fill", function(d) { return fill(rdr(d).gname); })
                  .attr("d", arc);

              g.append("svg:text")
                  .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
                  .attr("dy", ".35em")
                  .style("font-family", "helvetica, arial, sans-serif")
                  .style("font-size", "9px")
                  .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
                  .attr("transform", function(d) {
                    return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
                        + "translate(" + (r0 + 26) + ")"
                        + (d.angle > Math.PI ? "rotate(180)" : "");
                  })
                  .text(function(d) { return rdr(d).gname; });

                var chordPaths = svg.selectAll("path.chord")
                      .data(chord.chords())
                    .enter().append("svg:path")
                      .attr("class", "chord")
                      .style("stroke", function(d) { return d3.rgb(fill(rdr(d).sname)).darker(); })
                      .style("fill", function(d) { return fill(rdr(d).sname); })
                      .attr("d", d3.svg.chord().radius(r0))
                      .on("mouseover", function (d) {
                        d3.select("#tooltip")
                          .style("visibility", "visible")
                          .html(chordTip(rdr(d)))
                          .style("top", function () { return (d3.event.pageY - 170)+"px"})
                          .style("left", function () { return (d3.event.pageX - 100)+"px";})
                      })
                      .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });

              //Settaggi della tooltip del gruppo
                function chordTip (d) {
                  var p = d3.format(".1%"), q = d3.format(",.1f") //',.2f' per due valori dopo la virgola
                  return "Cessioni:<br/>"
                    +  d.sname + " &rarr; " + d.tname
                    + ": " + q(d.svalue) + " Mil €<br/>"
                    + p(d.svalue/d.stotal) + " del totale cessioni " + d.sname + " (" + q(d.stotal) + " Mil €)<br/>"
                    + p(d.svalue/d.mtotal) + " del valore delle cessioni totali ("  + q(d.mtotal) + " Mil €)<br/>"
                    + "<br/>"
                    + d.tname + " &rarr; " + d.sname
                    + ": " + q(d.tvalue) + " Mil €<br/>"
                    + p(d.tvalue/d.ttotal) + " del totale cessioni " + d.tname + " (" + q(d.ttotal) + " Mil €)<br/>"
                    + p(d.tvalue/d.mtotal) + " del valore delle cessioni totali (" + q(d.mtotal) + " Mil €)";
                }

                //Settaggi della tooltip del gruppo
                function groupTip (d) { 
                  var p = d3.format(".1%"), q = d3.format(",.1f")
                  return d.gname + "<br/>"
                      + "Valore cessioni: " + q(d.gvalue) + " Mil € <br/>"
                      + p(d.gvalue/d.mtotal) + " del valore delle cessioni totali (" + q(d.mtotal) + " Mil €)"
                }

                function mouseover(d, i) {
                  d3.select("#tooltip")
                    .style("visibility", "visible")
                    .html(groupTip(rdr(d)))
                    .style("top", function () { return (d3.event.pageY - 80)+"px"})
                    .style("left", function () { return (d3.event.pageX - 130)+"px";})

                  chordPaths.classed("fade", function(p) {
                    return p.source.index != i
                        && p.target.index != i;
                  });
                }
            }

          </script>
      </div>
    </div>
  </div>

我已尝试添加此代码

var canvas = d3.select("#chartContainer").append("svg:svg")

但它不起作用! 有什么建议吗?

【问题讨论】:

    标签: twitter-bootstrap d3.js chord-diagram


    【解决方案1】:

    将下面的代码替换为您的代码:

    <div class="row">
        <div class="col-xs-12">
            <div id="chartContainer">
    
              <div id="tooltip"></div>
              <!--<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>-->
              <script src="js/d3.min.js" charset="utf-8"></script>
              <script src="js/underscore.js"></script>
              <script src="js/mapper.js"></script>
              <script>
                //*******************************************************************
                //  CREATE MATRIX AND MAP
                //*******************************************************************
    
    
    
                d3.csv('trade-a.csv', function (error, data) {
                  var mpr = chordMpr(data);
    
                  mpr
                    .addValuesToMap('seller')
                    .addValuesToMap('buyer')
                    .setFilter(function (row, a, b) {
                      return (row.seller === a.name && row.buyer === b.name) ||
                             (row.seller === b.name && row.buyer === a.name)
                    })
                    .setAccessor(function (recs, a, b) {
                      if (!recs[0]) return 0;
                        return recs[0].seller === a.name ? +recs[0].flow1 : +recs[0].flow2; 
                    });
                  drawChords(mpr.getMatrix(), mpr.getMap());
                });
                //*******************************************************************
                //  DRAW THE CHORD DIAGRAM
                //*******************************************************************
    
                //Gets called everytime window resizes
                $( window ).resize(function() {
             d3.csv('trade-a.csv', function (error, data) {
                  var mpr = chordMpr(data);
    
                  mpr
                    .addValuesToMap('seller')
                    .addValuesToMap('buyer')
                    .setFilter(function (row, a, b) {
                      return (row.seller === a.name && row.buyer === b.name) ||
                             (row.seller === b.name && row.buyer === a.name)
                    })
                    .setAccessor(function (recs, a, b) {
                      if (!recs[0]) return 0;
                        return recs[0].seller === a.name ? +recs[0].flow1 : +recs[0].flow2; 
                    });
                  drawChords(mpr.getMatrix(), mpr.getMap());
                });
    });
                function drawChords (matrix, mmap) {
    
                      var margin = {top: 20, right: 10, bottom: 20, left: 10};
    
                      var w = $('body').width() -  margin.left - margin.right., h = $('body').height() - margin.top - margin.bottom, r1 = h / 2, r0 = r1 - 110;
    
                  //Qui i settaggi della scala dei colori vedere anche https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors
                  var fill = d3.scale.ordinal()
                      .range(['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a','#ffff99','#b15928']);
    
                  var chord = d3.layout.chord()
                      .padding(.02)
                      .sortSubgroups(d3.descending)
                      .sortChords(d3.descending);
    
                  var arc = d3.svg.arc()
                      .innerRadius(r0)
                      .outerRadius(r0 + 20);
    
                  var svg = d3.select("body").append("svg:svg")
                      .attr("width", w)
                      .attr("height", h)
                    .append("svg:g")
                      .attr("id", "circle")
                      .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");
    
                      svg.append("circle")
                          .attr("r", r0 + 20);
    
                  var rdr = chordRdr(matrix, mmap);
                  chord.matrix(matrix);
    
                  var g = svg.selectAll("g.group")
                      .data(chord.groups())
                    .enter().append("svg:g")
                      .attr("class", "group")
                      .on("mouseover", mouseover)
                      .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });
    
                  g.append("svg:path")
                      .style("stroke", "black")
                      .style("fill", function(d) { return fill(rdr(d).gname); })
                      .attr("d", arc);
    
                  g.append("svg:text")
                      .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
                      .attr("dy", ".35em")
                      .style("font-family", "helvetica, arial, sans-serif")
                      .style("font-size", "9px")
                      .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
                      .attr("transform", function(d) {
                        return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
                            + "translate(" + (r0 + 26) + ")"
                            + (d.angle > Math.PI ? "rotate(180)" : "");
                      })
                      .text(function(d) { return rdr(d).gname; });
    
                    var chordPaths = svg.selectAll("path.chord")
                          .data(chord.chords())
                        .enter().append("svg:path")
                          .attr("class", "chord")
                          .style("stroke", function(d) { return d3.rgb(fill(rdr(d).sname)).darker(); })
                          .style("fill", function(d) { return fill(rdr(d).sname); })
                          .attr("d", d3.svg.chord().radius(r0))
                          .on("mouseover", function (d) {
                            d3.select("#tooltip")
                              .style("visibility", "visible")
                              .html(chordTip(rdr(d)))
                              .style("top", function () { return (d3.event.pageY - 170)+"px"})
                              .style("left", function () { return (d3.event.pageX - 100)+"px";})
                          })
                          .on("mouseout", function (d) { d3.select("#tooltip").style("visibility", "hidden") });
    
                  //Settaggi della tooltip del gruppo
                    function chordTip (d) {
                      var p = d3.format(".1%"), q = d3.format(",.1f") //',.2f' per due valori dopo la virgola
                      return "Cessioni:<br/>"
                        +  d.sname + " &rarr; " + d.tname
                        + ": " + q(d.svalue) + " Mil €<br/>"
                        + p(d.svalue/d.stotal) + " del totale cessioni " + d.sname + " (" + q(d.stotal) + " Mil €)<br/>"
                        + p(d.svalue/d.mtotal) + " del valore delle cessioni totali ("  + q(d.mtotal) + " Mil €)<br/>"
                        + "<br/>"
                        + d.tname + " &rarr; " + d.sname
                        + ": " + q(d.tvalue) + " Mil €<br/>"
                        + p(d.tvalue/d.ttotal) + " del totale cessioni " + d.tname + " (" + q(d.ttotal) + " Mil €)<br/>"
                        + p(d.tvalue/d.mtotal) + " del valore delle cessioni totali (" + q(d.mtotal) + " Mil €)";
                    }
    
                    //Settaggi della tooltip del gruppo
                    function groupTip (d) { 
                      var p = d3.format(".1%"), q = d3.format(",.1f")
                      return d.gname + "<br/>"
                          + "Valore cessioni: " + q(d.gvalue) + " Mil € <br/>"
                          + p(d.gvalue/d.mtotal) + " del valore delle cessioni totali (" + q(d.mtotal) + " Mil €)"
                    }
    
                    function mouseover(d, i) {
                      d3.select("#tooltip")
                        .style("visibility", "visible")
                        .html(groupTip(rdr(d)))
                        .style("top", function () { return (d3.event.pageY - 80)+"px"})
                        .style("left", function () { return (d3.event.pageX - 130)+"px";})
    
                      chordPaths.classed("fade", function(p) {
                        return p.source.index != i
                            && p.target.index != i;
                      });
                    }
                }
    
              </script>
          </div>
        </div>
      </div>
    

    我做了两处改动:

    1. 每次调整窗口大小时,我都会调用drawCords

      $( window ).resize(function() {
           d3.csv('trade-a.csv', function (error, data) {
               var mpr = chordMpr(data);
               mpr
               .addValuesToMap('seller')
               .addValuesToMap('buyer')
               .setFilter(function (row, a, b) {
                   return (row.seller === a.name && row.buyer === b.name) ||
               (row.seller === b.name && row.buyer === a.name)
               })
               .setAccessor(function (recs, a, b) {
                   if (!recs[0]) return 0;
                   return recs[0].seller === a.name ? +recs[0].flow1 : +recs[0].flow2; 
               });
               drawChords(mpr.getMatrix(), mpr.getMap());
           });
      });
      
    2. 我正在为 svg 动态设置 widthheight

      var margin = {top: 20, right: 10, bottom: 20, left: 10};
      var w = $('body').width() -  margin.left - margin.right;
      h = $('body').height() - margin.top - margin.bottom;
      r1 = h / 2, r0 = r1 - 110;
      

    【讨论】:

      猜你喜欢
      • 2014-04-18
      • 1970-01-01
      • 2016-06-19
      • 1970-01-01
      • 2011-03-13
      • 2015-09-19
      • 2011-12-17
      • 2011-08-20
      • 1970-01-01
      相关资源
      最近更新 更多