data-join का उपयोग करते समय सामान्य नियम यह है कि आप डेटा से तत्वों के लिए एक-से-एक मैपिंग चाहते हैं। इसलिए, यदि आपके स्कैटरप्लॉट में दो श्रृंखलाएं हैं, तो आपको श्रृंखला का प्रतिनिधित्व करने के लिए दो कंटेनर तत्व (जैसे G elements) चाहिए। चूंकि आपके पास वर्तमान में केवल data
सरणी है, इसलिए आप डेटा प्रतिनिधित्व को दो समानांतर सरणी में समान प्रतिनिधित्व के साथ परिवर्तित करने के लिए array.map का उपयोग भी करना चाहेंगे। इस तरह, आपको प्रत्येक श्रृंखला के लिए कोड डुप्लिकेट करने की आवश्यकता नहीं है।
मान लें कि आपका डेटा एक CSV में प्रस्तुत किया गया था के लिए एक्स -values के लिए एक स्तंभ, और कई अन्य कॉलम के साथ फाइल y प्रत्येक श्रृंखला के -values:
x,y1,y2
5,90,22
25,30,25
45,50,80
65,55,9
85,25,95
यदि आप चाहते हैं कोड पूरी तरह से सामान्य होने के लिए, आपको पहले श्रृंखला के नामों की गणना करने की आवश्यकता है, जैसे कि ["y1", "y2"]
। (यदि आपने CSV फ़ाइल में तीसरा कॉलम जोड़ा है, तो यह ["y1", "y2", "y3"]
हो सकता है।) आप d3.keys का उपयोग करके नामों की गणना कर सकते हैं, जो ऑब्जेक्ट से नामित गुणों को निकालते हैं। उदाहरण के लिए, d3.keys({foo: 1, bar: 2})
["foo", "bar"]
देता है।
// Compute the series names ("y1", "y2", etc.) from the loaded CSV.
var seriesNames = d3.keys(data[0])
.filter(function(d) { return d !== "x"; })
.sort();
अब आपके पास श्रृंखला के नाम हैं, तो आप अंक के सरणी बना सकते हैं। बाहरी सरणी श्रृंखला का प्रतिनिधित्व करती है (जिसमें से दो हैं) और आंतरिक सरणी डेटा बिंदुओं को संग्रहित करती हैं। आप अंक को लगातार प्रतिनिधित्व (x
और y
गुणों के साथ ऑब्जेक्ट्स) में परिवर्तित कर सकते हैं, जिससे आप श्रृंखला में कोड का पुन: उपयोग कर सकते हैं।
// Map the data to an array of arrays of {x, y} tuples.
var series = seriesNames.map(function(series) {
return data.map(function(d) {
return {x: +d.x, y: +d[series]};
});
});
नोट इस कोड नंबरों के लिए सीएसवी मूल्यों मजबूर करने के लिए +
ऑपरेटर का उपयोग करता है। (सीएसवी फाइलें अनियमित हैं, इसलिए वे शुरुआत में तार हैं।)
अब जब आपने अपने डेटा को नियमित प्रारूप में मैप किया है, तो आप प्रत्येक श्रृंखला के लिए जी तत्व बना सकते हैं, और फिर प्रत्येक बिंदु के लिए तत्वों को सर्कल कर सकते हैं। परिणामी SVG संरचना इस तरह दिखेगा:
<g class="series">
<circle class="point" r="4.5" cx="1" cy="2"/>
<circle class="point" r="4.5" cx="3" cy="2"/>
…
</g>
<g class="series">
<circle class="point" r="4.5" cx="5" cy="4"/>
<circle class="point" r="4.5" cx="7" cy="6"/>
…
</g>
और इसी डी 3 कोड:
// Add the points!
svg.selectAll(".series")
.data(series)
.enter().append("g")
.attr("class", "series")
.style("fill", function(d, i) { return z(i); })
.selectAll(".point")
.data(function(d) { return d; })
.enter().append("circle")
.attr("class", "point")
.attr("r", 4.5)
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); });
मैं भी एक भरने शैली जोड़कर प्रत्येक श्रृंखला के लिए एक अनूठा रंग आवंटित करने के लिए कोड का एक सा जोड़ दिया है युक्त जी तत्व के लिए। निश्चित रूप से ऐसा करने के कई तरीके हैं। (उदाहरण के लिए, आप प्रत्येक श्रृंखला के लिए रंग के बारे में और अधिक विशिष्ट होना चाहते हैं।) मैंने कोड को भी छोड़ दिया है जो आपके x और y स्केल (साथ ही अक्षों को प्रतिपादित करने) के डोमेन की गणना करता है, लेकिन आप पूरे काम कर उदाहरण देखना चाहते हैं:
लगभग एक ट्यूटोरियल ... माइक Bostock द्वारा इस तरह के लंबे उत्तरों के माध्यम से उत्तर दिया गया था और अन्य समान प्रश्नों को FAQ में रखा जाना चाहिए – paxRoman