2013-07-24 11 views
6

W d3, selection.select ma efekt uboczny dziedziczenia danych z węzłów nadrzędnych w pierwotnym wyborze. Jest to pożądane w sytuacjach, w których dane są współużytkowane przez węzły nadrzędne i podrzędne, dzięki czemu zaktualizowane dane powiązane z rodzica zostaną przekazane dziecku bez konieczności łączenia danych na każdym poziomie.Zapobieganie niepożądanemu dziedziczeniu danych za pomocą selection.select

Ale co z sytuacjami, w których nie ma wyraźnego związku pomiędzy danymi powiązanymi z rodzicem a danymi powiązanymi z dzieckiem? W tej sytuacji selection.select może być podstępny, ponieważ po prostu wybierając węzeł powoduje, że dane tego węzła zostaną zbite z niepowiązanymi danymi macierzystymi.

Jaka jest najlepsza technika unikania tego? Mogę myśleć o kilka opcji, ale nie wydaje się wspaniałe:

  1. Zawsze używaj selection.selectAll wszędzie z wyjątkiem przypadków, w których dane są ukryte dziedzictwo chcieli. Nie jest to jednak idealne, ponieważ powoduje, że użycie selection.select jest niezgodne z d3.select, które jest używane po prostu do wybrania pojedynczego węzła (dokładnie to, co chcę zrobić z selection.select).

  2. Użyj d3.select z descendents selector zamiast selection.select, aby wyizolować określony węzeł. Wygodną rzeczą w używaniu selection.select jest to, że pośrednio ogranicza wybór do potomków początkowego zaznaczenia. Osiągnięcie tego za pomocą selektora nie jest tak miłe.

Osobiście nie jestem wielkim fanem posiadające DOM-państwowego modyfikując efekt uboczny w jednej konkretnej postaci niektóre z najczęściej używanych funkcji w API. Myślę, że łatwiej byłoby mi zrozumieć, czy jednoznaczne połączenie, takie jak selection.update(selector), jest symetryczne z selection.append i selection.insert.

Ale w bieżącym API, zastanawiam się, czy istnieje jakiś inny mechanizm, który może być użyty do skutecznego złamania dziedziczenia przy użyciu selection.select?

+0

Może coś podnieść na https://github.com/mbostock/d3/issues –

+0

Zgadzam się, że może to być problematyczne.Używam d3 do rysowania złożonych wykresów z zagnieżdżonymi elementami svg, a gdy chcę wybrać element potomny czegoś, używam something.select() i dane, które przywiązuję do dzieci, są tracone! Zajęło mi trochę czasu, aby dowiedzieć się, gdzie jest problem ... Chociaż nie mogę twierdzić, że ta ukryta funkcja może być przydatna w niektórych przypadkach, powoduje również niechciane wyniki w innych. Posiadanie opcji wyłączenia tego domyślnego zachowania będzie bardzo docenione. –

+0

Czy pomogłoby usunąć podselekcje danych za pomocą '.datum ([])' [like this] (http://mistakes.io/#6239812)? Nie jestem pewien, czy to rozumiem. – Anko

Odpowiedz

1

W efekcie przesłałem problem na D3 Github: https://github.com/mbostock/d3/issues/1443. Nie ma żadnej rozdzielczości, ale jest (myślę) interesująca dyskusja na temat problemu. Na samym dole Mike oferuje obejście, które zadziała, a które wkleję tutaj dla wygody:

Nie jest to dobra odpowiedź, ale jednym ze sposobów zapobiegania dziedziczeniu danych jest posiadanie węzła pośredniego bez powiązanych danych.

var intermediary = selection.append("div") 
    .datum(function() { return null; }); 

Następnie dowolny wybór pośrednika nie będzie propagował danych z wyboru rodzica. Ale oczywiście węzeł pośredni w DOM jest trochę niefortunny.

0

Można użyć:

d3.select(selection.node().querySelector(selector)) 

Zobacz go w akcji w tym jsfiddle który rozciąga prototyp naboru w metodzie selectWithoutDataPropagation().

Powiązane problemy