แผนภูมิ / กราฟเชิงโต้ตอบที่รวดเร็วและตอบสนอง: SVG, Canvas, อื่น ๆ ?


114

ฉันกำลังพยายามเลือกเทคโนโลยีที่เหมาะสมเพื่อใช้ในการอัปเดตโปรเจ็กต์ที่โดยทั่วไปแล้วจะแสดงจุดหลายพันจุดในกราฟที่สามารถซูมได้และสามารถเลื่อนได้ การใช้งานปัจจุบันโดยใช้ Protovis มีประสิทธิภาพต่ำ ตรวจสอบได้ที่นี่:

http://www.planethunters.org/classify

มีจุดประมาณ 2,000 จุดเมื่อซูมออกจนสุด ลองใช้ที่จับที่ด้านล่างเพื่อซูมเข้าเล็กน้อยแล้วลากเพื่อเลื่อนไปรอบ ๆ คุณจะเห็นว่ามันค่อนข้างขาด ๆ หาย ๆ และการใช้งาน CPU ของคุณอาจสูงถึง 100% ในหนึ่งคอร์เว้นแต่คุณจะมีคอมพิวเตอร์ที่เร็วมาก การเปลี่ยนพื้นที่โฟกัสแต่ละครั้งจะเรียกการวาดใหม่เป็นโปรโตวิสซึ่งค่อนข้างช้าและแย่กว่าเมื่อมีการดึงจุดมากขึ้น

ฉันต้องการอัปเดตอินเทอร์เฟซบางอย่างรวมทั้งเปลี่ยนเทคโนโลยีการแสดงภาพที่เป็นพื้นฐานให้ตอบสนองกับภาพเคลื่อนไหวและการโต้ตอบมากขึ้น จากบทความต่อไปนี้ดูเหมือนว่าตัวเลือกจะอยู่ระหว่างไลบรารีที่ใช้ SVG อื่นหรือแบบผ้าใบ

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

d3.jsซึ่งงอกออกมาจาก Protovis เป็น SVG-based และควรจะเป็นดีกว่าที่การแสดงผลภาพเคลื่อนไหว อย่างไรก็ตามฉันสงสัยว่าจะดีขึ้นมากแค่ไหนและเพดานประสิทธิภาพของมันเป็นอย่างไร สำหรับเหตุผลที่ฉันยังพิจารณายกเครื่องสมบูรณ์มากขึ้นโดยใช้ห้องสมุดผ้าใบ-based เช่นKineticJS อย่างไรก็ตามก่อนที่ฉันจะใช้วิธีใดวิธีหนึ่งมากเกินไปฉันอยากได้ยินจากคนที่ทำเว็บแอปพลิเคชันที่คล้ายกันซึ่งมีข้อมูลจำนวนมากนี้และขอความเห็นจากพวกเขา

สิ่งที่สำคัญที่สุดคือประสิทธิภาพโดยเน้นที่ความสะดวกในการเพิ่มคุณสมบัติการโต้ตอบอื่น ๆ และการเขียนโปรแกรมภาพเคลื่อนไหว อาจจะมีไม่เกิน 2,000 จุดในครั้งเดียวโดยมีแถบข้อผิดพลาดเล็ก ๆ ในแต่ละอัน การซูมเข้าออกและการเลื่อนไปมาจะต้องมีความราบรื่น หากไลบรารี SVG ล่าสุดเหมาะสมกับสิ่งนี้บางทีความสะดวกในการใช้ d3 จะมีมากกว่าการตั้งค่าที่เพิ่มขึ้นสำหรับ KineticJS เป็นต้น แต่หากมีข้อได้เปรียบด้านประสิทธิภาพอย่างมากในการใช้ผืนผ้าใบโดยเฉพาะอย่างยิ่งสำหรับผู้ที่มีคอมพิวเตอร์ที่ทำงานช้ากว่าฉัน อยากจะไปทางนั้นแน่นอน

ตัวอย่างแอปที่สร้างโดย NYTimes ที่ใช้ SVG แต่ยังคงเคลื่อนไหวได้อย่างราบรื่น: http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . ถ้าฉันได้รับประสิทธิภาพนั้นและไม่ต้องเขียนโค้ดวาดภาพแคนวาสของตัวเองฉันอาจจะใช้ SVG

