2012-08-31 4 views
9

मैं एक हीटमैप लागू कर रहा हूं जिसमें सेल पृष्ठभूमि रंग डी 3 रंग पैमाने द्वारा निर्धारित किया जाता है। कुछ मूल्य स्पष्ट हैं; उनका मूल्य एन अलग-अलग मनमानी स्ट्रिंग-प्रकार श्रेणियों जैसे ["6TH", "7TH", "5TH", "4TH"] हो सकता है।तारों के अलग डोमेन से निरंतर रंग स्केल?

एक प्रारंभ रंग d3.rgb ("नीला") और एक अंत रंग d3.rgb ("लाल") दिया गया है, मैं रंगीन पैमाने का निर्माण कैसे कर सकता हूं जो एक निरंतर रंग सीमा में तारों के एक अलग डोमेन को मानचित्रित कर सकता है?

मैं

var scale = d3.scale.ordinal() 
    .domain(["6TH", "7TH", "5TH", "4TH"]) 
    .rangeBands([ d3.rgb("blue"), d3.rgb("red") ]); 

जो स्पष्ट रूप से काम नहीं करता है की कोशिश की।

उत्तर

29

सबसे पहले, मैं आसानी से उपलब्ध रंगब्रॉवर स्केल का उपयोग करने पर विचार करता हूं; colorbrewer2.org देखें। ये डी 3 के गिट भंडार में जावास्क्रिप्ट और सीएसएस फाइलों के रूप में भी उपलब्ध हैं; lib/colorbrewer देखें। उदाहरण के लिए, अगर आप अपने डोमेन चार असतत मूल्यों है, और आप एक लाल-नीले अपसारी पैमाने चाहते हैं, आप कह सकते हैं:

var color = d3.scale.ordinal() 
    .domain(["6TH", "7TH", "5TH", "4TH"]) 
    .range(colorbrewer.RdBu[4]); 

ColorBrewer है (। आप एक <script src="colorbrewer.js"></script> कहीं इस से पहले भी आवश्यकता होगी) विभिन्न तरह के डिजाइन किए गए अनुक्रमिक, अलग-अलग और स्पष्ट रंग के तराजू।

यदि आप अपना खुद का रंग स्केल रोल करने का आग्रह करते हैं, तो मैं सटीक धारणा के लिए L*a*b* or HCL color space में इंटरपोलेट करने की दृढ़ता से अनुशंसा करता हूं। आप इसे d3.interpolateLab या d3.interpolateHcl का उपयोग करके कर सकते हैं। उदाहरण के लिए, d3.interpolateLab("red", "blue")(.5) लाल और नीले रंग के बीच आधा रंग देता है।

अपने ordinal पैमाने की सीमा के लिए रंगों की गणना करने के लिए, आप एक इंटरपोलेटर का उपयोग कर सकते हैं, या आप एक अस्थायी रैखिक पैमाने अधिक सुविधाजनक पा सकते हैं।उदाहरण के लिए:

var categories = ["6TH", "7TH", "5TH", "4TH"]; 

var color = d3.scale.ordinal() 
    .domain(categories) 
    .range(d3.range(categories.length).map(d3.scale.linear() 
     .domain([0, categories.length - 1]) 
     .range(["red", "blue"]) 
     .interpolate(d3.interpolateLab))); 
+1

अद्यतन: D3 का Colorbrewer lib [d3-scale-chromatic] (https://github.com/d3/d3-scale-chromatic) भंडार में स्थानांतरित हो गया है। – danasilver

3

आपके पास सही विचार है, आपको बस प्रत्येक आर/जी/बी रंग चैनल को संसाधित करने की आवश्यकता है। उदाहरण के लिए, वेनिला में जावास्क्रिप्ट आप निम्न कर सकते हैं:

# d3.rgb(color):

var a = [255, 0, 0], // First color 
    b = [0, 0, 255], // Other color 
    bands = 5,  // Bands is the length of your domain 
    i, 
    delta = [];  // Difference between color in each channel 

// Compute difference between each color 
for (i = 0; i < 4; i++){ 
    delta[i] = (a[i] - b[i])/(bands + 1); 
} 

// Use that difference to create your bands 
for (i = 0; i <= bands + 1; i++){ 
    var r = Math.round(a[0] - delta[0] * i); 
    var g = Math.round(a[1] - delta[1] * i); 
    var b = Math.round(a[2] - delta[2] * i); 
    console.log("<div style='background-color: #" + dec2hex(r) + dec2hex(g) + dec2hex(b) + "'>Band " + i + "</div>"); 
} 

// A helper function for formatting 
function dec2hex(i) { 
    return (i+0x100).toString(16).substr(-2).toUpperCase(); 
} 

d3 documentation के अनुसार, यदि आपके पास रंगीन वस्तु की r, g और b विशेषताओं का उपयोग प्रत्येक रंग चैनल निकाल सकते हैं

निर्दिष्ट रंग स्ट्रिंग को पार्स करके एक नया आरजीबी रंग बनाता है। अगर रंग एक स्ट्रिंग नहीं है, तो यह एक स्ट्रिंग के लिए मजबूर है; इस प्रकार, इस कन्स्ट्रक्टर का उपयोग मौजूदा रंग की प्रतिलिपि बनाने के लिए भी किया जा सकता है, या डी 3 एचएसएल रंग के आरजीबी में रूपांतरण को मजबूर कर सकता है।

...

जिसके परिणामस्वरूप रंग श्रेणी [0255] में लाल, हरे और नीले रंग के पूर्णांक चैनल मूल्यों के रूप में संग्रहीत किया जाता है। चैनल लौटे ऑब्जेक्ट के आर, जी और बी गुणों के रूप में उपलब्ध हैं।

इसलिए उपरोक्त उदाहरण के शीर्ष पर, आप कह सकते हैं:

var myColor = d3.rgb("blue"), 
    a = [myColor.r, myColor.g, myColor.b], 
... 

कि मदद करता है?

+0

हाँ, इसके निश्चित रूप से मदद की! धन्यवाद, पूरी तरह से काम करते हैं। – ekerner

0

आप हमेशा एक औपचारिक पैमाने और एक रैखिक पैमाने को श्रृंखलाबद्ध कर सकते हैं।

पहला पैमाने आपके अलग-अलग मूल्यों से मात्रात्मक मूल्य बनाएगा, और दूसरा पैमाने इन मानों को रंग पैमाने पर विभाजित करेगा।

कुछ इस तरह:

// Your categories 
 
var data = ["6TH", "7TH", "5TH", "4TH"], 
 

 
    // Define ordinal to linear scale... 
 
    ordinal = d3.scale.ordinal().domain(data).rangePoints([0, 1]), 
 

 
    // ...and linear to color scale 
 
    linear = d3.scale.linear().domain([0, 1]).range([d3.rgb("blue"), d3.rgb("red")]); 
 

 
// Now define your artificial 'compound' scale 
 
function scale(d) { 
 
    return linear(ordinal(d)); 
 
} 
 

 
// And then use it on your D3 code 
 
d3.selectAll('div') 
 
    .data(data) 
 
    .enter() 
 
    .append('div') 
 
    .style('background', scale) // <- et voilà ;) 
 
    .text(function(d) { 
 
    return d; 
 
    });
div { 
 
    color: white; 
 
    width: 3em; 
 
    padding: 1em; 
 
    margin: .2em 
 
    text-align: center; 
 
    font-family: Arial, Helvetica, sans-serif; 
 
    font-weight: bold 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

संबंधित मुद्दे