2012-04-25 14 views
9

में परिवर्तनीय परिशुद्धता डी 3.svg.axis.tickFormat के साथ d3.format ("s") का उपयोग कर एसआई इकाइयों (इकाइयों की अंतर्राष्ट्रीय प्रणाली से) के साथ टिक लेबल को अच्छी तरह से प्रारूपित करने के लिए उपयोग कर रहा है। यह अधिकांश हिस्सों के लिए खूबसूरती से काम करता है, कुछ मानों को छोड़कर जो गोल करने वाली त्रुटि में चलते हैं और दशमलव स्थानों का एक टन लौटाते हैं (उदाहरण के लिए, 1400 * 0.001 = 1.4000000000000001)।d3.format

इस के आसपास पाने के लिए मैं एक परिशुद्धता निर्दिष्ट कर सकता हूं, जैसे d3.format ("। 2s") लेकिन यह उन मामलों में 2 महत्वपूर्ण अंक बलों को लागू करता है जहां 1 बेहतर होगा। उदाहरण के लिए, यदि मेरे पास टिक [5000, 10000, 15000] हैं तो मैं अब [5.0k, 10k, 15k] देखूंगा। मूल रूप से जब मैंने सटीकता निर्दिष्ट नहीं की तो मुझे [5k, 10k, 15k] मिला।

मुझे आश्चर्य है कि अधिकतम सटीकता निर्दिष्ट करना संभव है जैसे कि यह केवल तभी लागू होगा जब महत्वपूर्ण अंकों की संख्या निर्दिष्ट संख्या से अधिक हो? तो 5000 5k होगा और 5.0k नहीं होगा।

उत्तर

2

आप किसी अज्ञात फ़ंक्शन में if/else कथन डालकर ऐसा कर सकते हैं जहां आप टेक्स्ट स्ट्रिंग आउटपुट करेंगे। उसमें अगर आप किसी भी स्थिति को संतुष्ट कर सकते हैं और फ़ंक्शन बना सकते हैं जो आपके मान को पार करता है। यहां एक उदाहरण दिया गया है:

var w = 30, h = 300; 
var data = [ 
    {'point':1, 'value':100.005}, 
    {'point':2, 'value':20.010}, 
    {'point':3, 'value':1000}, 
    {'point':4, 'value':5000.099}, 
    {'point':5, 'value':6000.934}, 
    {'point':6, 'value':9000.888}, 
    {'point':7, 'value':500.22}, 
    {'point':8, 'value':5.123}, 
    {'point':9, 'value':50.022}, 
    {'point':10, 'value':7000.999} 
]; 
var chart = d3.select("body").append("svg") 
    .attr('class', 'chart') 
    .attr("width", w * data.length - 1) 
    .attr("height", h); 

chart.selectAll('text') 
    .data(data) 
.enter().append('text') 
    .attr('x', function(d, i) { return x(i); }) 
    .attr('y', function(d) { return h - y(d.value); }) 
    .attr('dx', '0.75em') 
    .attr('dy', '-0.3em') 
    .attr('text-anchor', 'start') 
    .text(function(d) { 
    if(d.value > 5000) { 
     // Define your formatting function to return SI units 
     var si = d3.format('s'); 
     return String(si(d.value)); 
    } else { 
     // Otherwise round to the nearest integer 
     return String(d3.round(d.value, 0)); 
    } 
    }); 

आशा है कि मदद करता है।

+0

उत्तर के लिए धन्यवाद। दुर्भाग्यवश, मैं d3.svg.axis सहायक का उपयोग कर रहा हूं, इसलिए जिन प्रारूपों को मैं स्वरूपित कर रहा हूं वे मान मान हैं, डेटा मान नहीं। स्वरूपण आंतरिक रूप से किया जाता है क्योंकि टिक लेबल उत्पन्न होते हैं। मैं मूल्यों को रोकने के लिए अपने स्वयं के फ़ंक्शन में d3.format से वापस फ़ंक्शन को लपेट सकता हूं लेकिन एसआई फॉर्मेटर से लौटाई गई स्ट्रिंग को फिर से पार्स करना बहुत साफ नहीं लगता है। मैं सोच रहा था कि इसे कोडिंग किए बिना इसका समर्थन करने के लिए फॉर्मेटर में कुछ बनाया जा सकता है। –

+0

आह सही। मेरा कोड डेटा लेबल के लिए है, लेबल पर टिकटें नहीं। आशा है कि मैंने आपको गलत रास्ते का नेतृत्व नहीं किया है। क्या आप कुछ ऐसा ही कर सकते हैं, लेकिन टिक लेबलिंग फ़ंक्शंस के साथ (यानी उन्हें अज्ञात func में पास करें)? – tatlar

2

जबकि 1400 * .001 1.4000000000000001 है, 1400/1000 1.4 है; दस (जैसे .001) की नकारात्मक शक्ति से एक पूर्णांक गुणा करने से गोलाकार त्रुटि हो सकती है, लेकिन ऐसा लगता है कि दस की शक्ति (जैसे 1000) द्वारा एक पूर्णांक को विभाजित करना नहीं है। या कम से कम, यह कम संभावना है? मैंने फिक्स-सी-फॉर्मेट-राउंडिंग शाखा में एक टिकाऊ फिक्स लागू किया है। यह सख्ती से पीछे की तरफ असंगत है, लेकिन d3.formatPrefix फ़ंक्शन अनियंत्रित है, इसलिए मुझे लगता है कि अगली पैच रिलीज़ में शामिल होना सुरक्षित होगा।

संपादित करें: यह फ़िक्स संस्करण 2.9.2 में जारी किया गया था।

+0

दिलचस्प है कि उन दो संचालन अलग-अलग परिणाम उत्पन्न करते हैं। मैं अनुमान लगाया नहीं होगा। मैं अगले पैच में इस फिक्स के लिए अपनी आंखों को छील दूंगा। धन्यवाद! –