2013-11-15 14 views
8

में ज़ूम किए जाने पर बहुत बढ़िया अनाज बन जाते हैं। मैं एक धुरी फ़ंक्शन बनाने की कोशिश कर रहा हूं कि टिक/लेबल गतिशील होते हैं जिसका अर्थ है कि वे स्वचालित रूप से छुपा/दिखाते हैं। लेकिन इसके शीर्ष पर, मैं कुछ ज़ूम स्तर पर अधिक टिक/लेबल को रेंडर करना बंद करना चाहता हूं। यहां एक उदाहरण दिया गया है: सबसे पहले धुरी साल दिखाती है, फिर जब आप टिक्स में ज़ूम करते हैं तो महीनों बन जाते हैं, और जब आप इसमें ज़ूम करते हैं तो दिन (आईई, 28 दिसंबर) दिखाते हैं। सिवाय इसके कि मैं डी 3 को प्रतिबंधित करना चाहता हूं जैसे कि महीनों से ज़ूमिंग करते समय, यह कोई और टिक नहीं देता है क्योंकि महीनों की सबसे छोटी इकाई मैं चाहता हूं।डी 3 धुरी लेबल

मेरे पास कुछ उदाहरण हैं कि अगर संयुक्त बिल्कुल वही होगा जो मैं चाहता हूं, लेकिन मैं यह नहीं समझ सकता कि इसे कैसे किया जाए।

इसके अलावा: मैंने .tickFormat जोड़ा क्योंकि मैं प्रत्येक टिक को संक्षिप्त महीने प्रारूप के रूप में प्रदर्शित करना चाहता हूं।

उदाहरण 1: http://jsfiddle.net/GGYKL/

var xAxis = d3.svg.axis().scale(x) 
    .tickFormat(d3.time.format('%b')) 
    .orient("bottom"); 

यह उदाहरण दिखाता है कि टिक/लेबल दिखाई देते हैं और सही ढंग से गायब हो जाते हैं जब उसे ज़ूम, लेकिन जब आप उसे ज़ूम जारी रखते हैं, यह महीनों विभाजन और दोहरा महीने टिक्स शुरू होता है/लेबल, और मैं नहीं चाहता कि उसे ज़ूम से उपयोगकर्ता को प्रतिबंधित करना चाहते

उदाहरण 2:। http://jsfiddle.net/4kz7t/

यह उदाहरण समस्या को हल करता है जब आप उदाहरण 1 के साथ जो देखते हैं, उसमें ज़ूम करना जारी रखते हैं, लेकिन यह ज़ूम करने पर गति/लेबल को गतिशील रूप से छुपा/दिखाता नहीं है।

+3

डी 3 करता है स्वचालित रूप से, आप एक देने के लिए 'आवश्यकता नहीं होनी चाहिए .tickFormat' बिल्कुल - http://jsfiddle.net/GGYKL/1/ –

+0

आप बस अपने बहु-पैमाने के समय प्रारूप को परिभाषित कर सकते हैं - http://bl.ocks.org/mbostock/4149176 –

+0

@Lars देखें Kotthoff कारण मैंने जोड़ा .tickFormat क्योंकि मैं संक्षिप्त महीने टिक प्रारूप (जनवरी, फरवरी, मार्च 2013, जनवरी) चाहते हैं। क्या निश्चित ज़ूम डिग्री पर अधिक टिक अंक जोड़ने से रोकने के लिए डी 3 में कोई विकल्प है? महीने की टिकटें दिखाने के बाद कहें, अगर आप आगे ज़ूम करते हैं तो यह रेंज को दिनों में विभाजित नहीं करता है? मैं आपके उदाहरण का उपयोग करूंगा: यदि आप "2004" पर ज़ूम इन करते हैं तो आपको जल्द ही "अप्रैल", "जुलाई", अक्टूबर "," 2004 "आदि दिखाई देगा। लेकिन यदि आप ज़ूमिंग जारी रखते हैं, तो आप" नवंबर "," दिसंबर "देखेंगे , "2004", आदि ज़ूम भी आगे और यह "28 दिसंबर", 2 9 दिसंबर में विभाजित है "जो मैं समझने की कोशिश कर रहा हूं। – dcryan22

उत्तर

5

निकटतम जवाब मैं बहु पैमाने पर समय प्रारूप कि @Lars Kotthoff सुझाव दिया था का सामना करना पड़ा। मैं कस्टम समय फ़ॉर्मेटर संपादित होने के लिए:

