2013-01-10 6 views
26

अपडेट करें: मैंने उत्तर अनुभाग में एक पूरी तरह से काम कर रहे समाधान को पोस्ट और स्वीकार कर लिया है। इस खंड में किसी भी कोड को अपने स्वयं के गैर-कार्य कोड की तुलना के संदर्भ के रूप में उपयोग किया जाना है, लेकिन समाधान के रूप में उपयोग नहीं किया जाना है।d3.js मानचित्र (<svg>) माता-पिता कंटेनर में ऑटो फ़िट करें और विंडो


मैं एक डैशबोर्ड का निर्माण कर रहा हूँ और दुनिया के नक्शे कि भू स्थान के आधार पर वास्तविक समय में ट्वीट्स साजिश जाएगा जोड़ने के लिए d3.js का उपयोग कर।

world.json फ़ाइल d3.json() लाइन में संदर्भित डाउनलोड करने योग्य है HERE (यह विश्व countries.json कहा जाता है)।

enter image description here

नक्शा एक एसवीजी कंटेनर के रूप में पृष्ठ पर है और डी 3 का उपयोग कर गाया है।

नीचे प्रासंगिक कोड स्लाइस हैं।

<div id="mapContainer"> 
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="500"></svg> 
</div> 

#mapContainer svg { 
    display:block; 
    margin:0 auto; 
} 
#mapContainer path { 
    fill:#DDD; 
    stroke:#FFF; 
} 

// generate US plot 
function draw() { 
    var map = d3.select("svg"); 
    var width = $("svg").parent().width(); 
    var height = $("svg").parent().height(); 

    var projection = d3.geo.equirectangular().scale(185).translate([width/2, height/2]); 
    var path = d3.geo.path().projection(projection); 
    d3.json('plugins/maps/world.json', function(collection) { 
     map.selectAll('path').data(collection.features).enter() 
      .append('path') 
      .attr('d', path) 
      .attr("width", width) 
      .attr("height", height); 
    }); 
} 
draw(); 
latestLoop(); 

$(window).resize(function() { 
    draw(); 
}); 

अद्यतन: मैं एक स्वीकार्य आकार (मेरी विशेष ब्राउज़र आकार के लिए) के लिए नक्शे बढ़ाया है, लेकिन यह अभी भी स्केल नहीं करेगा और जब मैं खिड़की के आकार को बदलता हूं तो केंद्र। यदि, हालांकि, मैं खिड़की का आकार बदलता हूं, फिर रीफ्रेश दबाता हूं, फिर पृष्ठ को फिर से लोड होने के बाद मानचित्र केंद्रित किया जाएगा। हालांकि, चूंकि पैमाने स्थिर है, यह ठीक से स्केल नहीं किया गया है।

enter image description here

उत्तर

28

पूर्ण समाधान:

यहाँ समाधान है जो नक्शे का आकार बदलने के बाद उपयोगकर्ता आकार बदलने के लिए विंडो के किनारे जारी किया है है , और इसे मूल कंटेनर में केंद्रित करें।

<div id="mapContainer"></div> 

function draw(ht) { 
    $("#mapContainer").html("<svg id='map' xmlns='http://www.w3.org/2000/svg' width='100%' height='" + ht + "'></svg>"); 
    map = d3.select("svg"); 
    var width = $("svg").parent().width(); 
    var height = ht; 

    // I discovered that the unscaled equirectangular map is 640x360. Thus, we 
    // should scale our map accordingly. Depending on the width ratio of the new 
    // container, the scale will be this ratio * 100. You could also use the height 
    // instead. The aspect ratio of an equirectangular map is 2:1, so that's why 
    // our height is half of our width. 

    projection = d3.geo.equirectangular().scale((width/640)*100).translate([width/2, height/2]); 
    var path = d3.geo.path().projection(projection); 
    d3.json('plugins/maps/world.json', function(collection) { 
     map.selectAll('path').data(collection.features).enter() 
      .append('path') 
      .attr('d', path) 
      .attr("width", width) 
      .attr("height", width/2); 
    }); 
} 
draw($("#mapContainer").width()/2); 