ผมสังเกตเห็นว่าผู้ใช้บางคนได้ใช้ไฮบริดของการจัดการ d3.js รวมกับการแสดงผลบนผืนผ้าใบ อย่างไรก็ตามฉันไม่พบเอกสารเกี่ยวกับเรื่องนี้ทางออนไลน์หรือติดต่อ OP ของโพสต์นั้นได้มากนัก ถ้าใครมีประสบการณ์การทำชนิดของ DOM เพื่อผ้าใบ (นี้สาธิต , รหัส ) การดำเนินงานที่ฉันต้องการที่จะได้ยินจากคุณเช่นกัน ดูเหมือนว่าจะเป็นลูกผสมที่ดีในการจัดการข้อมูลและมีการควบคุมวิธีการแสดงผลแบบกำหนดเอง (และประสิทธิภาพ) แต่ฉันสงสัยว่าการโหลดทุกอย่างลงใน DOM จะยังคงทำให้สิ่งต่างๆช้าลงหรือไม่

ฉันรู้ว่ามีคำถามบางข้อที่คล้ายกับคำถามนี้ แต่ไม่มีคำถามใดที่ถามเหมือนกันทุกประการ ขอบคุณสำหรับความช่วยเหลือของคุณ.

การติดตามผล : การใช้งานที่ฉันใช้อยู่ที่https://github.com/zooniverse/LightCurves


"สิ่งที่สำคัญที่สุดคือประสิทธิภาพโดยเน้นที่ความสะดวกในการเพิ่มการโต้ตอบอื่น ๆ " +1 สำหรับ canvas
philipp

คำถามคือ SVG เพียงพอสำหรับเบราว์เซอร์ส่วนใหญ่สำหรับ 2k คะแนน + องค์ประกอบแผนภูมิอื่น ๆ หรือไม่ ถ้าเป็นเช่นนั้นและความช้าเป็นเพียงเพราะจุดอ่อนในโปรโตวิสฉันก็ค่อนข้างจะยึดติดกับ SVG
Andrew Mao

1
Mike Bostock ให้คำตอบที่ดี สำหรับข้อมูลเพิ่มเติมคุณสามารถดูแหล่งข้อมูลทั้งสองนี้: stackoverflow.com/questions/5882716/html5-canvas-vs-svg-vs-div/… blogs.msdn.com/b/ie/archive/2011/04/22 / …
Ü

8
การติดตามผล: ฉันได้ใช้สิ่งนี้ด้วยวิธี SVG / canvas แบบไฮบริดโดยที่ SVG ดูแลแกนและเส้นตารางและผืนผ้าใบสามารถแสดงจุดได้เร็วมาก เร็วมาก!
Andrew Mao

คำตอบ:


183

โชคดีที่การวาดวงกลม 2,000 วงเป็นตัวอย่างที่ค่อนข้างง่ายในการทดสอบ ต่อไปนี้คือการนำไปใช้งานที่เป็นไปได้สี่แบบโดยแต่ละ Canvas และ SVG:

ตัวอย่างเหล่านี้ใช้พฤติกรรมการซูมของ D3 เพื่อใช้การซูมและการแพนกล้อง นอกเหนือจากการแสดงผลวงกลมใน Canvas หรือ SVG แล้วความแตกต่างที่สำคัญอื่น ๆ ก็คือไม่ว่าคุณจะใช้การซูมทางเรขาคณิตหรือความหมาย

การซูมทางเรขาคณิตหมายความว่าคุณใช้การแปลงเพียงครั้งเดียวกับวิวพอร์ตทั้งหมด: เมื่อคุณซูมเข้าวงกลมจะใหญ่ขึ้น การซูมเข้าในความหมายแบบคอนทราสต์หมายความว่าคุณใช้การแปลงกับวงกลมแต่ละวงทีละวง: เมื่อคุณซูมเข้าวงกลมจะยังคงมีขนาดเท่าเดิม ปัจจุบัน Planethunters.org ใช้การซูมเชิงความหมาย แต่อาจเป็นประโยชน์ในการพิจารณากรณีอื่น ๆ

