2015-10-05 101 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。我們將該值設置爲一個變量並在返回中調用它,以便它顯示在工具提示中。