$(window).resize(function() { 
    if(this.resizeTO) clearTimeout(this.resizeTO); 
    this.resizeTO = setTimeout(function() { 
     $(this).trigger('resizeEnd'); 
    }, 500); 
}); 

$(window).bind('resizeEnd', function() { 
    var height = $("#mapContainer").width()/2; 
    $("#mapContainer svg").css("height", height); 
    draw(height); 
}); 
+2

क्या यह सब कुछ लिखना नहीं है? इससे कैसे बचा जा सकता है? – Arkanoid

+0

@arkanoid शायद ... यह समाधान मेरे लिए काम करता है, तो अगर अंत में यह क्या कर रहा है, तो * shrug *। मैंने यह नहीं खोला कि डी 3 चीजें कैसे प्रस्तुत कर रहा है, इसलिए यदि मेरा समाधान वास्तव में सिर्फ एक पुनर्लेखन है, तो मुझे लगता है कि आप इसे कैसे करते हैं। – Jon

4

यह काम करना चाहिए:

<svg 
    xmlns="http://www.w3.org/2000/svg" 
    width="860" 
    height="500" 
    viewBox="0 0 860 500" 
    preserveAspectRatio="xMinYMin meet"> 
+1

तो इस कंटेनर में भर जाता है, लेकिन नक्शे की स्केलिंग waaay ज़ूम इन करता है। वहाँ एक तरह से मैं यह कंटेनर के आकार के आधार पैमाने पर करने के प्राप्त कर सकते हैं है? मुझे कोई परवाह नहीं है कि मुझे कुछ jQuery या जावास्क्रिप्ट का उपयोग करना है, लेकिन मुझे नहीं पता कि मुझे कौन से मूल्यों को बदलना होगा। – Jon

+0

आप व्यूबॉक्स की सेटिंग्स को समायोजित करने के अलावा प्रक्षेपण के .scale() को समायोजित करना चाहते हैं। यदि आप भूगर्भीय परिप्रेक्ष्य से मानचित्र के अधिक या कम दिखाने में रुचि रखते हैं, तो आपके पास कितनी स्क्रीन रीयल एस्टेट है, तो आप दृश्य बॉक्स पर भरोसा नहीं करना चाहते हैं, बल्कि बदले जाने पर आधारित या फिर घुमाएं कंटेनर की चौड़ाई और ऊंचाई। – Elijah

8

चयन वस्तु एक बहुआयामी सरणी है, हालांकि ज्यादातर मामलों में यह शायद उस में केवल एक ही वस्तु होगा। उस ऑब्जेक्ट में "क्लाइंटविड्थ" फ़ील्ड है जो आपको बताता है कि उसके माता-पिता कितने व्यापक हैं।

तो तुम यह कर सकते हैं:

var selection = d3.select("#chart"); 
width = selection[0][0].clientWidth; 
+2

चूंकि मैंने इसे थोड़ी देर में नहीं देखा है, इसलिए मैं इसके लिए अपना शब्द ले जाऊंगा। यदि आपके पास समय है, तो भविष्य में लोगों के लिए एक पहेली मदद कर सकती है, लेकिन आपके उत्तर के लिए धन्यवाद! – Jon

+0

d3v4 के साथ, दूसरी पंक्ति 'select._groups [0] [0] होना चाहिए .clientWidth' – AlexG

2

सबसे अच्छा विकल्प d3 ग्राफ के चौड़ाई और ऊंचाई की सामान्य परिभाषा पर पहलू अनुपात के एक संयुक्त उपयोग है। इससे मुझे मेरे बहुत सारे ग्राफ कार्यों में मदद मिली है।
चरण 1: गतिशील रूप से div की ऊंचाई प्राप्त करें जिसमें ग्राफ को जोड़ा जाना है।
चरण 2: गतिशील रूप से पकड़े गए ऊंचाई के संबंध में चौड़ाई घोड़े अनुपात के रूप में घोषित करें।

var graph_div = document.getElementById(graph.divId); 
graph.height = graph_div.clientHeight; 
graph.width = (960/1200)*graph.height;