การซูมทางเรขาคณิตช่วยลดความยุ่งยากในการนำไปใช้: คุณใช้การแปลและมาตราส่วนเพียงครั้งเดียวจากนั้นวงกลมทั้งหมดจะแสดงผลใหม่ การติดตั้ง SVG นั้นง่ายมากโดยการอัปเดตแอตทริบิวต์ "transform" เพียงรายการเดียว ประสิทธิภาพของทั้งสองตัวอย่างการซูมทางเรขาคณิตให้ความรู้สึกว่าเพียงพอ สำหรับการซูมความหมายคุณจะสังเกตได้ว่า D3 เร็วกว่า Protovis อย่างมาก เนื่องจากมันทำงานน้อยลงมากสำหรับแต่ละเหตุการณ์การซูม (เวอร์ชัน Protovis ต้องคำนวณแอตทริบิวต์ทั้งหมดในองค์ประกอบทั้งหมดใหม่) การซูมเชิงความหมายแบบ Canvas นั้นมีซิปมากกว่า SVG เล็กน้อย แต่การซูมความหมาย SVG ยังคงตอบสนองได้ดี

ยังไม่มีสัญลักษณ์แสดงหัวข้อย่อยวิเศษสำหรับประสิทธิภาพและสี่วิธีที่เป็นไปได้นี้ไม่ได้เริ่มครอบคลุมความเป็นไปได้ทั้งหมด ตัวอย่างเช่นคุณสามารถรวมการซูมทางเรขาคณิตและความหมายโดยใช้วิธีการทางเรขาคณิตสำหรับการแพน (อัปเดตแอตทริบิวต์ "transform") และวาดเฉพาะวงกลมแต่ละวงในขณะที่ซูม คุณอาจรวมเทคนิคเหล่านี้อย่างน้อยหนึ่งอย่างเข้ากับการแปลง CSS3 เพื่อเพิ่มการเร่งความเร็วของฮาร์ดแวร์ (เช่นในตัวอย่างการรวมขอบแบบลำดับชั้น ) แม้ว่าจะเป็นเรื่องยุ่งยากในการนำไปใช้และอาจแนะนำสิ่งประดิษฐ์ที่มองเห็นได้

ยังคงการตั้งค่าส่วนตัวของฉันคือการให้มากที่สุดเท่าใน SVG เป็นไปได้และใช้ผ้าใบเฉพาะสำหรับ "ภายในวง" เมื่อการแสดงผลเป็นคอขวด SVG มีสิ่งอำนวยความสะดวกมากมายสำหรับการพัฒนาเช่น CSS การรวมข้อมูลและตัวตรวจสอบองค์ประกอบซึ่งมักจะเป็นการเพิ่มประสิทธิภาพก่อนกำหนดโดยเริ่มจาก Canvas การรวม Canvas กับ SVG เช่นเดียวกับการแสดงภาพ IPO ของ Facebook ที่คุณเชื่อมโยงเป็นวิธีที่ยืดหยุ่นในการรักษาความสะดวกสบายเหล่านี้ส่วนใหญ่ในขณะที่ยังคงประสิทธิภาพที่ดีที่สุด ฉันยังใช้เทคนิคนี้ในCubism.jsซึ่งกรณีพิเศษของการแสดงภาพอนุกรมเวลาช่วยให้สามารถแคชบิตแมปได้ดี

ดังที่แสดงในตัวอย่างเหล่านี้คุณสามารถใช้ D3 กับ Canvas ได้แม้ว่าบางส่วนของ D3 จะเป็นแบบ SVG ก็ตาม ดูกราฟบังคับทิศทางและตัวอย่างการตรวจจับการชนกันนี้


ว้าวนั่นเป็นคำตอบที่ยอดเยี่ยมและจากผู้เชี่ยวชาญด้านการสร้างภาพเอง! ฉันคิดว่าฉันจะต้องใช้การซูมเชิงความหมายและในคอมพิวเตอร์ของฉันตัวแสดงผลแบบผ้าใบจะเร็วกว่าเวอร์ชัน SVG เมื่อแพน / ซูม (อาจเกี่ยวข้องกับการใช้เบราว์เซอร์หรือไม่) สิ่งที่คุณพูดเกี่ยวกับการใช้ SVG กับแคนวาสเนื่องจากวงในเป็นสิ่งที่ฉันต้องการยืนยันและตัวอย่างโค้ดเป็นเพียงโบนัสที่น่าสนใจ ขอบคุณมาก!
Andrew Mao

