无法在d3中向圈子添加文字

时间:2016-04-01 06:08:16

标签: jquery d3.js

我正在尝试创建一个气泡图,如下图所示 enter image description here

现在我想为每个气泡添加一些文字标签。但我无法这样做。 根据我目前研究的内容,我需要添加以将这些圆圈添加到单独的“g”节点中。 任何人都可以指导我如何完成这项任务。

以下是我的代码

BubbleChart.prototype.create_vis = function() {
    var that,
    _this = this;
    this.vis = d3.select("#"+div)
    .append("svg")
    .attr("viewBox", "0 -20 "+(divWidth)+" "+(divHeight + margin.top + margin.bottom)+" ")
    .append("g")
    .attr("id", "svg_vis");

    var gradient = this.vis.append("svg:defs").selectAll("radialGradient").data(this.data).enter()
    .append("svg:radialGradient")
    .attr("id", function(d) {
        return "gradient" + (d[columns[0]]).replace(/[^a-zA-Z0-9]/g, '', 'gi');
    })
    .attr("fx", "5%")
    .attr("fy", "5%")
    .attr("r", "50%")
    .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
    .attr("offset", "0%")
    .attr("stop-color", "rgb(240,240,240)")
    .attr("stop-opacity", 1);

    gradient.append("svg:stop")
    .attr("offset", "80%")
    .attr("stop-opacity", 1);
    parent.$("#legends").val(JSON.stringify(chartMap));
    gradient = this.vis.append("svg:defs").selectAll("radialGradient").data(this.data).enter()
    .append("svg:radialGradient")
    .attr("id", function(d) {
        return "gradientDrill";
    })
    .attr("fx", "5%")
    .attr("fy", "5%")
    .attr("r", "50%")
    .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
    .attr("offset", "0%")
    .attr("stop-color", "rgb(240,240,240)")
    .attr("stop-opacity", 1);

    gradient.append("svg:stop")
    .attr("offset", "80%")
    .attr("stop-color", drillShade)
    .attr("stop-opacity", 1);
   var node = this.vis.append("g") 
    this.circles = this.vis.selectAll("circle")
    .data(this.nodes);
    that = this;

    var circles1=this.circles.enter()
    .append("circle")
    .attr("class", "node")
    .attr("fill", "blue")
    .attr("stroke-width", 2)
    //            .attr("stroke", function(d) {
    //                return "url(#gradient" + (d.name).replace(/[^a-zA-Z0-9]/g, '', 'gi') + ")";
    //            })
    .attr("id", function(d) {
        return d.name+ ":" + d.id + "_" + d.measure;
    })
    .attr("opacity",".7")
    .attr("index_value", function(d, i) {
        return "index-" + d.name.replace(/[^a-zA-Z0-9]/g, '', 'gi');
    })
    .attr("class", function(d, i) {
        return "bars-Bubble-index-" + d.name.replace(/[^a-zA-Z0-9]/g, '', 'gi')+div;
    })


    return this.circles.transition().duration(500)
    .attr("r", function(d) {
        return d.radius;
    })

};

提前致谢!

1 个答案:

答案 0 :(得分:2)

您必须使用g元素对圆圈和文字标签进行分组。然后使用g元素的transform属性而不是cxcy属性更新节点位置。

更新小提琴:



