2013-05-28 9 views
8

मैं d3.js. के साथ एक मानचित्र विज़ुअलाइज़ेशन का निर्माण कर रहा हूं। मैं अमेरिका के राज्यों और काउंटी दोनों के लिए भरे बहुभुज चित्रित कर रहा हूं। काउंटी के लिए एसवीजी परत राज्यों के लिए परत के नीचे है। राज्य भर गए हैं, लेकिन भरने की अस्पष्टता 0 पर सेट है; भरने की घटनाओं को पकड़ने के लिए भरना आवश्यक है (मुझे लगता है)।ओवरलैपिंग एसवीजी परतों में माउस इवेंट्स को संभालना

मैं राज्य स्तर पर क्लिक घटनाओं को पकड़ना चाहता हूं, लेकिन मैं काउंटी स्तर पर माउसओवर घटनाओं को पकड़ना चाहता हूं।

हालांकि, माउसओवर घटना राज्यों द्वारा कब्जा कर लिया गया है और काउंटी तक नहीं पारित किया गया है।

क्या कोई परत नीचे ईवेंट को पास करने का कोई तरीका है या अन्यथा काउंटर पर माउसओवर ईवेंट ट्रिगर करना है?

+0

क्या आपके पास उपयोग किए जा रहे उदाहरण का लिंक है? –

उत्तर

2

यदि आप किसी राज्य पर क्लिक करते समय कुछ करना चाहते हैं, जैसे सीमा रेखा बदलने या आकार की अस्पष्टता, तो आप इस तथ्य का उपयोग कर सकते हैं कि प्रत्येक काउंटी एक राज्य से संबंधित है और राज्यों में काउंटी को समूहित करती है, कैप्चरिंग काउंटी में 'क्लिक' ईवेंट, संबंधित राज्य तत्व का चयन करें और इसके दृश्य विशेषताओं को बदलें। इस अभियान का mockup: http://jsfiddle.net/pnavarrc/PGTCM/5/:

// Setup the visualization, assuming that you have a div with id 'chart' 
var width = 300, 
    height = 300, 
    div = d3.select('#chart'), 
    svg = div.append('svg') 
     .attr('width', width) 
     .attr('height', height); 

// Array of states, each one containing one or more counties. In this example, 
// the states are rectangles, but you get the idea 
var states = [ 
    { 
     width: 300, 
     height: 300, 
     name: 'Fake State', 
     counties: [ 
      {x: 5, y: 5, width: 95, height: 290, fill: '#b4a0a0'}, 
      {x: 100, y: 5, width: 150, height: 290, fill: '#b4c0a0'}, 
      {x: 250, y: 5, width: 45, height: 290, fill: '#a4a0c0'} 
     ] 
    }]; 

// Create a group for each state, with class state 
var gstates = svg.selectAll('g.state') 
    .data(states) 
    .enter() 
    .append('g') 
    .classed('state', true); 

// Add the state background, in this case, a transparent rectangle 
gstates 
    .append('rect') 
    .classed('state', true) 
    .attr('width', function(d) { return d.width; }) 
    .attr('height', function(d) { return d.height; }) 
    .attr('fill', '#444') 
    .attr('fill-opacity', 0.0); 

// For each group, add rectangles for each county, binding them to the 
// county array of each state. 
gstates.selectAll('rect.county') 
    .data(function(d) { return d.counties; }) 
    .enter() 
    .append('rect') 
    .classed('county', true) 
     .attr('x', function(d) { return d.x; }) 
     .attr('y', function(d) { return d.y; }) 
     .attr('width', function(d) { return d.width; }) 
     .attr('height', function(d) { return d.height; }) 
     .attr('fill', function(d) { return d.fill; }) 
     .on('mouseover', function() { 
      d3.select(this).attr('fill-opacity', 0.5); 
     }) 
     .on('mouseout', function() { 
      d3.select(this).attr('fill-opacity', 0.9); 
     }) 
     .on('click', function() { 
      // Retrive the parent group of each county, and then select 
      // the shape corresponding to the state and alter its properties 
      // you can also access the state data 
      var parent = d3.select(d3.select(this).node().parentNode), 
       state = parent.select('rect.state'); 
       // Output 'Fake State' 
       console.log(parent[0][0].__data__.name); 
       state.attr('fill-opacity', 1.0); 
     }); 

एक काम बेला यहाँ नहीं है। विनम्र,

6

यहां एक डी 3 फ़ंक्शन है जो आप चाहते हैं।

यह शीर्ष परत पर पॉइंटर घटनाओं को अस्थायी रूप से अक्षम करके और अगली परत पर माउस ईवेंट को मैन्युअल रूप से ट्रिगर करके परतों को कम करता है।

function passThruEvents(g) { 
    g .on('mousemove.passThru', passThru) 
     .on('mousedown.passThru', passThru) 
    ; 

    function passThru(d) { 
     var e = d3.event; 

     var prev = this.style.pointerEvents; 
     this.style.pointerEvents = 'none'; 

     var el = document.elementFromPoint(d3.event.x, d3.event.y); 

     var e2 = document.createEvent('MouseEvent'); 
     e2.initMouseEvent(e.type,e.bubbles,e.cancelable,e.view, e.detail,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget); 

     el.dispatchEvent(e2); 

     this.style.pointerEvents = prev; 
    } 
} 
+0

भयानक समाधान! – rockTheWorld

+1

यह समाधान अन्य परिस्थितियों में अनुकूलित करने के लिए कमाल और आसान है, हालांकि, शीर्ष तत्व द्वारा "अस्पष्ट" तत्व 'होवर' के माध्यम से स्टाइल-सक्षम नहीं होंगे, मैं वास्तव में इसे ठीक करना भी चाहूंगा। – luismreis

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