http://jsfiddle.net/BdGv5/1/

var customTimeFormat = timeFormat([ 
    [d3.time.format("%Y"), function() { return true; }], 
    [d3.time.format("%b"), function(d) { return d.getMonth(); }], 
    [function(){return "";}, function(d) { return d.getDate() != 1; }] 
]); 

तो टिक्स खुद को अभी भी जब उसे ज़ूम उत्पन्न किया जा सकता है, लेकिन लेबल रिक्त स्ट्रिंग होगा।

अद्यतन:

मैं अपने खुद के समारोह है कि मैं .ticks में इस्तेमाल किया() बना दी। टिक्स आपके कार्य को टी 0 और टी 1 के रूप में स्केल सीमा तक गुजरता है। ओवरलैपिंग के बिना लेबल की अधिकतम मात्रा को खोजने के लिए मैंने लेबल आकार (और पैडिंग) द्वारा चार्ट चौड़ाई को विभाजित किया, और अतिव्यापी होने पर हर दूसरे टिक को हटाने के लिए अंडरस्कोर का उपयोग किया।

http://jsfiddle.net/BdGv5/3/

function customTickFunction(t0, t1, dt) 
    { 

     var labelSize = 30; // largest label is 23 pixels ("May") 
     var maxTotalLabels = Math.floor(width/labelSize); 

     function step(date, offset) 
     { 
      date.setMonth(date.getMonth() + offset); 
     } 

     var time = d3.time.month.ceil(t0), times = []; 

     while (time < t1) times.push(new Date(+time)), step(time, 1); 

     if(times.length > maxTotalLabels) 
      times = _.filter(times, function(d){ 
       return (d.getMonth() + 1) % 2; 
      }); 

     return times; 
    } 

    var domain = xScale.domain(); 
    var xAxisMonthsFunction = d3.svg.axis().scale(xScale) 
     .ticks(customTickFunction) 
     .tickFormat(d3.time.format("%b")) 
     .orient("bottom"); 

अद्यतन 2:

http://jsfiddle.net/BdGv5/5/

टिक बनाया सिर्फ 1 स्तर से आगे समायोजित, अब यह 4 स्तरों (2,3,4,6) है।

function customTickFunction(t0, t1, dt) 
{ 

    var labelSize = 30; // largest label is 23 pixels ("May") 
    var maxTotalLabels = Math.floor(width/labelSize); 

    function step(date, offset) 
    { 
     date.setMonth(date.getMonth() + offset); 
    } 

    var time = d3.time.month.ceil(t0), times = [], monthFactors = [2,3,4,6]; 

    while (time < t1) times.push(new Date(+time)), step(time, 1); 

    var i; 
    for(i=1 ; times.length > maxTotalLabels ; i++) 
     times = _.filter(times, function(d){ 
      return (d.getMonth()) % monthFactors[i] == 0; 
     }); 

    return times; 
} 
+0

मैं इसे हासिल करने की भी कोशिश कर रहा था, और यह सहायक दिखता है हालांकि, मुझे समझ में नहीं आता कि कौन सा महीना फैक्टर है। क्या आप कृपया बता सकते हैं कि इसका क्या उपयोग किया जाता है? मैं इस फ़ंक्शन को दिन, मिनट और सेकंड के साथ काम करने के लिए विस्तारित करना चाहता हूं। इसके अलावा यदि लैंड के लिए लूप कभी भी टूट नहीं जाता है सच नहीं है। – Himanshu

+0

टी 0 से टी 1 तक सभी महीनों के साथ पॉप्युलेट हो जाने के बाद, _.filter() महीनों का उपयोग करता है, बिना किसी ओवरलैपिंग के महीने के लेबल फिट करने के लिए सबसे अच्छा संभव समाधान खोजने के लिए। – dcryan22

+1

आपको इसे विस्तारित करना होगा दिन, मिनट और सेकंड के साथ काम करने के लिए, लेकिन आप इस विधि का उपयोग डिफ़ॉल्ट समय की तुलना में क्यों करेंगे। स्केल के टिक फ़ंक्शन? इस तरह: http://bl.ocks.org/mbostock/1667367 – dcryan22

-1

