2015-12-04 11 views
22

मैंने एक डी 3 डोनट चार्ट बनाया है। यहां मेरा कोड है:डी 3: नए डेटा वाले चार्ट को रीफ्रेश कैसे करें?

var width = 480; 
var height = 480; 
var radius = Math.min(width, height)/2; 
var doughnutWidth = 30; 

var color = d3.scale.category10(); 

var arc = d3.svg.arc() 
.outerRadius(radius - 10) 
.innerRadius(radius - 70); 

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

var dataset = settings.dataset; 
console.log(dataset); 

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

var path = svg.selectAll('path') 
.data(pie(dataset)) 
.enter() 
.append('path') 
.attr('d', arc) 
.attr('fill', function(d, i) { 
    return color(d.data[0]); 
}) 

मेरे पास मेरे वेब पेज पर एक साधारण रूप है जो कई विकल्पों के साथ एक ड्रॉपडाउन मेनू प्रदर्शित करता है। हर बार जब उपयोगकर्ता फॉर्म पर एक मान बदलता है तो मेरी स्क्रिप्ट (settings.dataset) पर एक नया डेटासेट भेजा जाता है और पृष्ठ पर डोनट को फिर से खींचा जाता है।

समस्या यह है कि पिछले डेटासेट के कुछ मान डोम में रहते हैं। नीचे कंसोल आउटपुट में, आप देख सकते हैं कि दूसरे डेटासेट में केवल दो तत्व हैं। तीसरा एक पिछले डेटासेट से है। यह चार्ट को गड़बड़ कर रहा है, क्योंकि यह एक ऐसा मूल्य प्रदर्शित कर रहा है जो वहां नहीं होना चाहिए।

enter image description here

मेरा प्रश्न: मैं कैसे पुराने मूल्यों को स्पष्ट करते हैं? मैंने .exit() और .remove() पर पढ़ा है, लेकिन मैं इन तरीकों के आसपास अपना सिर नहीं प्राप्त कर सकता हूं।

+0

तो जिस कोड को आपने ऊपर चिपकाया है वह हर समय उदेट पर निष्पादित हो जाता है? – Cyril

+0

हां, स्क्रिप्ट को हर बार बुलाया जाता है जब उपयोगकर्ता मेरे फॉर्म पर एक अलग विकल्प चुनता है। – 24ma13wg

+1

एक मुद्दा जो मैं देख सकता हूं वह है d3.select ("body") .append ("svg") जिसका अर्थ है कि आप अद्यतन पर हर बार svg जोड़ रहे हैं। d3.select ("svg") करें। हटाएं() को अद्यतन पर हटाए जाने के लिए। – Cyril

उत्तर

7

वहाँ 'पुनः बनाने' प्रभाव आप चाहते हैं को लागू करने के दो चरण हैं:

पहले, मैं आप चाहते हैं svg कैनवास केवल एक बार जब पेज पहली बार के लिए भरी हुई है तैयार हो लगता है, और उसके बाद अद्यतन निकालें के बजाय svg में चार्ट और svg पुनः बनाने:

var svg = d3.select("body") 
       .selectAll("svg") 
       .data([settings.dataset]); 
// put data in an array with only one element 

// this ensures there is only one consistent svg on the page when data is updated(when the script gets executed) 
svg.enter().append("svg") 

दूसरा, enter(), exit() समझने, इस बारे में कई महान ट्यूटोरियल हैं। आपके मामले में, मैं इस तरह डोनट कुछ आकर्षित करने के लिए सुझाव है:

var path = svg.selectAll(".donut") 
      .data(settings.data) 

// bind data to elements, now you have elements belong to one of those 
// three 'states', enter, exit, or update 

// for `enter` selection, append elements 
path.enter().append("path").attr("d", arc).attr("fill", "teal") 

// for `update` selection, which means they are already binded with data 
path.transition().attrTween("d", someFunction) // apply transition here if you want some animation for data change 

// for `exit` selection, they shouldn't be on the svg canvas since there is no corresponding data, you can then remove them 
path.exit().remove() 
+0

मैं अपना पॉइंट लेता हूं: चार्ट को एक बार खींचें और फिर उपयोगकर्ता चयन के अनुसार अपडेट करें। इस तरह थोड़ा: http: //bl.ocks।org/mbostock/1,346,410। फिलहाल मैं केवल उस डेटा को लोड कर रहा हूं जिसमें उपयोगकर्ता दिलचस्पी लेता है। इस दृष्टिकोण में मुझे सभी डेटा और स्टोर को एक बड़ी सरणी में लोड करने की आवश्यकता है - जो एक बड़ी समस्या नहीं है क्योंकि यह डेटा की एक छोटी राशि है। मुझे उस कोड को फिर से लिखना होगा जो डेटा प्रदान करता है। सलाह के लिये धन्यवाद। – 24ma13wg

+0

प्रत्येक बार मेरे उपयोग के मामले को बेहतर तरीके से सूट करने के लिए चार्ट को फिर से निकालना, मुझे लगता है। – 24ma13wg

+0

यदि आप का मतलब है कि हर बार पथ को हटाने और फिर से जोड़ने के लिए, संक्रमण() और निकास() आवश्यक नहीं होगा तो – fengshuo

17

एक समारोह है कि (पुनः) पाई कब बनाया जाता है खींचता है और जब यह अपडेट हो जाता है बनाएँ।

नए डेटा enter() का उपयोग कर पाई में जोड़ा जाना चाहिए और पुराने डेटा का उपयोग कर हटा दिया जाना चाहिए exit().remove()

यह इस रूप में सरल है:

path.enter().append("path") 
      .attr("fill", function(d, i) { return color(i); }) 
      .attr("d", arc) 
      .each(function(d) {this._current = d;}); 

    path.transition() 
      .attrTween("d", arcTween); 

    path.exit().remove() 

पूर्ण काम कर कोड ->JSFIDDLE

+1

'.each (function (d) {this._current = d;}) क्या करता है? –

2
//remove and create svg 
d3.select("svg").remove(); 
var svg = d3.select("body").append("svg").attr("width","960").attr("height", "600"), 
inner = svg.append("g"); 
संबंधित मुद्दे