เพิ่งมีความคิดที่จะลองใช้ตัวอย่างการย่อ / ขยายความหมายในเบราว์เซอร์ต่างๆ: Chrome ทั้งคู่เร็วมากฉันไม่สามารถบอกความแตกต่างได้ IE: SVG ช้าลงเล็กน้อย; Firefox (ความคิดเห็นสุดท้าย): SVG ช้าเมื่อเทียบกับผ้าใบ ฉันเดาว่านั่นทำให้การตัดสินใจซับซ้อนขึ้นเล็กน้อย แต่ทำให้การแสดงผลแคนวาสเป็นตัวเลือกที่ปลอดภัย อีกหนึ่งคำถาม: การใช้ KineticJS แทนผ้าใบโดยตรงจะส่งผลต่อประสิทธิภาพอย่างมากหรือไม่?
Andrew Mao

1
แอนดรูมาช้าไปหน่อย แต่นี่คือประสบการณ์ของฉันกับ FF: กำลังตามทัน ฉันเคยเรียกใช้การเปลี่ยน FF 15 และ D3 SVG เริ่มช้าอย่างรวดเร็ว แต่เวอร์ชันใหม่แต่ละเวอร์ชันจะเร็วขึ้นมาก ตอนนี้ผมใช้ FF 18 beta และเร็วเมื่อเทียบกับ 17 ไม่แน่ใจว่าจะเนียนเหมือน chrome รึเปล่า
user2503795

@AndrewMao สวัสดีแอนดรูฉันเจอสถานการณ์ที่ดูเหมือนว่าการแสดงผลเป็นคอขวด ฉันต้องแพนและซูมบางจุดและเส้นทางโค้งประมาณ 6,000 เส้น stackoverflow.com/questions/17907769/svg-path-rendering-speed/…แต่ฉันไม่ค่อยเข้าใจ Bostock เมื่อเขาพูดว่า "เก็บใน SVG ให้มากที่สุดเท่าที่จะเป็นไปได้และใช้ Canvas เฉพาะสำหรับ" วงใน "" ที่ฉันมี ดูตัวอย่างทั้งสี่แล้ว .. คุณช่วยส่องไฟให้ฉันหน่อยได้ไหม?
kakacii

@kakacii การเปลี่ยนแปลงช้าเท่ากันในทุกเบราว์เซอร์หรือไม่? ถ้าเป็นเช่นนั้นฉันจะบอกว่าคุณใช้รหัสผิดหรือคุณถึงขีด จำกัด การแสดงผลของเบราว์เซอร์ หากคุณสามารถโพสต์รหัสได้ฉันอาจช่วยได้ mbostock หมายถึงการใช้ SVG เพื่อความเรียบง่ายในการจัดการและแคนวาสเท่าที่จำเป็นเท่านั้นเนื่องจากโค้ดมีความซับซ้อนมากขึ้น อย่างไรก็ตามไลบรารีเช่น KineticJS ต้องทำให้ง่ายขึ้นบ้าง
Andrew Mao

8

ฉันคิดว่าในกรณีของคุณการตัดสินใจระหว่าง canvas กับ svg ไม่เหมือนกับการตัดสินใจระหว่าง»ขี่ม้า«หรือขับ» Porsche « สำหรับฉันมันเหมือนกับการตัดสินใจเกี่ยวกับสีรถมากกว่า

ให้ฉันอธิบาย: สมมติว่าตามกรอบการดำเนินงาน

  • วาดดาว
  • เพิ่มดาวและ
  • ลบดาว

ใช้เวลาเชิงเส้น ดังนั้นหากการตัดสินใจของคุณเกี่ยวกับเฟรมเวิร์กนั้นดีก็จะเร็วขึ้นเล็กน้อยมิฉะนั้นจะช้าลงเล็กน้อย

หากคุณสมมติว่าเฟรมเวิร์กนั้นเร็วกว่าที่เห็นได้ชัดโดยสิ้นเชิงว่าการขาดประสิทธิภาพนั้นเกิดจากจำนวนดาวที่สูงและการจัดการกับมันเป็นสิ่งที่ไม่มีกรอบใดสามารถทำเพื่อคุณได้อย่างน้อยฉันก็ไม่รู้ เกี่ยวกับเรื่องนี้.

สิ่งที่ผมอยากจะบอกก็คือว่าฐานของนำไปสู่ปัญหาที่เป็นปัญหาพื้นฐานของการคำนวณเรขาคณิตคือ: ช่วงการค้นหาและเป็นหนึ่งในคอมพิวเตอร์กราฟิกอื่น: ระดับของรายละเอียด

