2012-11-01 4 views
5

Próbuję ustawić etykietę narzędzia dla ścieżki obszaru, który utworzyłem. Sprawdziłem wszystkie argumenty przekazywane do obsługi zdarzenia on mousemove i właśnie otrzymuję pełny zestaw danych, 0, 0. Nic nie wskazuje na mój indeks w danych, o ile widzę. "Ten" kontekst to także element ścieżki SVG. Wciąż nic przydatnego. Nawet spojrzał na d3.select (this), i nie mogę znaleźć nigdzie tam wskaźnika. Czy jest jakiś sposób, aby ustalić, nad którym punktem danych znajduje się moja mysz?Korzystając z biblioteki JavaScript D3, jak określić pozycję myszy w zestawie danych elementu obszaru podczas zdarzenia mousemove?

Rozglądając się znalazłem odniesienie do d3.mouse (this) i to daje mi współrzędną x/y, ale jak mogę odwzorować to z powrotem do punktu danych w zbiorze danych?

Moim celem jest posiadanie podpowiedzi do wyświetlania niektórych metadanych związanych z tym konkretnym punktem danych w zestawie.

Oto niektóre fragmenty kodu wnioskowane:

var area=d3.svg.area() 
    .interpolate("monotone") 
    .x(function(d){ 
     return(scale.x(d.date)); 
    }) 
    .y0(height-padding.bottom) 
    .y1(function(d){ 
     return(scale.y(d.count)); 
    }); 

var path=svg.append('path') 
      .datum(data) 
      .attr('d',area) 
      .attr("clip-path", "url(#clip)") 
      .attr('fill','url(#gradient)') 
      // .attr('title','path') 
      .on('mousemove',function(){ 
       console.log(arguments); 
       console.log(d3.select(this)); 
       console.log(d3.mouse(this));   
      });   
+0

Możesz opublikować JavaScript? lub krótki przykład, aby go odtworzyć? –

+0

Zazwyczaj narysowałeś jakiś element nad punktem danych (np. Kółkiem), aby nadać mu tytuł http://www.mecxpert.de/svg/tooltips.html – Duopixel

+0

Chciałem uniknąć dodawania kolejnych elementów, ponieważ używam suwaka jQuery UI do sterowania powiększaniem widoku za pomocą skali czasu X i ścieżki klipu. Więcej elementów również musi być kontrolowanych w ten sam sposób. Jeśli to jest to, co muszę zrobić, niech tak będzie, wydaje się, że powinno być czystszy sposób. Nie wiesz, dlaczego program obsługi zdarzeń mousemove nie otrzymuje żadnych użytecznych argumentów. –

Odpowiedz

2

Twój problem jest nie tyle związane ze zdarzeniem słuchacza mouseover, ale bardziej na sposób powiązać dane na swojej drodze; nie wykonujesz poprawnego sprzężenia danych.

Więcej o dane dołącza: http://bost.ocks.org/mike/join/

Poniższy przykład używa div zamiast ścieżek, ale zasada jest taka sama. Patrz przykład w pracy: http://jsfiddle.net/RghQn/

var data = ['a', 'b', 'c']; 
d3.select("body").selectAll("div") 
    .data(data) 
    .enter().append("div") 
    .text(String) 
    .on("mouseover", function(d,i) { 
     console.log("mouseover!"); 
     // d: bound datum to DOM element 
     console.log("d: ", d); 
     // i: index of the selection 
     console.log("i: ", i); 
     // this context: the current DOM element 
     console.log(d3.select(this).text()); 
    }); 
​​​​​​​​​​​​​​​ 

również sekcja Dokumentacja API o słuchacza zdarzenia: https://github.com/mbostock/d3/wiki/Selections#wiki-on

selection.on (typ [, detektor [przechwycenie]])

Dodaje lub usuwa detektor zdarzeń do każdego elementu z bieżącego wyboru dla określonego typu. Typ to nazwa zdarzenia łańcuchowego o nazwie , np. "Kliknij", "najechanie kursorem myszy" lub "wyślij". Określony detektor jest wywoływany w taki sam sposób, jak inne funkcje operatora, przekazując bieżący punkt odniesienia d i indeks i, w tym kontekście jako bieżący element DOM. Aby uzyskać dostęp do bieżącego wydarzenia, należy użyć globalnego d3.event.


EDIT

Wiem sobie sprawę, że źle zrozumiał pytanie. Masz jedną ścieżkę i chcesz uzyskać informacje o współrzędnych ścieżki w miejscu myszy.

Nie jest to proste. Możesz zobaczyć, jak Mike zrobił to w następującym przykładzie: http://bl.ocks.org/3902569

+0

Dzięki za odpowiedź. Ta metoda wydaje się działać dobrze dla rzeczy takich jak div czy SVG rect, ale nie mogę jej uruchomić dla ścieżki SVG. Po prostu nie zostanie narysowany ani dodany do rodzica SVG. Wszystkie przykłady robią to w inny sposób. Takich jak http://bl.ocks.org/3883195 ze strony przykładów D3. –

+0

Znalazłem sposób przy użyciu .data ([dane]) zamiast .datum (dane). I to nadal poprawnie rysuje obszar. To ma zrobić połączenie danych. Jednak zdarzenie mousemove nadal zwraca te same dane. –

+0

Chodzi o to, że patrzysz na jeden element ścieżki SVG. Ten element nie zawiera już informacji o oryginalnych punktach danych. Generator d3.svg.area() odebrał twoje punkty danych i przekształcił je w jedną ciągłą ścieżkę, używając dowolnego interpolatora, który podałeś. Tak więc nie ma pojedynczych elementów DOM dla kursora myszy, które odpowiadają Twojemu zestawowi danych. Będziesz musiał dodać te elementy punktów danych (np. Okręgi), jak wspomniano w Duopixelu. – nautat

6

@nautat ma poprawną odpowiedź w swojej edycji, ale chciałbym ją rozwinąć, ponieważ z jakiegoś powodu przykłady bloków rzadko mają komentarze i mogą być podobne rozkładanie cudzego origami.

To obowiązujących, odnośnych część z http://bl.ocks.org/3902569 ... Komentarze po drodze są moje

// define a function for mouse move 
// this function is wired up to the visualization elsewhere with .on('mousemove', fn) 
function mousemove() { 
    // using the x scale, in this case a d3 time scale 
    // use the .invert() function to interpolate a date along the scale 
    // given the x-coordinates of the mouse 
    var x0 = x.invert(d3.mouse(this)[0]), 

    // using the interpolated date, find an index in the sorted data 
    // this would be the index suitable for insertion 
    i = bisectDate(data, x0, 1), 

    // now that we know where in the data the interpolated date would "fit" 
    // between two values, pull them both back as temporaries 
    d0 = data[i - 1], 
    d1 = data[i], 

    // now, examine which of the two dates we are "closer" to 
    // to do this, compare the delta values 
    d = x0 - d0.date > d1.date - x0 ? d1 : d0; 

    // move the "focus" element into position 
    // we find the X and Y values for the new position using the x and y scales 
    // using the closest data point to the mouse 
    focus.attr("transform", "translate(" + x(d.date) + "," + y(d.close) + ")"); 

    // set the text of the "focus" element to be the value of the element selected 
    focus.select("text").text(formatCurrency(d.close)); 
} 
+0

Dziękuję @ flf za wyjaśnienie, bardzo pomocne! – caffeinescript

Powiązane problemy