2017-12-13 96 views
6

का उपयोग करके ओवरलैप पर दो मंडलियों के रंग को कैसे बदलें, हैलो मैं जानना चाहूंगा कि यह कैसे संभव होगा दो यह बनाते हैं कि दो मंडल ओवरलैप होने पर रंग बदलते हैं। अधिमानतः जो अनुभाग ओवरलैप किया गया है वह सेट का प्रतिनिधित्व करने के लिए सफेद हो जाएगा।डी 3 लाइब्रेरी

var canvas = d3.select("canvas"), 
 
    context = canvas.node().getContext("2d"), 
 
    width = canvas.property("width"), 
 
    height = canvas.property("height"), 
 
    radius = 32; 
 

 
var circles = d3.range(4).map(function(i) { 
 
    return { 
 
    index: i, 
 
    x: Math.round(Math.random() * (width - radius * 2) + radius), 
 
    y: Math.round(Math.random() * (height - radius * 2) + radius) 
 
    }; 
 
}); 
 

 
var color = d3.scaleOrdinal() 
 
    .range(d3.schemeCategory20); 
 

 
render(); 
 

 
canvas.call(d3.drag() 
 
    .subject(dragsubject) 
 
    .on("start", dragstarted) 
 
    .on("drag", dragged) 
 
    .on("end", dragended) 
 
    .on("start.render drag.render end.render", render)); 
 

 
function render() { 
 
    context.clearRect(0, 0, width, height); 
 
    for (var i = 0, n = circles.length, circle; i < n; ++i) { 
 
    circle = circles[i]; 
 
    context.beginPath(); 
 
    context.moveTo(circle.x + radius, circle.y); 
 
    context.arc(circle.x, circle.y, radius, 0, 2 * Math.PI); 
 
    context.fillStyle = color(circle.index); 
 
    context.fill(); 
 
    if (circle.active) { 
 
     context.lineWidth = 2; 
 
     context.stroke(); 
 
    } 
 
    } 
 
} 
 

 
function dragsubject() { 
 
    for (var i = circles.length - 1, circle, x, y; i >= 0; --i) { 
 
    circle = circles[i]; 
 
    x = circle.x - d3.event.x; 
 
    y = circle.y - d3.event.y; 
 
    if (x * x + y * y < radius * radius) return circle; 
 
    } 
 
} 
 

 
function dragstarted() { 
 
    circles.splice(circles.indexOf(d3.event.subject), 1); 
 
    circles.push(d3.event.subject); 
 
    d3.event.subject.active = true; 
 
} 
 

 
function dragged() { 
 
    d3.event.subject.x = d3.event.x; 
 
    d3.event.subject.y = d3.event.y; 
 
} 
 

 
function dragended() { 
 
    d3.event.subject.active = false; 
 
}
<canvas width="800" height="500"></canvas> 
 
<script src="//d3js.org/d3.v4.min.js"></script>

मेरे आदर्श समाधान कुछ है कि मुझे 2 सेट के बीच चौराहे का प्रतिनिधित्व करने के लिए एक और रंग के लिए ओवरलैपिंग अनुभाग का रंग बदलने के लिए अनुमति देते हैं होगा।

अग्रिम धन्यवाद

संपादित करें: कुछ अपडेट हालांकि Ive केवल कैसे स्थिर तत्वों के लिए रंग करने के लिए के बजाय

