如何使和弦响应

时间:2016-05-04 10:28:01

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

我正在尝试为项目开发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")

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

1 个答案:

答案 0 :(得分: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;