var chartData = JSON.parse('{"chart1":{"viewBys":["Category","Store"],"viewIds":["13917","13972"],"dimensions":["13917","13972"],"aggregation":["SUM"],"meassures":["Total Orders"],"defaultMeasures":["Total Orders"],"defaultMeasureIds":["15042"],"meassureIds":["15042"],"size":"S","records":"12","sortBasis":"Value","chartType":"Split-Bubble","viewByLevel":"single","others":"N","othersL":"N","row":"1","col":"1","size_x":"15","size_y":"9","id":"divchart1","KPIName":"Total Orders","currencySymbol":{"15042":""},"comboData":false,"isKPI":false}}');
var data = JSON.parse('[{"Category":"Footwear","Store":"Bengaluru","Total Orders":"18"},{"Category":"Clothing","Store":"Chennai","Total Orders":"17"},{"Category":"Footwear","Store":"Mumbai","Total Orders":"17"},{"Category":"Clothing","Store":"Delhi","Total Orders":"16"},{"Category":"Clothing","Store":"Noida","Total Orders":"16"},{"Category":"Footwear","Store":"Chennai","Total Orders":"16"},{"Category":"Footwear","Store":"Delhi","Total Orders":"16"},{"Category":"Footwear","Store":"Gurgaon","Total Orders":"16"},{"Category":"Clothing","Store":"Kolkata","Total Orders":"15"},{"Category":"Computer Hardware","Store":"Delhi","Total Orders":"15"},{"Category":"Clothing","Store":"Bengaluru","Total Orders":"14"},{"Category":"Computer Hardware","Store":"Mumbai","Total Orders":"13"},{"Category":"Computer Hardware","Store":"Bengaluru","Total Orders":"12"},{"Category":"Computer Hardware","Store":"Pune","Total Orders":"12"},{"Category":"Computer Hardware","Store":"Hyderabad","Total Orders":"11"},{"Category":"Cameras","Store":"Bengaluru","Total Orders":"8"},{"Category":"Cameras","Store":"Delhi","Total Orders":"8"},{"Category":"Cameras","Store":"Gurgaon","Total Orders":"8"},{"Category":"Cameras","Store":"Mumbai","Total Orders":"8"},{"Category":"Cameras","Store":"Noida","Total Orders":"8"},{"Category":"Watches","Store":"Secunderabad","Total Orders":"7"},{"Category":"Watches","Store":"Bengaluru","Total Orders":"6"},{"Category":"Watches","Store":"Delhi","Total Orders":"6"},{"Category":"Watches","Store":"Gurgaon","Total Orders":"6"},{"Category":"Watches","Store":"Hyderabad","Total Orders":"6"},{"Category":"Mobile Phones","Store":"Delhi","Total Orders":"5"},{"Category":"Mobile Phones","Store":"Hyderabad","Total Orders":"5"},{"Category":"Mobile Phones","Store":"Mumbai","Total Orders":"4"},{"Category":"Mobile Phones","Store":"Aurangabad","Total Orders":"3"},{"Category":"Mobile Phones","Store":"Bengaluru","Total Orders":"3"}]');
var div = 'chart1';
var columns = ['Category'];
var measureArray = ['Total Orders'];
var divWidth = 500;
var divHeight = 300;
var drillShade = 'red';
var color = ['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue'];
var colIds;
var colName;
var dashletid;
var count = 0;
var colorCount = 0
var columnsVar = columns;
var fromoneview = 'false'
var colorGroup = {};
var div1 = ''
if (fromoneview != 'null' && fromoneview == 'true') {

  dashletid = div;
  div = div1
  colIds = chartData[div1]["viewIds"];
  colName = chartData[div]["viewBys"];
} else {
  colIds = chartData[div]["viewIds"];
  colName = chartData[div]["viewBys"];

}
var BubbleChart, root,
  __bind = function(fn, me) {
    return function() {
      return fn.apply(me, arguments);
    };
  };


var margin = {
  top: 10,
  right: 12,
  bottom: 30,
  left: 70
};
var legendColorMap = {};