.tickFormat हटाएं क्योंकि D3 स्वचालित रूप से गतिशील रूप से टिक को अद्यतन करता है। आप टिक को भी सीमित कर सकते हैं।

उदाहरण के लिए:

d3.svg.axis().scale(x) 
.ticks(6) /*Number of Ticks you desire to display in x-axis scale*/ 
.orient("bottom") 
+0

जब मेरा मतलब गति गतिशील रूप से अद्यतन होता है, तो मेरा मतलब था कि वे मेरे पहले उदाहरण की तरह स्वचालित रूप से टिक/लेबल छुपाते/दिखाते हैं। मैं जो कुछ करने की कोशिश कर रहा हूं वह ज़ूम की कुछ डिग्री के बाद है, मैं नहीं चाहता कि डी 3 और अधिक टिक/लेबल उत्पन्न करे क्योंकि मैं चाहता हूं कि छोटी इकाई मासिक हो। – dcryan22

1

मैं जबकि एक d3 charting components layer पर काम कर रहे एक समान मुद्दा था और इस विधि मैं अक्ष प्रतिपादन से पहले फोन के साथ इसे हल:

function preventTooSmallTimeIntervals(period) { 
     var tickSeconds = (xScale.ticks()[1] - xScale.ticks()[0])/1000; 
     var minSecondsPerInterval = period.seconds; 
     if (tickSeconds < minSecondsPerInterval) { 
      xAxis.ticks(period.d3TimeInterval.unit, period.d3TimeInterval.value); 
     } else { 
      xAxis.ticks(6); 
     } 
    } 

कि उदाहरण में, अवधि एक वस्तु है, लेकिन आप मुश्किल प्रदान कर सकते हैं अवधि के बजाय आपकी स्थिति के लिए कोडित मूल्य। सेकेंड (जो एक अंतराल की अवधि है) और period.d3TimeInterval फ़ील्ड।

sc.model.period.day1 = periodFactory({ 
     display: '1 Day', 
     seconds: 86400, 
     d3TimeInterval: {unit: d3.time.day, value: 1}, 
     timeFormat: '%b-%d'}); 
    sc.model.period.hour1 = periodFactory({ 
     display: '1 Hour', 
     seconds: 3600, 
     d3TimeInterval: {unit: d3.time.hour, value: 1}, 
     timeFormat: '%b-%d %Hh'}); 
    sc.model.period.minute5 = periodFactory({ 
     display: '5 Minutes', 
     seconds: 300, 
     d3TimeInterval: {unit: d3.time.minute, value: 5}, 
     timeFormat: '%H:%M'}); 
    sc.model.period.minute1 = periodFactory({ 
     display: '1 Minute', 
     seconds: 60, 
     d3TimeInterval: {unit: d3.time.minute, value: 1}, 
     timeFormat: '%H:%M'}); 

कारण मैं सेकंड उपयोग नहीं कर रहा xAxis.ticks में हर बार है कि मैं एक बहुत बड़ा प्रदर्शन ड्रॉप जब के रूप में xAxis.ticks (d3.time.seconds, 86400) एक दिन में कम से कम व्यक्त किया था है, इसलिए मैं संग्रहीत एक क्षेत्र में डी 3 के लिए आवश्यक तत्व।

विचार axis.ticks के 2 व्यवहार, या तो अंतराल या गिनती के साथ खेलना है। दहलीज के नीचे, हम एक निश्चित अंतराल का उपयोग करते हैं, ऊपर हम डी 3 स्वचालित व्यवहार पर वापस आते हैं। जो ज़ूम इन करने के बाद ज़ूम आउट करने की समस्या को हल करता है। अन्य भाग के बिना, आप निर्दिष्ट कई अंतराल पर रहते हैं जो आपके द्वारा निर्दिष्ट अंतराल पर रहते हैं।

और तुम बस कॉपी/एक साधारण उदाहरण पेस्ट करना चाहते मामले में, यहाँ 1 दिन की एक न्यूनतम अंतराल के लिए एक उदाहरण है:

function preventTimeIntervalsSmallerThanADay() { 
     var tickSeconds = (xScale.ticks()[1] - xScale.ticks()[0])/1000; 
     var secondsPerDay = 86400; 
     if (tickSeconds < secondsPerDay) { 
      xAxis.ticks(d3.time.day, 1); 
     } else { 
      xAxis.ticks(6); 
     } 
    } 
संबंधित मुद्दे