2016-06-08 64 views
2

我試圖繪製一個圖表,其中包含一個text容器內的多個餅圖和每個圖表,兩個中心tspan標籤。提供每個子圖的單獨數據並進行初始繪圖。d3:繪製一次兒童,但每次更新

但是,單擊setX按鈕時,tspan的內容不會被更新 - 與圓弧(其代碼已隱藏在此處)相反。

當我更換由var centerTextGroup = graphGroup.append("text")var centerTextGroup = ggEnter.append("text"),然而,然後drawChart描繪了一個文本組元素,這是我不希望任何。

如何解決此問題並使drawCharts正確更新tspans?

編輯:一種解決方案可能是var centerTextGroup = graphGroup.append("text")前使用graphGroup.selectAll("text").remove();,和它的作品,但我強烈懷疑這是不是做事情的方式D3 ...

var config = { 
 
    width: 150, 
 
    height: 100, 
 
    circleYCenter: 50, 
 
    circleXCenter: 75, 
 
    circleRad: 50, 
 
    circleWidth: 15, 
 
    arcWidth: 20, 
 
}; 
 
var svgContainer = null; 
 

 
function drawCharts(data) { 
 
    var container = svgContainer.select("#bigCircleGroup"); 
 
    var graphGroup = container.selectAll("g.graphGroup").data(data); 
 
    var ggEnter = graphGroup.enter().append("g").attr({ 
 
    transform: function(d, i) { 
 
     return "translate(" + (config.width * i) + ",0)"; 
 
    }, 
 
    class: "graphGroup", 
 
    id: function(d, i) { 
 
     return "bigCircle" + i; 
 
    } 
 
    }); 
 
    graphGroup.exit().remove(); 
 

 
    //Standard, common background arc. Append to enter selection, needs only to be drawn once per graph 
 
    var circleArc = d3.svg.arc().innerRadius(config.circleRad - (config.circleWidth/2)).outerRadius(config.circleRad + (config.circleWidth/2)).startAngle(0).endAngle(Math.PI * 2); 
 
    ggEnter.append("path").attr({ 
 
    "d": circleArc, 
 
    "transform": "translate(" + (config.circleXCenter) + "," + (config.circleYCenter) + ")", 
 
    "stroke": "none", 
 
    "fill": "#ececec" 
 
    }); 
 

 
    //Label. Group and labels should be drawn once per graph, but updated every time 
 
    var centerTextGroup = ggEnter.append("text").attr({ 
 
    "x": config.circleXCenter, 
 
    "y": config.circleYCenter, 
 
    "class": "center" 
 
    }).style({ 
 
    "text-anchor": "middle", 
 
    "alignment-baseline": "baseline", 
 
    "font-size": "30px", 
 
    "fill": "#5d5d5d" 
 
    }); 
 
    var bigDigitLabel = centerTextGroup.append("tspan").style("alignment-baseline", "baseline").attr("class", "bigDigit").text(function(d) { 
 
    return d.text.center; 
 
    }); 
 
    var unitLabel = centerTextGroup.append("tspan").style("font-size", "20px").attr("dy", 0).text(function(d) { 
 
    return d.text.unit; 
 
    }); 
 

 
    //Draw arcs here (removed for brevity) 
 
} 
 

 

 
$(document).ready(function() { 
 
    svgContainer = d3.select("svg"); 
 
    $("#set1").click(function() { 
 
    drawCharts([{ 
 
     "data": [{ 
 
     "value": "0.5", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.3", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 50, 
 
     "unit": "%" 
 
     } 
 
    }, { 
 
     "data": [{ 
 
     "value": "0.7", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.3", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 70, 
 
     "unit": "%" 
 
     } 
 
    }]); 
 
    }).click(); 
 
    $("#set2").click(function() { 
 
    drawCharts([{ 
 
     "data": [{ 
 
     "value": "0.1", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.05", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 10, 
 
     "unit": "%" 
 
     } 
 
    }, { 
 
     "data": [{ 
 
     "value": "1", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 100, 
 
     "unit": "%" 
 
     } 
 
    }]); 
 
    }); 
 
    $("#set3").click(function() { 
 
    drawCharts([{ 
 
     "data": [{ 
 
     "value": "0.1", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.5", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 10, 
 
     "unit": "%" 
 
     } 
 
    }]); 
 
    }); 
 
    $("#set4").click(function() { 
 
    drawCharts([{ 
 
     "data": [{ 
 
     "value": "0.1", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.5", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 10, 
 
     "unit": "%" 
 
     } 
 
    }, { 
 
     "data": [{ 
 
     "value": "0.1", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.5", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 10, 
 
     "unit": "%" 
 
     } 
 
    }, { 
 
     "data": [{ 
 
     "value": "0.9", 
 
     "color": "pink" 
 
     }, { 
 
     "value": "0.1", 
 
     "color": "lightblue" 
 
     }], 
 
     "text": { 
 
     "center": 10, 
 
     "unit": "%" 
 
     } 
 
    }, ]); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<svg width=450 height=100 style="display:block;"> 
 
    <g id="bigCircleGroup"></g> 
 
</svg> 
 
<button id="set1">set1</button> 
 
<button id="set2">set2</button> 
 
<button id="set3">set3</button> 
 
<button id="set4">set4</button>

回答

1

因此,對於改變數據,enter適用於新的數據點。有一個具象update,它可以應用於enter之前的變化數據點,或者如often the case,新應用於現有數據點的元素,最後exit適用於已刪除的數據點。所以它會變得更復雜一些,但是如果你可以清理並重新使用你設置數據的方式,並在enter後面輸入update步驟,那麼你可以更加符合d3如何幫助你寫數據驅動文檔。也有方法來啓用點擊功能只有D3和沒有jQuery,但我會假設頁面的其他部分使用jQuery,所以它是有效的免費給你。

var dataSets = [ 
 
    // Set One: 2 Datapoints 
 
    [{ 
 
"data": [{"value": "0.5","color": "pink"}, 
 
      {"value": "0.3","color": "lightblue"}], 
 
"text": {"center": 50, "unit": "%"} 
 
    },{ 
 
"data": [{"value": "0.7", "color": "pink"}, 
 
      {"value": "0.3", "color": "lightblue"}], 
 
"text": {"center": 70, "unit": "%"} 
 
    }], 
 
    // Set Two: 2 Datapoints 
 
    [{ 
 
"data": [{"value": "0.1", "color": "pink"}, 
 
      {"value": "0.05", "color": "lightblue"}], 
 
"text": {"center": 10, "unit": "%"} 
 
}, { 
 
"data": [{"value": "1", "color": "pink"}, 
 
      {"value": "0", "color": "lightblue"}], 
 
"text": {"center": 100, "unit": "%"} 
 
    }], 
 
    // Set Three: 1 Datapoints 
 
    [{ 
 
"data": [{"value": "0.1", "color": "pink"}, 
 
      {"value": "0.5", "color": "lightblue"}], 
 
"text": {"center": 10, "unit": "%"} 
 
    }], 
 
    // Set Four: 3 Datapoints 
 
    [{ 
 
"data": [{"value": "0.1", "color": "pink"}, 
 
      {"value": "0.5", "color": "lightblue"}], 
 
"text": {"center": 10, "unit": "%"} 
 
    },{ 
 
"data": [{"value": "0.1", "color": "pink"}, 
 
      {"value": "0.5", "color": "lightblue"}], 
 
"text": {"center": 10, "unit": "%"} 
 
    },{ 
 
"data": [{"value": "0.9", "color": "pink"}, 
 
      {"value": "0.1", "color": "lightblue"}], 
 
"text": {"center": 10, "unit": "%"} 
 
    }]]; 
 

 
var config = { 
 
    width: 150, 
 
    height: 100, 
 
    circleYCenter: 50, 
 
    circleXCenter: 75, 
 
    circleRad: 50, 
 
    circleWidth: 15, 
 
    arcWidth: 20, 
 
}; 
 
var svgContainer = null; 
 

 
function drawCharts(setIndex) { 
 
    var container = svgContainer.select("#bigCircleGroup"); 
 
    var graphGroup = container.selectAll("g.graphGroup").data(dataSets[setIndex]); 
 
    var ggEnter = graphGroup.enter().append("g").attr({ 
 
    transform: function(d, i) { 
 
     return "translate(" + (config.width * i) + ",0)"; 
 
    }, 
 
    class: "graphGroup", 
 
    id: function(d, i) { 
 
     return "bigCircle" + i; 
 
    } 
 
    }); 
 

 
    //Standard, common background arc. Append to enter selection, needs only to be drawn once per graph 
 
    var circleArc = d3.svg.arc().innerRadius(config.circleRad - (config.circleWidth/2)).outerRadius(config.circleRad + (config.circleWidth/2)).startAngle(0).endAngle(Math.PI * 2); 
 
    ggEnter.append("path").attr({ 
 
    "d": circleArc, 
 
    "transform": "translate(" + (config.circleXCenter) + "," + (config.circleYCenter) + ")", 
 
    "stroke": "none", 
 
    "fill": "#ececec" 
 
    }); 
 

 
    //Label. Group and labels should be drawn once per graph, but updated every time 
 
    ggEnterText = ggEnter.append("text"); 
 
    ggEnterText.append("tspan").attr("class", "bigDigit"); 
 
    ggEnterText.append("tspan").attr("class", "unit"); 
 
    graphGroup.exit().remove(); // No need to update items that will be removed. 
 
    setText(graphGroup.select("text")); // Notice: 
 
    // this applies to newly appended items that were entered 
 
    // and to existing items that were not entered and need updating. 
 

 
    //Draw arcs here (removed for brevity) 
 
    // [probably need to handle both append and update as labels do] 
 
} 
 

 
function setText(selection) { 
 
    selection = selection.transition(); 
 
    selection.attr({ 
 
    "x": config.circleXCenter, 
 
    "y": config.circleYCenter, 
 
    "class": "center" 
 
    }).style({ 
 
    "text-anchor": "middle", 
 
    "alignment-baseline": "baseline", 
 
    "font-size": "30px", 
 
    "fill": "#5d5d5d" 
 
    }); 
 
    selection.select(".bigDigit").style("alignment-baseline", "baseline").text(function(d) { 
 
    return d.text.center; 
 
    }); 
 
    selection.select(".unit").style("font-size", "20px").attr("dy", 0).text(function(d) { 
 
    return d.text.unit; 
 
    }); 
 
} 
 

 

 
$(document).ready(function() { 
 
    svgContainer = d3.select("svg"); 
 
    $("#set1").click(function() {drawCharts(0);}).click(); 
 
    $("#set2").click(function() {drawCharts(1);}); 
 
    $("#set3").click(function() {drawCharts(2);}); 
 
    $("#set4").click(function() {drawCharts(3);}); 
 
});
.ref {width:100%;padding:1em 5em;} 
 
.ref a{font-family:sans-serif;font-size:2em;text-decoration:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
    <svg width=450 height=100 style="display:block;"> 
 
     <g id="bigCircleGroup"></g> 
 
    </svg> 
 
    <button id="set1">set1</button> 
 
    <button id="set2">set2</button> 
 
    <button id="set3">set3</button> 
 
    <button id="set4">set4</button> 
 
<div class="ref"><a href="https://bl.ocks.org/mbostock/3808218">See Also</a></div>

0

D3的方式是:

1 - enter - incoming elements, entering the stage. 
2 - update - persistent elements, staying on stage. 
3 - exit - outgoing elements, exiting the stage. 

您需要更新。這就是爲什麼你必須刪除並重新更新

看看這個:Three Little Circles