Hızlı ve duyarlı etkileşimli tablolar / grafikler: SVG, Canvas, diğer?


114

Temelde yakınlaştırılabilir, kaydırılabilir bir grafikte binlerce noktayı oluşturan bir projeyi güncellemek için kullanılacak doğru teknolojiyi seçmeye çalışıyorum. Protovis kullanan mevcut uygulama düşük performans gösteriyor. Buradan kontrol edin:

http://www.planethunters.org/classify

Tamamen uzaklaştırıldığında yaklaşık 2000 nokta vardır. Biraz yakınlaştırmak için alttaki tutamaçları kullanmayı deneyin ve kaydırmak için sürükleyin. Oldukça dalgalı olduğunu göreceksiniz ve gerçekten hızlı bir bilgisayarınız olmadıkça CPU kullanımınızın muhtemelen bir çekirdekte% 100'e kadar çıktığını göreceksiniz. Odak alanındaki her değişiklik, oldukça yavaş olan ve daha fazla nokta çizildiğinde daha kötü olan protovise yeniden çizim çağrısı yapar.

Arayüzde bazı güncellemeler yapmak ve altta yatan görselleştirme teknolojisini animasyon ve etkileşimle daha duyarlı olacak şekilde değiştirmek istiyorum. Aşağıdaki makaleden, seçim başka bir SVG tabanlı kitaplık veya tuval tabanlı bir kitaplık arasında gibi görünüyor:

http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/

Protovis'ten çıkan d3.js, SVG tabanlıdır ve animasyonları oluşturmada daha iyi olması gerekir . Bununla birlikte, ne kadar daha iyi ve performans tavanının ne olduğu konusunda şüpheliyim. Bu nedenle, KineticJS gibi tuval tabanlı bir kitaplık kullanarak daha eksiksiz bir revizyon yapmayı da düşünüyorum . Bununla birlikte, bir yaklaşımı veya diğerini çok fazla kullanmadan önce, bu kadar veriye sahip benzer bir web uygulaması yapmış birinden haber almak ve fikirlerini almak isterim.

En önemli şey performanstır, ikincil olarak diğer etkileşim özelliklerini ekleme ve animasyonu programlama kolaylığına odaklanır. Her birinde bu küçük hata çubuklarıyla aynı anda 2000'den fazla nokta olmayacaktır. Yakınlaştırma, uzaklaştırma ve gezinme işlemlerinin düzgün olması gerekir. En son SVG kitaplıkları bu konuda yeterliyse, belki de d3'ü kullanmanın kolaylığı, KineticJS vb. İçin artan kurulumdan daha ağır basacaktır. Ancak, özellikle daha yavaş bilgisayarlara sahip kişiler için bir tuval kullanmanın büyük bir performans avantajı varsa, o zaman ben kesinlikle böyle gitmeyi tercih eder.

SVG kullanan, ancak yine de kabul edilebilir derecede sorunsuz bir şekilde animasyon uygulayan NYTimes tarafından yapılan uygulama örneği: http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . Bu performansı elde edebilirsem ve kendi tuval çizim kodumu yazmak zorunda kalmazsam, muhtemelen SVG'ye giderim.

Bazı kullanıcıların tuval oluşturmayla birlikte bir d3.js manipülasyonu kullandığını fark ettim . Ancak, bununla ilgili çok fazla belge bulamıyorum veya bu yazının OP'si ile iletişime geçemiyorum. Bu tür bir DOM-to-Canvas ( demo , kod ) uygulaması olan varsa, sizden de haber almak isterim. Verileri işleyebilmenin ve nasıl işleneceği (ve dolayısıyla performansın) üzerinde özel kontrole sahip olmanın iyi bir karması gibi görünüyor, ancak her şeyi DOM'a yüklemek zorunda kalmanın hala işleri yavaşlatıp yavaşlatmayacağını merak ediyorum.

Buna benzer bazı mevcut sorular olduğunu biliyorum, ancak hiçbiri tam olarak aynı şeyi sormuyor. Yardımınız için teşekkürler.

Takip : Kullanmayı sonlandırdığım uygulama https://github.com/zooniverse/LightCurves adresinde


