Próbuję wybrać odpowiednią technologię do aktualizacji projektu, która w zasadzie renderuje tysiące punktów na powiększalnym, przesuwalnym wykresie. Obecna implementacja przy użyciu Protovis jest gorsza. Sprawdź to tutaj:
http://www.planethunters.org/classify
Po całkowitym oddaleniu jest około 2000 punktów. Spróbuj użyć uchwytów na dole, aby nieco powiększyć, i przeciągnij, aby przesuwać. Zobaczysz, że jest dość niestabilny, a zużycie procesora prawdopodobnie wzrasta do 100% na jednym rdzeniu, chyba że masz naprawdę szybki komputer. Każda zmiana w obszarze ostrości wywołuje przerysowanie do protovis, które jest cholernie wolne i jest gorsze, gdy rysuje się więcej punktów.
Chciałbym dokonać pewnych aktualizacji interfejsu, a także zmienić podstawową technologię wizualizacji, aby była bardziej responsywna podczas animacji i interakcji. Z poniższego artykułu wynika, że można wybrać między inną biblioteką opartą na SVG lub biblioteką opartą na płótnie:
http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/
d3.js , który wyrósł z Protovis, jest oparty na SVG i ma być lepszy w renderowaniu animacji . Jednak mam wątpliwości, o ile lepszy i jaki jest jego sufit wydajności. Z tego powodu rozważam również bardziej kompletny przegląd przy użyciu biblioteki opartej na płótnie, takiej jak KineticJS . Zanim jednak zajdę zbyt daleko w stosowanie tego czy innego podejścia, chciałbym usłyszeć od kogoś, kto wykonał podobną aplikację internetową z tak dużą ilością danych i uzyskać jego opinię.
Najważniejsza jest wydajność, z drugorzędnym naciskiem na łatwość dodawania innych funkcji interakcji i programowania animacji. Prawdopodobnie nie będzie więcej niż 2000 punktów naraz, z tymi małymi słupkami błędów na każdym z nich. Powiększanie, pomniejszanie i przesuwanie musi być płynne. Jeśli najnowsze biblioteki SVG są w tym przyzwoite, być może łatwość korzystania z d3 przeważy nad zwiększoną konfiguracją dla KineticJS itp. Ale jeśli jest ogromna przewaga wydajności w używaniu płótna, szczególnie dla ludzi z wolniejszymi komputerami, to ja zdecydowanie wolałby iść tą drogą.
Przykład aplikacji stworzonej przez NYTimes, która używa SVG, ale nadal animuje się w akceptowalny sposób płynnie: http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . Gdybym mógł uzyskać taką wydajność i nie musiałbym pisać własnego kodu do rysowania na płótnie, prawdopodobnie wybrałbym SVG.
Zauważyłem, że niektórzy użytkownicy używali hybrydy manipulacji d3.js połączonej z renderowaniem na płótnie . Jednak nie mogę znaleźć dużo dokumentacji na ten temat w Internecie ani skontaktować się z operatorem tego postu. Jeśli ktoś ma jakieś doświadczenie w realizacji tego rodzaju implementacji DOM-to-Canvas ( demonstracja , kod ), również chciałbym poznać Twoją opinię. Wydaje się, że jest to dobra hybryda możliwości manipulowania danymi i posiadania niestandardowej kontroli nad ich renderowaniem (a tym samym wydajnością), ale zastanawiam się, czy konieczność ładowania wszystkiego do DOM nadal będzie spowalniać.
Wiem, że istnieją pytania podobne do tego, ale żadne z nich nie dotyczy dokładnie tego samego. Dzięki za pomoc.
Kontynuacja : implementacja, z której korzystałem, znajduje się na https://github.com/zooniverse/LightCurves
Odpowiedzi:
Na szczęście narysowanie 2000 okręgów jest dość łatwym przykładem do przetestowania. Oto cztery możliwe implementacje, po dwie z Canvas i SVG:
W tych przykładach wykorzystano zachowanie zoomu D3 do implementacji powiększania i przesuwania. Oprócz tego, czy okręgi są renderowane w formacie Canvas czy SVG, inna ważna różnica dotyczy tego, czy używasz powiększania geometrycznego czy semantycznego .
Powiększanie geometryczne oznacza, że zastosujesz pojedynczą transformację do całej rzutni: po powiększeniu okręgi stają się większe. Kontrastowe powiększanie semantyczne oznacza, że stosujesz transformacje do każdego okręgu osobno: po powiększeniu okręgi zachowują ten sam rozmiar, ale się rozchodzą. Planethunters.org używa obecnie semantycznego powiększania, ale warto rozważyć inne przypadki.
Powiększanie geometryczne upraszcza implementację: raz zastosujesz przesunięcie i skalowanie, a następnie wszystkie okręgi zostaną ponownie renderowane. Implementacja SVG jest szczególnie prosta, ponieważ aktualizuje pojedynczy atrybut „transform”. Wydajność obu przykładów przybliżania geometrycznego wydaje się więcej niż wystarczająca. W przypadku powiększania semantycznego zauważysz, że D3 jest znacznie szybszy niż Protovis. Dzieje się tak, ponieważ wykonuje dużo mniej pracy przy każdym zdarzeniu powiększenia. (Wersja Protovis musi ponownie obliczyć wszystkie atrybuty wszystkich elementów.) Semantyczne powiększanie oparte na kanwie jest nieco bardziej błyskawiczne niż SVG, ale semantyczne powiększanie SVG nadal jest responsywne.
Jednak nie ma magicznej kuli dla wydajności, a te cztery możliwe podejścia nie obejmują całej przestrzeni możliwości. Na przykład można połączyć powiększanie geometryczne i semantyczne, używając podejścia geometrycznego do przesuwania (aktualizacja atrybutu „transform”) i przerysowując tylko pojedyncze okręgi podczas powiększania. Prawdopodobnie możesz nawet połączyć jedną lub więcej z tych technik z transformacjami CSS3, aby dodać trochę przyspieszenia sprzętowego (jak w przykładzie hierarchicznego łączenia brzegów ), chociaż może to być trudne do wdrożenia i może powodować artefakty wizualne.
Mimo to, moim osobistym preferencją jest zachowanie jak największej ilości plików SVG i używanie Canvas tylko jako „wewnętrznej pętli”, gdy wąskim gardłem jest renderowanie . SVG ma tak wiele udogodnień dla rozwoju - takich jak CSS, łączenia danych i inspektor elementów - że często przedwczesna optymalizacja jest rozpoczynana od Canvas. Połączenie Canvas z SVG, jak w połączonej wizualizacji Facebook IPO, jest elastycznym sposobem na zachowanie większości tych udogodnień przy jednoczesnym zachowaniu najlepszej wydajności. Użyłem tej techniki również w Cubism.js , gdzie specjalny przypadek wizualizacji szeregów czasowych dobrze nadaje się do buforowania bitmap.
Jak pokazują te przykłady, możesz używać D3 z Canvas, nawet jeśli części D3 są specyficzne dla SVG. Zobacz także ten wykres ukierunkowany na siłę i ten przykład wykrywania kolizji .
źródło
Myślę, że w twoim przypadku decyzja między płótnem a svg nie przypomina decyzji między »jazdą na koniu« lub »porsche«. Dla mnie to bardziej decyzja o kolorze auta.
Pozwól mi wyjaśnić: Zakładając, że w oparciu o ramy działania
zajmuje liniowy czas. Tak więc, jeśli twoja decyzja dotycząca frameworka była dobra, jest trochę szybsza, w przeciwnym razie nieco wolniejsza.
Jeśli przyjmiesz założenie, że framework jest po prostu szybki, to staje się całkowicie oczywiste, że brak wydajności jest spowodowany dużą ilością gwiazdek, a obsługa ich jest czymś, czego żaden framework nie może dla ciebie zrobić, przynajmniej nie wiem o tym.
Chcę powiedzieć, że podstawa problemu prowadzi do podstawowego problemu geometrii obliczeniowej, a mianowicie: przeszukiwania zakresów i kolejnego z grafiki komputerowej: poziomu szczegółowości .
Aby rozwiązać problem z wydajnością, musisz zaimplementować dobry preprocesor, który jest w stanie bardzo szybko znaleźć gwiazdy do wyświetlenia i być może jest w stanie skupić gwiazdy, które są blisko siebie, w zależności od powiększenia. Jedyną rzeczą, która zapewnia żywy i szybki widok, jest utrzymywanie jak najniższej liczby gwiazd do narysowania.
Jak powiedziałeś, najważniejsza jest wydajność, niż zwykle używałbym płótna, ponieważ działa bez operacji DOM. Oferuje również możliwość korzystania z webGL, co znacznie zwiększa wydajność graficzną.
BTW: czy sprawdziłeś paper.js ? Używa płótna, ale emuluje grafikę wektorową.
PS: W tej książce można znaleźć bardzo szczegółowe omówienie grafiki w Internecie, technologii, zalet i wad płótna, SVG i DHTML.
źródło
Niedawno pracowałem nad pulpitem nawigacyjnym działającym niemal w czasie rzeczywistym (odświeżanie co 5 sekund) i zdecydowałem się użyć wykresów renderujących się za pomocą kanwy.
Wypróbowaliśmy Highcharts (biblioteka wykresów JavaScript oparta na SVG) i CanvasJS (biblioteka wykresów JavaScript oparta na płótnie). Chociaż Highcharts jest fantastycznym interfejsem API do tworzenia wykresów i oferuje znacznie więcej funkcji, zdecydowaliśmy się użyć CanvasJS.
Musieliśmy wyświetlić co najmniej 15 minut danych na wykres (z możliwością wybrania zakresu maksymalnie dwóch godzin).
Tak więc przez 15 minut: 900 punktów (punkt danych na sekundę) x2 (wykres liniowy i słupkowy) x4 wykresy = łącznie 7200 punktów.
Używając profilera Chrome, z CanvasJS pamięć nigdy nie przekroczyła 30 MB, podczas gdy użycie pamięci Highcharts przekroczyło 600 MB.
Również z czasem odświeżania wynoszącym 5 sekund, renderowanie CanvasJS było bardziej responsywne niż Highcharts.
Użyliśmy jednego timera (setInterval 5 sekund), aby wykonać 4 wywołania interfejsu API REST w celu pobrania danych z serwera zaplecza, który łączył się z Elasticsearch. Każdy wykres aktualizowany po odebraniu danych przez JQuery.post ().
To powiedziawszy, w przypadku raportów offline wybrałbym Highcharts, ponieważ jest to bardziej elastyczny interfejs API.
Istnieją również wykresy Zing, które twierdzą, że używają SVG lub Canvas, ale ich nie oglądały.
Canvas należy wziąć pod uwagę, gdy wydajność jest naprawdę krytyczna. SVG dla elastyczności. Nie chodzi o to, że frameworki kanwy nie są elastyczne, ale frameworowi kanwy potrzeba dużo więcej pracy, aby uzyskać taką samą funkcjonalność jak framework svg.
źródło
Warto również zajrzeć do Meteor Charts, który jest oparty na szybkim frameworku KineticJS: http://meteorcharts.com/
źródło
Odkryłem również, że kiedy drukujemy do pliku PDF stronę z grafiką SVG, wynikowy plik PDF nadal zawiera obraz wektorowy, a jeśli drukujesz stronę z grafiką Canvas, obraz w wynikowym pliku PDF jest rasteryzowany.
źródło