ในการแก้ปัญหาด้านประสิทธิภาพของคุณคุณต้องใช้ตัวประมวลผลล่วงหน้าที่ดีซึ่งจะสามารถค้นหาดาวที่จะแสดงได้เร็วมากและอาจจะรวมกลุ่มดาวที่อยู่ใกล้กันขึ้นอยู่กับการซูม สิ่งเดียวที่ช่วยให้มุมมองของคุณสดใสและรวดเร็วคือการรักษาจำนวนดาวให้เหลือน้อยที่สุด

ตามที่คุณระบุไว้สิ่งที่สำคัญที่สุดคือประสิทธิภาพมากกว่าที่ฉันมักจะใช้ผ้าใบเพราะมันทำงานได้โดยไม่ต้องดำเนินการ DOM นอกจากนี้ยังมีโอกาสในการใช้ webGL ซึ่งช่วยเพิ่มประสิทธิภาพด้านกราฟิกได้มาก

BTW: คุณตรวจสอบpaper.jsหรือไม่? ใช้ผ้าใบ แต่เลียนแบบกราฟิกแบบเวกเตอร์

ป.ล. : ในหนังสือเล่มนี้คุณจะพบการอภิปรายโดยละเอียดเกี่ยวกับกราฟิกบนเว็บเทคโนโลยีข้อดีข้อเสียของผ้าใบ SVG และ DHTML


7

ฉันเพิ่งทำงานบนแดชบอร์ดแบบเรียลไทม์ (รีเฟรชทุกๆ 5 วินาที) และเลือกใช้แผนภูมิที่แสดงผลโดยใช้ผ้าใบ

เราลองใช้ Highcharts (ไลบรารีแผนภูมิ JavaScript ที่ใช้ SVG) และ CanvasJS (ไลบรารีแผนภูมิ JavaScript ที่ใช้ผ้าใบ) แม้ว่า Highcharts จะเป็น API การสร้างแผนภูมิที่ยอดเยี่ยมและมีคุณสมบัติอื่น ๆ อีกมากมายที่เราตัดสินใจใช้ CanvasJS

เราจำเป็นต้องแสดงข้อมูลอย่างน้อย 15 นาทีต่อแผนภูมิ (พร้อมตัวเลือกในการเลือกช่วงสูงสุดสองชั่วโมง)

เป็นเวลา 15 นาที: 900 คะแนน (จุดข้อมูลต่อวินาที) x2 (แผนภูมิรวมเส้นและแท่ง) แผนภูมิ x4 = รวม 7200 คะแนน

การใช้ chrome profiler กับ CanvasJS หน่วยความจำไม่เคยเกิน 30MB ในขณะที่การใช้งานหน่วยความจำ Highcharts เกิน 600MB

นอกจากนี้ด้วยเวลารีเฟรช 5 วินาทีการเรนเดอร์ CanvasJS ยังตอบสนองได้ดีกว่า Highcharts

เราใช้ตัวจับเวลาหนึ่งตัว (setInterval 5 วินาที) เพื่อทำการเรียก REST API 4 ครั้งเพื่อดึงข้อมูลจากเซิร์ฟเวอร์ส่วนหลังซึ่งเชื่อมต่อกับ Elasticsearch แต่ละแผนภูมิจะอัปเดตเมื่อได้รับข้อมูลโดย JQuery.post ()

ที่กล่าวว่าสำหรับรายงานออฟไลน์ฉันจะใช้ Highcharts เนื่องจาก API ที่ยืดหยุ่นกว่า

นอกจากนี้ยังมีแผนภูมิ Zing ซึ่งอ้างว่าใช้ SVG หรือ Canvas แต่ยังไม่ได้ดู

ควรพิจารณา Canvas เมื่อประสิทธิภาพเป็นสิ่งสำคัญมาก SVG เพื่อความยืดหยุ่น ไม่ใช่ว่าเฟรมเวิร์กผ้าใบจะไม่ยืดหยุ่น แต่ต้องใช้เวลามากขึ้นสำหรับเฟรมเวิร์กผ้าใบเพื่อให้ได้ฟังก์ชันเดียวกันกับเฟรมเวิร์ก svg



0

ฉันยังพบว่าเมื่อเราพิมพ์เป็น PDF หน้าด้วยกราฟิก SVG ไฟล์ PDF ที่ได้จะยังคงมีรูปภาพที่เป็นเวกเตอร์ในขณะที่ถ้าคุณพิมพ์หน้าด้วยกราฟิก Canvas รูปภาพในไฟล์ PDF ที่ได้จะถูกแรสเตอร์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.