"En önemli şey performanstır, ikincil olarak diğer etkileşimleri eklemenin kolaylığına odaklanır" tuval için +1
philipp

Soru şu ki, SVG çoğu tarayıcıda 2k puan + diğer grafik öğeleri için yeterli mi? Eğer öyleyse ve yavaşlık sadece protovisteki zayıflıklardan kaynaklanıyorsa, o zaman SVG'ye bağlı kalmayı tercih ederim.
Andrew Mao

1
Mike Bostock her zaman iyi bir cevap verdi. Bazı ek bilgiler için şu iki kaynağa göz atabilirsiniz: stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div/… blogs.msdn.com/b/ie/archive/2011/04/22 /…
Ümit

8
Takip: Bunu, SVG'nin eksenleri ve kılavuz çizgilerini ilgilendirdiği ve kanvasın noktaları son derece hızlı bir şekilde oluşturabildiği karma bir SVG / tuval yaklaşımıyla uyguladım. Süper hızlı!
Andrew Mao

Yanıtlar:


183

Neyse ki 2000 daire çizmek test etmek için oldukça kolay bir örnek. İşte her biri iki Canvas ve SVG olmak üzere dört olası uygulama:

Bu örnekler, yakınlaştırma ve kaydırmayı uygulamak için D3'ün yakınlaştırma davranışını kullanır. Dairelerin Canvas'ta mı yoksa SVG'de mi oluşturulduğunun yanı sıra, diğer önemli ayrım, geometrik veya anlamsal yakınlaştırmayı kullanıp kullanmadığınızdır .

Geometrik yakınlaştırma, tüm görüntü alanına tek bir dönüşüm uyguladığınız anlamına gelir: yakınlaştırdığınızda daireler büyür. Buna karşılık anlamsal yakınlaştırma, dönüşümleri her daireye ayrı ayrı uygulayacağınız anlamına gelir: Yakınlaştırdığınızda, daireler aynı boyutta kalır ancak yayılırlar. Planethunters.org şu anda anlamsal yakınlaştırmayı kullanıyor, ancak diğer durumları dikkate almak faydalı olabilir.

Geometrik yakınlaştırma, uygulamayı basitleştirir: bir kez bir çeviri ve ölçek uygularsınız ve ardından tüm daireler yeniden oluşturulur. SVG uygulaması özellikle basittir, tek bir "dönüştürme" özniteliğini günceller. Her iki geometrik yakınlaştırma örneğinin performansı fazlasıyla yeterli geliyor. Anlamsal yakınlaştırma için, D3'ün Protovis'ten önemli ölçüde daha hızlı olduğunu fark edeceksiniz. Bunun nedeni, her yakınlaştırma olayı için çok daha az iş yapmasıdır. (Protovis sürümü, tüm öğelerdeki tüm öznitelikleri yeniden hesaplamak zorundadır.) Canvas tabanlı anlamsal yakınlaştırma, SVG'den biraz daha hızlıdır, ancak SVG anlamsal yakınlaştırma yine de duyarlıdır.

Yine de performans için sihirli bir mermi yok ve bu dört olası yaklaşım tüm olasılıkları kapsamaya başlamıyor. Örneğin, yatay kaydırma için geometrik yaklaşımı kullanarak ("dönüştürme" özelliğini güncelleyerek) ve yakınlaştırma sırasında yalnızca tek tek daireleri yeniden çizerek geometrik ve anlamsal yakınlaştırmayı birleştirebilirsiniz. Hatta bazı donanım hızlandırmaları eklemek için ( hiyerarşik kenar gruplama örneğinde olduğu gibi ) bu tekniklerden birini veya daha fazlasını CSS3 dönüşümleriyle birleştirebilirsiniz , ancak bu, uygulanması zor olabilir ve görsel eserler ortaya çıkarabilir.

