2015-10-05 129 views
1

所以我创建了一个饼图,它接受了一些JSON数据。单击单选按钮后,饼图的数据将根据选择的选项进行更新。然而,我遇到了一个问题,因为我想在饼图上放置一个D3工具提示,并在饼图更新时更新它的值......任何人都知道最好的方法来做到这一点?D3更新饼图的工具提示

这里就是我的饼图看起来像至今:

<form> 
    <label><input type="radio" name="dataset" value="females" checked> Females </label> 
    <label><input type="radio" name="dataset" value="males"> Males </label> 
    <label><input type="radio" name="dataset" value="totalNumber"> Both </label> 
    </form> 

    <script> 
    var width = 760, height = 300, radius = Math.min(width, height)/2; 
    var legendRectSize = 18; 
    var legendSpacing = 4; 

    var color = d3.scale.ordinal() 
     .domain(["7-15", "16-24", "25-33", "34-42", "43-51", "52-60", "61-70"]) 
     .range(["#ff8b3d", "#d65050", "#ab0e4d", "#6f0049", "#4a004b", "#d0743c", "#BE2625"]); 

    var arc = d3.svg.arc() 
     .outerRadius(radius * 0.9) 
     .innerRadius(radius * 0.3); 

    var outerArc = d3.svg.arc() 
     .innerRadius(radius * 0.9) 
     .outerRadius(radius * 0.9); 

    var pie = d3.layout.pie() 
     .sort(null) 
     .value(function(d) { return d.females; }); 

    var svg = d3.select("#donut1").append("svg") 
     .attr("width", width) 
     .attr("height", height) 
    .append("g") 
     .attr("transform", "translate(" + width/4 + "," + height/2 + ")") 

    d3.json("graphdata.php", function(error, data) { 

    data.forEach(function(d) { 
     var path = svg.datum(data).selectAll("path") 
     .data(pie) 
     d.females = +d.females; 
     d.males = +d.males; 
     d.totalNumber = +d.totalNumber; 
    }); 

    var tip = d3.tip() 
     .attr('class', 'd3-tip') 
     .offset([55, 0]) 
     .html(function(d) { 
     return ("Victims:") + " " + d[value] + "<br>"; 
     }) 

    svg.call(tip); 

    var donut1 = svg.selectAll(".arc") 
     .data(pie(data)) 
     .enter().append("g") 
     .attr("class", "arc") 
     .on("mouseover", tip.show) 
     .on("mouseout", tip.hide); 

    donut1.append("path") 
     .style("fill", function(d) { return color(d.data.age); }) 
     .attr("d", arc) 
     .each(function(d) {this._current = d; }); //stores the initial angles 


    /*Control for changing the radio buttons & filtering the data*/ 
    d3.selectAll("input") 
    .on("change", change); 

    var timeout = setTimeout(function() { 
     d3.select("input[value=\"females\"]").property("checked", true).each(change);}, 2000); 

    function change() { 
     var path = svg.datum(data).selectAll("path") 
     var value = this.value; 
     clearTimeout(timeout); 
     pie.value(function(d) { return d[value]; }); //change value function 
     tip.html(function(d) { return "Victims:" + " " + d[value]; }); //change the tooltip 
     path = path.data(pie); //compute new angles 
     path.transition().duration(1800).attrTween("d", arcTween); //redraw the arcs, please! 
    } 

    function type(d) { 
     d.females = +d.females; 
     d.males = +d.males; 
     d.totalNumber = +d.totalNumber; 
     return d; 
    } 

    //Store displayed angles in _current 
    //Interpolate them from _current to new angles 
    //_current is updated in-place by d3.interpolate during transition 
    function arcTween(a) { 
     var i = d3.interpolate(this._current, a); 
     this._current = i(0); 
     return function(t) { 
     return arc(i(t)); 
     }; 
    } 

我知道,关键在于改变()函数,这在行内:

tip.html(function(d) { return "Victims:" + " " + d[value]; }); //change the tooltip 

但当我尝试在该行上使用它时,d [值]是不确定的。我只是不知道它可能是些什么..

编辑: 这里的graphdata.php文件内容:

<?php include("connectDB.php"); 

$query = "SELECT sum(sex ='M') males, sum(sex ='F') females, CASE 
WHEN age BETWEEN 7 AND 15 THEN '7-15' 
WHEN age <= 24 THEN '16-24' 
WHEN age <= 33 THEN '25-33' 
WHEN age <= 42 THEN '34-42' 
WHEN age <= 51 THEN '43-51' 
WHEN age <= 52 THEN '52-60' 
WHEN age <= 70 THEN '61-70' 
END AS age, 
COUNT(*) AS totalNumber 

FROM people 

GROUP BY CASE 
WHEN age <= 15 THEN '7-15' 
WHEN age <= 24 THEN '16-24' 
WHEN age <= 33 THEN '25-33' 
WHEN age <= 42 THEN '34-42' 
WHEN age <= 51 THEN '43-51' 
WHEN age <= 52 THEN '52-60' 
WHEN age <= 70 THEN '61-70' 
END"; 

$data = array(); 

if($result = mysqli_query($db,$query)) { 
    while ($row = mysqli_fetch_assoc($result)) 
    { 
    $data[] = $row; 
    } 
} 

echo json_encode($data, JSON_PRETTY_PRINT); 
?> 
+0

发布什么是graphdata.php? - 一个工作演示会有帮助。 – somename

+1

数据被“pie-ed”后,'d.value'将包含该点,只需使用'tip.html(function(d){return“Victims:”+“”+ d [“value”]; });'或'tip.html(function(d){return“Victims:”+“”+ d.value;});' – Mark

+0

@Mark我认为是这种情况。然而,当我尝试'tip.html(function(d){return“Victims:”+“”+ d [“value”];});'或'tip.html(function(d){return“Victims: “+”“+ d.value;});',我只会得到d.females值,无论我更新图形。 –

回答

0

我有一个朋友来帮助我。他最终做的是这样的:

function change() { 
     var path = svg.datum(data).selectAll("path") 
     var value = this.value; 
     clearTimeout(timeout); 

     pie.value(function(d) { return d[value]; }); //change value function 

     tip.html(function(d) { 
      console.log($("input:checked").val()); 
     if($("input:checked").val() == "males") { 
      hoverValue = d.data.males; 
     } 
     if($("input:checked").val() == "females") { 
      hoverValue = d.data.females; 
     } 
     if($("input:checked").val() == "totalNumber") { 
      hoverValue = d.data.totalNumber; 
     } 
     return "Victims:" + " " +hoverValue; 
     }); //change the tooltip 
     path = path.data(pie); //compute new angles 
     path.transition().duration(1800).attrTween("d", arcTween); //redraw the arcs, please! 
    } 

特别是,tip.html函数发生了什么变化。我们将检查任何无线电值输入的值,并使用它来确定要显示的数据。但是,我的数据位于对象的下方,因此我们必须像这样导航:例如,d.data.males。我们将该值设置为一个变量并在返回中调用它,以便它显示在工具提示中。