BubbleChart = (function() {
  var chartMap = {};

  function BubbleChart(data) {
    this.hide_details = __bind(this.hide_details, this);

    this.show_details = __bind(this.show_details, this);

    this.hide_years = __bind(this.hide_years, this);

    this.display_years = __bind(this.display_years, this);

    this.move_towards_year = __bind(this.move_towards_year, this);

    this.display_by_year = __bind(this.display_by_year, this);

    this.move_towards_center = __bind(this.move_towards_center, this);

    this.display_group_all = __bind(this.display_group_all, this);

    this.start = __bind(this.start, this);
    this.create_vis = __bind(this.create_vis, this);
    this.create_nodes = __bind(this.create_nodes, this);
    var max_amount;
    this.data = data;
    this.width = divWidth;
    this.height = divHeight - 50;
    this.center = {
      x: this.width / 2,
      y: this.height / 2.4
    };
    this.layout_gravity = -0.01;
    this.damper = 0.1;
    this.vis = null;
    this.nodes = [];
    this.force = null;
    this.circles = null;
    this.fill_color = ['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'blue'];
    max_amount = d3.max(this.data, function(d) {
      return parseFloat(d[measureArray[0]]);
    });
    var radScale = 38;
    this.radius_scale = d3.scale.pow().exponent(0.5).domain([0, max_amount]).range(["2", radScale]);
    this.create_nodes();
    this.create_vis();
  }
  var legends = [];

  BubbleChart.prototype.create_nodes = function() {
    var _this = this;
    this.data.forEach(function(d, i) {
      if (i < 500) {
        var node;
        node = {
          id: d[measureArray[0]],
          radius: _this.radius_scale(parseFloat(d[measureArray[0]])),
          value: d[measureArray[0]],
          measure: measureArray[0].replace("_", "-", "gi"),
          name: d[columns[0]],
          group: d[columns[0]],
          year: d[columns[1]],
          x: Math.random(),
          y: Math.random()
        };
        return _this.nodes.push(node);
      }
    });
    return this.nodes.sort(function(a, b) {
      return b.value - a.value;
    });
  };
  data.forEach(function(d, i) {
    if (legends.indexOf(d[columns[0]]) === -1)
      legends.push(d[columns[0]]);
  });
  BubbleChart.prototype.create_vis = function() {
    var that,
      _this = this;

    this.vis = d3.select("body")
      .append("svg")
      .attr("viewBox", "0 -20 " + (divWidth) + " " + (divHeight + margin.top + margin.bottom) + " ")
      .append("g")
      .attr("id", "svg_vis");

    var gradient = this.vis.append("svg:defs").selectAll("radialGradient").data(this.data).enter()
      .append("svg:radialGradient")
      .attr("id", function(d) {
        return "gradient" + (d[columns[0]]).replace(/[^a-zA-Z0-9]/g, '', 'gi');
      })
      .attr("fx", "5%")
      .attr("fy", "5%")
      .attr("r", "50%")
      .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
      .attr("offset", "0%")
      .attr("stop-color", "rgb(240,240,240)")
      .attr("stop-opacity", 1);

    gradient.append("svg:stop")
      .attr("offset", "80%")
      .attr("stop-opacity", 1);

    var gradient = this.vis.append("svg:defs").selectAll("radialGradient").data(this.data).enter()
      .append("svg:radialGradient")
      .attr("id", function(d) {
        return "gradientDrill";
      })
      .attr("fx", "5%")
      .attr("fy", "5%")
      .attr("r", "50%")
      .attr("spreadMethod", "pad");

    gradient.append("svg:stop")
      .attr("offset", "0%")
      .attr("stop-color", "rgb(240,240,240)")
      .attr("stop-opacity", 1);

    gradient.append("svg:stop")
      .attr("offset", "80%")
      .attr("stop-color", drillShade)
      .attr("stop-opacity", 1);
    var node = this.vis.append("g")

    this.circles = this.vis.selectAll("g.node")
      .data(this.nodes);

    that = this;



    var circles1 = this.circles.enter()
      .append("g").attr("class", "node");

    circles1.append("circle")
      .attr("fill", "blue")
      .attr("stroke-width", 2)
      //            .attr("stroke", function(d) {
      //                return "url(#gradient" + (d.name).replace(/[^a-zA-Z0-9]/g, '', 'gi') + ")";
      //            })
      .attr("id", function(d) {
        return d.name + ":" + d.id + "_" + d.measure;
      })
      .attr("opacity", ".7")
      .attr("index_value", function(d, i) {
        return "index-" + d.name.replace(/[^a-zA-Z0-9]/g, '', 'gi');
      })
      .attr("class", function(d, i) {
        return "bars-Bubble-index-" + d.name.replace(/[^a-zA-Z0-9]/g, '', 'gi') + div;
      }).append("title")
      .text(function(d) {
        return d.store;
      });

    circles1.append("text")
      .attr("text-anchor", "middle")
      .attr("class", "gFontFamily")
      .style("font-size", '11px')
      .text(function(d, i) {
        return "aaa";
      });

    return this.circles.selectAll("circle").transition().duration(500)
      .attr("r", function(d) {
        return d.radius;
      })

  };

  BubbleChart.prototype.charge = function(d) {
    return -Math.pow(d.radius, 2.0) / 8;
  };

  BubbleChart.prototype.start = function() {
    return this.force = d3.layout.force()
      .nodes(this.nodes)
      .size([this.width * .5, this.height * .5]);
  };

  BubbleChart.prototype.display_group_all = function() {
    var _this = this;
    this.force.gravity(this.layout_gravity).charge(this.charge).friction(0.9).on("tick", function(e) {
      return _this.circles.each(_this.move_towards_center(e.alpha))
        .attr("transform", function(d) {
          return "translate(" + (d.x - 70) + "," + (d.y + 10) + ")";
        });
    });
    this.force.start();
    return this.hide_years();
  };

  BubbleChart.prototype.move_towards_center = function(alpha) {
    var _this = this;
    return function(d) {
      d.x = d.x + (_this.center.x - d.x) * (_this.damper + 0.02) * alpha;
      return d.y = d.y + (_this.center.y - d.y) * (_this.damper + 0.02) * alpha;
    };
  };

  BubbleChart.prototype.display_by_year = function() {
    var _this = this;
    this.force.gravity(this.layout_gravity).charge(this.charge).friction(0.9).on("tick", function(e) {
      return _this.circles.each(_this.move_towards_year(e.alpha))
        .attr("cx", function(d) {
          return d.x - 70;
        })
        .attr("cy", function(d) {
          return d.y + 10;
        });
    });
    this.force.start();
    return this.hide_years();
  };

  BubbleChart.prototype.move_towards_year = function(alpha) {
    var _this = this;
    return function(d, i) {
      var target;
      target = _this.year_centers[d.year];
      if (typeof target !== "undefined") {
        d.x = d.x + (target.x - d.x) * (_this.damper + 0.02) * alpha * 1.1;
        return d.y = d.y + (target.y - d.y) * (_this.damper + 0.02) * alpha * 1.1;
      }
    };
  };

  BubbleChart.prototype.display_years = function() {
    var years, years_data,
      _this = this;
    var allValuesArray = [];
    var group_labels = [];
    var yea = {};
    var mul = 1;
    var years_x = {};
    var position = 4;
    var x_position = 160;
    data.forEach(function(d) {
      if (allValuesArray.indexOf(d[columns[1]]) === -1)
        allValuesArray.push(d[columns[1]]);
    });
    var hgt = _this.height;
    var wid = _this.width;
    var total_slots = allValuesArray.length;
    var x_position = 160;
    allValuesArray.forEach(function(d, i) {
      if (i < 3) {
        if (position === 0) {
          position = 2;
          mul = 1.5;
        }
        x_position = wid / position;
        group_labels[i] = mul * x_position;
        years_x[allValuesArray[i]] = group_labels[i];
        position = position - 2;

      }
    });

    years_data = d3.keys(years_x);
    years = this.vis.selectAll(".years").data(years_data);
    return years.enter().append("text").attr("class", "years").attr("x", function(d) {
      return years_x[d];
    }).attr("y", 40).attr("text-anchor", "middle").text(function(d) {
      return d;
    });
  };

  BubbleChart.prototype.hide_years = function() {
    var years;
    return years = this.vis.selectAll(".years").remove();
  };

  BubbleChart.prototype.show_details = function(data, i, element) {
    var content;
    if (columns == columns[0]) {
      content = "<span class=\"name\">" + columns[0] + "</span><span class=\"value\"> " + data.name + "</span><br/>";
    } else {
      content = "<span class=\"name\">" + columns[0] + "</span><b>:</b><span class=\"value\"> " + data.name + "</span><br/>";
      content += "<span class=\"name\">" + columns[1] + "</span><b>:</b><span class=\"value\"> " + data.year + "</span><br/>";
    }
    content += "<span class=\"name\">" + measureArray[0] + "</span><b>:</b><span class=\"value\"> " + data.value + "</span><br/>";
    return tooltip.showTooltip(content, d3.event);
  };

  BubbleChart.prototype.hide_details = function(data, i, element) {
    return tooltip.hideTooltip();
  };

  return BubbleChart;
})();

root = typeof exports !== "undefined" && exports !== null ? exports : this;
var chart, render_vis,
  _this = this;
chart = null;
render_vis = function(csv) {
  chart = new BubbleChart(data);
  chart.start();
  return root.display_all();
};
root.display_all = function() {
  return chart.display_group_all();
};
root.display_year = function(splitby1) {
  splitby = splitby1;
  return chart.display_by_year(splitby1);
};
root.toggle_view = function(view_type, splitby) {
  if (view_type === 'year') {
    return root.display_year(splitby);
  } else {
    return root.display_all();
  }
};
render_vis();
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;