Yine de, kişisel tercihim SVG'de olabildiğince fazla tutmak ve Canvas'ı yalnızca "iç döngü" için kullanmak, çünkü işleme darboğaz oluşturuyorsa . SVG, geliştirme için o kadar çok kolaylığa sahiptir - CSS, veri birleştirmeleri ve öğe denetçisi gibi - Canvas ile başlamak genellikle erken optimizasyondur. Kanvası, bağladığınız Facebook IPO görselleştirmesinde olduğu gibi, SVG ile birleştirmek, bu kolaylıkların çoğunu muhafaza ederken en iyi performansı elde etmenin esnek bir yoludur. Bu tekniği , zaman serisi görselleştirmenin özel durumunun bitmap önbelleğe almaya uygun olduğu Cubism.js'de de kullandım .

Bu örneklerin gösterdiği gibi, D3'ün bazı bölümleri SVG'ye özgü olsa da D3'ü Canvas ile kullanabilirsiniz. Ayrıca bu kuvvet yönelimli grafiğe ve bu çarpışma algılama örneğine bakın .


Vay canına, bu harika bir cevaptı ve görselleştirme ustasından! Anlamsal yakınlaştırmaya bağlı kalmam gerektiğini düşünüyorum ve bilgisayarımda, tuval tabanlı oluşturucu kaydırma / yakınlaştırma sırasında SVG sürümünden çok daha hızlı (tarayıcı uygulamasıyla bir ilgisi olabilir mi?). SVG'yi iç döngü olarak tuval ile kullanmak hakkında söyledikleriniz, tam olarak onaylamak istediğim şeydi ve kod örnekleri sadece tatlı bir bonus. Çok teşekkürler!
Andrew Mao

Anlamsal yakınlaştırma örneklerini farklı tarayıcılarda denemeyi düşündüm: Chrome, her ikisi de oldukça hızlı, farkı anlayamıyorum; IE: SVG biraz daha yavaş; Firefox (son yorum): SVG, tuvale kıyasla çok yavaş. Sanırım bu da kararı biraz zorlaştırıyor ama tuvali oluşturmayı güvenli bir seçim haline getiriyor. Bir soru daha: Canvas yerine KineticJS kullanmak performansı önemli ölçüde etkileyecek mi?
Andrew Mao

1
Andrew, biraz geç ama işte FF ile olan deneyimim: Yaklaşıyor. Eskiden FF 15 çalıştırırdım ve D3 SVG geçişleri hızla yavaşlamaya başladı. Ancak her yeni sürüm önemli ölçüde daha hızlı hale geldi. Şimdi FF 18 beta sürümündeyim ve 17'ye kıyasla hızlı. Yine de krom kadar pürüzsüz olup olmadığından emin değilim.
user2503795

@AndrewMao Merhaba Andrew, oluşturmanın bir darboğaz gibi göründüğü bir durumla karşılaştım. Bazı noktaları ve yaklaşık 6000 eğri yolunu kaydırmam ve yakınlaştırmam gerekiyor. stackoverflow.com/questions/17907769/svg-path-rendering-speed/… Ancak Bostock'un "SVG'de olabildiğince fazla tutun ve Canvas'ı yalnızca sahip olduğum" iç döngü "için kullanın dediğini tam olarak anlamıyorum Yine de dört örneğe baktım .. Bana biraz ışık tutabilir misin?
kakacii

@kakacii dönüşüm tüm tarayıcılarda eşit derecede yavaş mı? Öyleyse, yanlış kod kullandığınızı veya tarayıcı oluşturma sınırlarını aştığınızı söyleyebilirim. Biraz kod gönderebilirseniz yardımcı olabilirim. mbostock, kodlama daha karmaşık olduğu için, SVG'yi işlem ve tuvali yalnızca gerektiği kadar basitleştirmek için kullanmaya atıfta bulunuyordu. Bununla birlikte, KineticJS gibi kütüphaneler bunu bir dereceye kadar basitleştirdi.
Andrew Mao

8

Sanırım sizin durumunuzda tuval ve svg arasındaki karar, "Ata binmek" veya bir "Porsche" kullanmak arasında bir karara benzemiyor. Benim için daha çok arabaların rengiyle ilgili karar gibi.

Açıklayayım: Çerçeveye göre operasyonların

  • bir yıldız çiz
  • bir yıldız ekleyin ve
  • bir yıldızı kaldır

