2014-02-12 129 views
0

我使用動態氣泡圖創建可視化效果。我有它的工作,但不是有浮動工具提示,我只想用它的名稱標記每個氣泡,我嘗試了一些不同的方法,但似乎無法得到它的工作。任何提示將不勝感激!d3動態氣泡圖 - 向氣泡添加文本

window.custom_bubble_chart = (function(d3, CustomTooltip) { 
//"use strict"; 


    $("#tags").html(""); 

// Work out chart sizes 
var width = $("#tags").width(); 
var height = $("#tags").height(); 

var tooltip = CustomTooltip("gates_tooltip", 180); 
var layout_gravity = -0.01; 
var damper = 0.1; 
var nodes = []; 
var vis, force, circles, radius_scale; 

    var center = {x: width/2, y: height/2}; 

var year_centers = { 
    "positive": {x: width/3, y: height/2}, 
    "neutral": {x: width/2, y: height/2}, 
    "negative": {x: 2 * width/3, y: height/2} 
    }; 

    var fill_color = d3.scale.ordinal() 
       .domain(["low", "medium", "high"]) 
       .range(["#99cc00", "#ff4444", "#33b5e5"]); 

function custom_chart(data) { 


var max_amount = d3.max(data, function(d) { return parseInt(d.freq, 10); }); 
radius_scale = d3.scale.pow().exponent(0.5).domain([0, max_amount]).range([2, 25]); 

//create node objects from original data 
//that will serve as the data behind each 
//bubble in the vis, then add each node 
//to nodes to be used later 
data.forEach(function(d){ 
    var node = { 
    id: d.id, 
    radius: radius_scale(parseInt(d.freq, 4)), 
    value: d.freq, 
    name: d.word, 
    group: d.sentiment_adj, 
    year: d.sentiment_adj, 
    x: Math.random() * 900, 
    y: Math.random() * 800 
    }; 
    nodes.push(node); 
}); 

nodes.sort(function(a, b) {return b.value- a.value; }); 

vis = d3.select("#tags").append("svg") 
      .attr("width", width) 
      .attr("height", height) 
      .attr("id", "svg_tags"); 

circles = vis.selectAll("circle") 
      .data(nodes, function(d) { return d.id ;}); 

circles.enter().append("circle") 
    .attr("r", 0) 
    .attr("fill", function(d) { return fill_color(d.group) ;}) 
    .attr("stroke-width", 2) 
    .attr("stroke", function(d) {return d3.rgb(fill_color(d.group)).darker();}) 
    .attr("id", function(d) { return "bubble_" + d.id; }) 
    .on("mouseover", function(d, i) {show_details(d, i, this);}) 
    .on("mouseout", function(d, i) {hide_details(d, i, this);}); 

    //fill circles with text - testing code that doesnt work! 
//circles.append("text") 
    //.attr("text-anchor", "middle") 
// .attr("dy", ".3em") 
// .text(function(d) { return data.name ; }); 

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

} 

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

    function start() { 
    force = d3.layout.force() 
     .nodes(nodes) 
     .size([width, height]); 
} 

function display_group_all() { 
    force.gravity(layout_gravity) 
    .charge(charge) 
    .friction(0.9) 
    .on("tick", function(e) { 
     circles.each(move_towards_center(e.alpha)) 
       .attr("cx", function(d) {return d.x;}) 
       .attr("cy", function(d) {return d.y;}); 
     }); 
    force.start(); 
    hide_years(); 
} 

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

    function display_by_year() { 
    force.gravity(layout_gravity) 
    .charge(charge) 
    .friction(0.9) 
    .on("tick", function(e) { 
     circles.each(move_towards_year(e.alpha)) 
      .attr("cx", function(d) {return d.x;}) 
      .attr("cy", function(d) {return d.y;}); 
    }); 
    force.start(); 
    display_years(); 
} 

    function move_towards_year(alpha) { 
return function(d) { 
    var target = year_centers[d.year]; 
    d.x = d.x + (target.x - d.x) * (damper + 0.02) * alpha * 1.1; 
    d.y = d.y + (target.y - d.y) * (damper + 0.02) * alpha * 1.1; 
    }; 
} 


function display_years() { 
    var years_x = {"Positive": width/3, "Neutral": width/2, "Negative": width - width/3}; 
    var years_data = d3.keys(years_x); 
    var years = vis.selectAll(".years") 
      .data(years_data); 

    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;}); 

} 

function hide_years() { 
    var years = vis.selectAll(".years").remove(); 
} 


function show_details(data, i, element) { 
d3.select(element).attr("stroke", "black"); 
var content = "<span><b> " + data.name + "</b></span><br/>"; 
    tooltip.showTooltip(content, d3.event); 
} 

function hide_details(data, i, element) { 
    d3.select(element).attr("stroke", function(d) { return   d3.rgb(fill_color(d.group)).darker();}); 
tooltip.hideTooltip(); 
} 

    var my_mod = {}; 
my_mod.init = function (_data) { 
custom_chart(_data); 
start(); 
}; 

my_mod.display_all = display_group_all; 
my_mod.display_year = display_by_year; 
my_mod.toggle_view = function(view_type) { 
if (view_type == 'year') { 
    display_by_year(); 
} else { 
    display_group_all(); 
    } 
}; 

return my_mod; 
})(d3, CustomTooltip); 
+0

由於圓圈元素不是容器,因此不能將文本元素附加到圓形元素。您需要創建一個組元素(「g)」,並將圓圈和相關的文本元素添加到它。 – FernOfTheAndes

回答

0

您不能在SVG中的形狀內添加文本。文本元素需要分開定位。

你有兩個選擇:

  • 創建一個選擇<text>元素,以及數據結合到他們,從圈完全分開;或者,
  • 使您的主要選擇(您加入的數據)由<g>元素組成,然後將圓圈和文本添加到組中。

第二個選項使更新操作更簡單,但你必須改變你的更新功能使用轉換爲定位,而不是cxcy。這是一個tree layout,它爲每個節點使用組,每個節點包含一個圓圈和一個標籤。