var x1 = 100, 
 
     y1 = 100, 
 
     x2 = 150, 
 
     y2 = 150, 
 
     r = 70; 
 

 
    var svg = d3.select('svg') 
 
     .append('svg') 
 
     .attr('width', 500) 
 
     .attr('height', 500); 
 

 
    svg.append('circle') 
 
     .attr('cx', x1) 
 
     .attr('cy', y1) 
 
     .attr('r', r) 
 
     .style('fill', 'steelblue') 
 
     .style("fill-opacity",0.5) 
 
     .style("stroke","black"); 
 

 
    svg.append('circle') 
 
     .attr('cx', x2) 
 
     .attr('cy', y2) 
 
     .attr('r', r) 
 
     .style('fill', 'orange') 
 
     .style("fill-opacity",0.5) 
 
     .style("stroke","black"); 
 

 
    var interPoints = intersection(x1, y1, r, x2, y2, r); 
 

 
    svg.append("g") 
 
     .append("path") 
 
     .attr("d", function() { 
 
     return "M" + interPoints[0] + "," + interPoints[2] + "A" + r + "," + r + 
 
      " 0 0,1 " + interPoints[1] + "," + interPoints[3]+ "A" + r + "," + r + 
 
      " 0 0,1 " + interPoints[0] + "," + interPoints[2]; 
 
     }) 
 
     .style('fill', 'red') 
 
     .style("fill-opacity",0.5) 
 
     .style("stroke","black"); 
 

 

 
    function intersection(x0, y0, r0, x1, y1, r1) { 
 
     var a, dx, dy, d, h, rx, ry; 
 
     var x2, y2; 
 

 
     /* dx and dy are the vertical and horizontal distances between 
 
     * the circle centers. 
 
     */ 
 
     dx = x1 - x0; 
 
     dy = y1 - y0; 
 

 
     /* Determine the straight-line distance between the centers. */ 
 
     d = Math.sqrt((dy * dy) + (dx * dx)); 
 

 
     /* Check for solvability. */ 
 
     if (d > (r0 + r1)) { 
 
     /* no solution. circles do not intersect. */ 
 
     return false; 
 
     } 
 
     if (d < Math.abs(r0 - r1)) { 
 
     /* no solution. one circle is contained in the other */ 
 
     return false; 
 
     } 
 

 
     /* 'point 2' is the point where the line through the circle 
 
     * intersection points crosses the line between the circle 
 
     * centers. 
 
     */ 
 

 
     /* Determine the distance from point 0 to point 2. */ 
 
     a = ((r0 * r0) - (r1 * r1) + (d * d))/(2.0 * d); 
 

 
     /* Determine the coordinates of point 2. */ 
 
     x2 = x0 + (dx * a/d); 
 
     y2 = y0 + (dy * a/d); 
 

 
     /* Determine the distance from point 2 to either of the 
 
     * intersection points. 
 
     */ 
 
     h = Math.sqrt((r0 * r0) - (a * a)); 
 

 
     /* Now determine the offsets of the intersection points from 
 
     * point 2. 
 
     */ 
 
     rx = -dy * (h/d); 
 
     ry = dx * (h/d); 
 

 
     /* Determine the absolute intersection points. */ 
 
     var xi = x2 + rx; 
 
     var xi_prime = x2 - rx; 
 
     var yi = y2 + ry; 
 
     var yi_prime = y2 - ry; 
 

 
     return [xi, xi_prime, yi, yi_prime]; 
 
    }
<script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> 
 
<svg width="500" height="500"></svg>

चलती पाया किए गए हैं^यह statics

के लिए काम करता है

^यह मेरी चलती हलकों है कि मैं जोड़ना चाहते हैं कहा पर प्रभाव है।

क्या यह प्राप्त करने के लिए दो कोडों को गठबंधन करने का कोई तरीका है? फिर

+0

शायद इसे प्राप्त करने का एक तरीका 'context.globalCompositeOperation' प्रॉपर्टी (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) के साथ हो सकता है। लेकिन मुझे यकीन नहीं है कि आप ओवरलैपिंग सेक्शन के लिए अपने रंग को कस्टमाइज़ कर सकते हैं। – JulCh

+0

यह चलती मंडलियों के साथ काम नहीं कर रहा है और मैं कैनवास के विपरीत svg का भी उपयोग कर रहा हूं। मुझे थोड़े समय के लिए काम करने के लिए एक रास्ता मिल गया है, जबकि स्थिर है लेकिन चलते समय नहीं। – Cormanno

उत्तर

0

SVG mix-blend-mode

एसवीजी screen से normal

करने के लिए mix-blend-mode मंडराना

धन्यवाद यह वह जगह है वास्तव में क्या नहीं आप के लिए है, क्योंकि यह नहीं करता है आप प्रोग्राम अंतर्विभाजक के रंग को नियंत्रित देख रहे हैं सेगमेंट, लेकिन सीएसएस mix-blend-mode एक बहुत ही सरल समाधान है जिसका मैंने डी 3 के साथ उपयोग किया है। मैंने एक ही चीज़ को पूरा करने की कोशिश की है लेकिन बड़े डेटासेट को एनिमेट करने पर चौराहे की गणना करने वाली प्रदर्शन समस्याओं में भाग गया है। Compatibility चिंता का विषय हो सकता है अगर इसे आईई/एज में काम करने की ज़रूरत है, लेकिन अन्यथा अधिकांश मोड क्रोम, फ़ायरफ़ॉक्स और सफारी (यहां तक ​​कि मोबाइल) में समर्थित हैं।

यहां एक अच्छा guide with examples डी 3 पर और एक सरलीकृत Codepen snippet है।

अन्यथा ऐसा लगता है कि आपको पहले से ही D3.js - detect intersection area मिल गया है। ड्रैग के साथ काम करने के लिए, आपको निर्धारित करने के लिए गणना लिखनी होगी, जो मंडल ओवरलैपिंग कर रहे हैं, फिर उनके चौराहे क्षेत्र की गणना करें।