doğrusal zaman alır. Yani, çerçeveye ilişkin kararınız iyiyse, biraz daha hızlı, aksi halde biraz daha yavaştır.

Çerçevenin sadece hızlı olduğunu varsaymaya devam ederseniz, performans eksikliğinin yüksek miktarda yıldız olmasından kaynaklandığı ve bunları işlemek çerçevelerin sizin için yapamayacağı bir şey olduğu tamamen açık hale gelir, en azından bilmiyorum bunun hakkında.

Söylemek istediğim şey, problemin temelinin hesaplamalı geometri ile ilgili temel bir probleme yol açtığıdır, yani: aralık arama ve bir başka bilgisayar grafiği: detay seviyesi .

Performans sorununuzu çözmek için, hangi yıldızların görüntüleneceğini çok hızlı bulabilen ve yakınlaştırmaya bağlı olarak birbirine yakın yıldızları kümelendirebilen iyi bir önişlemci uygulamanız gerekir. Görüşünüzü canlı ve hızlı tutan tek şey, çizilecek yıldız sayısını olabildiğince düşük tutmaktır.

Sizin de belirttiğiniz gibi, en önemli şey performanstı, tuval kullanma eğilimindeyim, çünkü DOM işlemleri olmadan çalışıyor. Ayrıca, grafik performansını çok artıran webGL'yi kullanma fırsatı sunar.

BTW: paper.js'yi kontrol ettiniz mi? Kanvas kullanır, ancak vektör grafiklerine öykünür.

Not: Bu Kitapta , web üzerindeki grafikler, kanvasın teknolojileri, artıları ve eksileri, SVG ve DHTML hakkında çok ayrıntılı bir tartışma bulabilirsiniz.


7

Yakın zamanda neredeyse gerçek zamanlı bir kontrol paneli üzerinde çalıştım (her 5 saniyede bir yenileyin) ve tuval kullanarak işlenen grafikleri kullanmayı seçtim.

Highcharts (SVG tabanlı JavaScript Grafik kitaplığı) ve CanvasJS (Tuval tabanlı JavaScript Grafik kitaplığı) denedik. Highcharts harika bir grafik API'sı olmasına ve çok daha fazla özellik sunmasına rağmen, CanvasJS kullanmaya karar verdik.

Grafik başına en az 15 dakikalık veri göstermemiz gerekiyordu (en fazla iki saatlik aralık seçme seçeneğiyle).

Yani 15 dakika için: 900 nokta (saniyede veri noktası) x2 (çizgi ve çubuk kombinasyon grafiği) x4 grafik = toplam 7200 puan.

Chrome profil oluşturucuyu kullanarak, CanvasJS ile bellek hiçbir zaman 30 MB'ın üzerine çıkarken, Highcharts bellek kullanımı 600 MB'ı aştı.

Ayrıca 5 saniyelik yenileme süresiyle CanvasJS oluşturma, Highcharts'tan daha duyarlıydı.

Elasticsearch'e bağlı arka uç sunucudan verileri çekmek için 4 REST API çağrısı yapmak için bir timer (setInterval 5 saniye) kullandık. Veriler olarak güncellenen her grafik, JQuery.post () tarafından alınır.

Bu, çevrimdışı raporlar için daha esnek API'sinden bu yana Highcharts ile gideceğimi söyledi.

Ayrıca SVG veya Canvas'ı kullandığını iddia eden ancak bunlara bakmayan Zing grafikleri de var.

Performans gerçekten kritik olduğunda tuval düşünülmelidir. Esneklik için SVG. Tuval çerçevelerinin esnek olmadığından değil, ancak bir svg çerçevesiyle aynı işlevselliği elde etmek için tuval çerçevesine daha fazla çalışma yapılması gerekiyor.



0

Ayrıca, SVG grafikli bir sayfayı PDF'ye yazdırdığımızda, ortaya çıkan PDF'nin hala vektör tabanlı bir görüntü içerdiğini, Canvas grafikleriyle bir sayfa yazdırırsanız, elde edilen PDF dosyasındaki görüntünün rasterleştirildiğini gördüm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.