ไลบรารี D3 เหมาะอย่างยิ่งสำหรับการสร้างการแสดงภาพข้อมูลที่ครบถ้วนและโต้ตอบได้ซึ่งทำงานในเบราว์เซอร์ของคุณ D3 เป็นไลบรารี JavaScript ที่ให้การเชื่อมโยงที่ง่ายดายระหว่างพลังของ SVG (Scalable Vector Graphics) ในเบราว์เซอร์และแอปพลิเคชัน JavaScript ของคุณ (และของฉัน) เอง ไม่ว่าคุณจะใช้ React, Angular, Vue หรือเว็บเฟรมเวิร์กหรือโปรแกรมอื่นๆ ในเทคโนโลยี W3C ทั่วไป D3 ก็มอบ API ที่ใช้งานง่ายเพื่อจัดการอ็อบเจ็กต์ SVG และทำให้วัตถุเป็นแบบโต้ตอบและเคลื่อนไหวได้ ขั้นตอนง่ายๆ ในการเริ่มใช้งาน SVG และ D3.js ได้อธิบายไว้ในบทความก่อนหน้าของฉันเกี่ยวกับ การสร้างเกมอย่างง่ายด้วย D3

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

ฉันใช้เวลาสักพักกว่าจะเข้าใจว่า d3-force คืออะไร และอะไรไม่ใช่ด้วย ให้ฉันพยายามอธิบาย:

  • แรง d3 สามารถคำนวณตำแหน่งและความเร็วของธาตุต่างๆ ในระบบที่อยู่ภายใต้กฎที่คล้ายกับกฎฟิสิกส์ เช่น กฎแรงโน้มถ่วง หรือแรงอันตรกิริยาอื่นๆ หรือสนามแรง
  • สามารถใช้แรง d3 เพื่อกำหนดองค์ประกอบที่มีขนาด มวล ตำแหน่งเริ่มต้น และความเร็วของตำแหน่งและความเร็วขององค์ประกอบนั้น ( ณ เวลาใดเวลาหนึ่งหรือหลังจากช่วงเวลาหนึ่ง) — ตัวอย่างเช่น เพื่อค้นหาสถานะสิ้นสุดที่เสถียร (ถ้ามี) .
  • d3-force ไม่ทำงานกับองค์ประกอบ SVG d3-force ทำหน้าที่กับข้อมูล
  • เราสามารถนำผลลัพธ์จากการคำนวณ (หรือที่เรียกว่าการจำลอง) ของ d3-force และแสดงภาพโดยใช้องค์ประกอบ SVG หากเราต้องการเห็นภาพผลลัพธ์จากการจำลองแรง d3 ก็ขึ้นอยู่กับเราเองที่จะทำแบบนั้น เพราะนั่นไม่ใช่สิ่งที่ d3-force ทำ หลังจากการวนซ้ำของการจำลองแต่ละครั้ง (เรียกว่า "ขีด") เราสามารถใช้ผลการคำนวณระดับกลางและวาดภาพจากผลลัพธ์เหล่านี้โดยใช้ SVG หรือเราไม่ทำก็ได้ (d3-force ไม่สนใจวิธีใดวิธีหนึ่ง)
  • นอกจากนี้เรายังสามารถปล่อยให้ d3-force ผ่านขั้นตอนการจำลองหลายขั้นตอน และใช้เฉพาะผลลัพธ์ 'สุดท้าย' เพื่อแสดงภาพ (หรือไม่แม้แต่แสดงภาพ) ตำแหน่งสุดท้ายขององค์ประกอบในระบบที่ใช้ในการจำลอง
  • d3-force สามารถใช้ได้โดยไม่มีส่วนอื่นๆ ของ d3 และไม่มีการแสดงภาพในระดับใดๆ

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

นี่คือการจำลองภาพที่เกิดขึ้นจริง:

สาระสำคัญของโค้ดที่สร้างพฤติกรรมนี้:

ไลบรารี d3 ถูกโหลดลงในเอกสาร HTML แบบคงที่นี้ มีการสร้างอาร์เรย์ที่มี 40 องค์ประกอบ แต่ละองค์ประกอบได้รับการกำหนดคุณสมบัติแบบสุ่ม: คุณสมบัติที่เรียกว่า x และ y — ซึ่งค่าจะถูกนำมาจากช่วงสุ่มระหว่าง 0 ถึง w และ h (ซึ่งแสดงถึงความกว้างและความสูงของบางพื้นที่) และ r — แมปกับรัศมีของวงกลม — และ สี. โปรดทราบว่าในตอนแรกสิ่งเหล่านี้เป็นเพียงออบเจ็กต์ข้อมูล โดยไม่มีความสัมพันธ์กับออบเจ็กต์ SVG องค์ประกอบ HTML หรืออะไรก็ตามที่เกี่ยวข้องกับการแสดงภาพ การจำลองแรง D3 คาดหวังหรือสร้างคุณสมบัติที่เรียกว่า x และ y (และอาจเป็นทางเลือก vx และ vy สำหรับส่วนประกอบเวกเตอร์ความเร็ว และอาจรวมถึง fx และ fy เพื่อระบุค่า x และ y ที่การจำลองไม่ควรเปลี่ยนแปลง)

ฟังก์ชัน doSVG() ในกรณีนี้จะทำการแมปองค์ประกอบข้อมูลเหล่านี้กับออบเจ็กต์ SVG ที่สร้างโดยใช้ d3 เพื่อให้เราสามารถเห็นการแสดงการจำลองแบบเคลื่อนไหวและผลลัพธ์สุดท้ายได้ และเมื่อการจำลองแรง d3 ทำงานกับองค์ประกอบข้อมูลเหล่านี้ มันจะอัปเดตพิกัด x และ y และเราใช้สิ่งเหล่านั้นเพื่อวาดองค์ประกอบ SVG ใหม่

โปรดทราบว่าเราสามารถรันการจำลองได้โดยไม่ต้องสร้างองค์ประกอบ SVG ใดๆ ตัวจัดการ tickสามารถลงทะเบียนตำแหน่ง x และ y สุดท้ายหลังจากการวนซ้ำหลายครั้ง และพิจารณาว่าเป็นเพียงผลลัพธ์เดียวของการจำลอง

อย่างไรก็ตาม ในกรณีนี้ blipElements คือวัตถุวงกลม SVG ที่สร้างขึ้นสำหรับองค์ประกอบอาร์เรย์ node_data โดยใช้คุณสมบัติขององค์ประกอบเหล่านี้ในการวาดวงกลม ในตัวจัดการ ติ๊ก ตำแหน่งของแต่ละวงกลมจะได้รับการอัปเดต (โดยการปรับคำสั่งการแปลของแอตทริบิวต์การแปลง) โดยขึ้นอยู่กับค่าคุณสมบัติ x และ y ที่คำนวณใหม่

การจำลองถูกกำหนดด้วยแรงสามแบบ: แรง x และ y ที่ดึงองค์ประกอบทั้งหมดไปยังศูนย์กลางของพื้นที่ SVG และแรง ชนกัน ที่ป้องกันไม่ให้วงกลมมาปิด ระยะทางที่วงกลมเก็บไว้จากวงกลมอื่นๆ ทั้งหมดจะถูกตั้งค่าไว้ที่รัศมีบวกค่าคงที่ nodePadding

sim = d3.forceSimulation(node_data)
.force(“x”, d3.forceX(w / 2))
.force(“y”, d3.forceY(h / 2))
.force(“collide”, d3.forceCollide().radius(d => d.r + nodePadding))

แรง x ดึงองค์ประกอบทั้งหมดไปยังเส้นแนวตั้งที่ x = 300 แรง y ดึงองค์ประกอบไปยังเส้นแนวนอนที่ y = 200 หากไม่มีแรงชนกัน (ต้าน) องค์ประกอบทั้งหมดจะเคลื่อนที่ไปที่ ( 300, 200) ซึ่งซ้อนทับกันอยู่ที่ศูนย์กลางของระบบเล็กๆ นี้ อย่างไรก็ตาม แรงชนกันจะป้องกันการชนกัน (หรือ: การทับซ้อนกัน) และรักษาระยะห่างขององค์ประกอบต่างๆ องค์ประกอบวงกลมแต่ละองค์ประกอบจะไม่เข้าใกล้รัศมีของมันเอง บวกกับค่าคงที่การเติมโหนด ซึ่งตั้งค่าไว้ที่ 3 กับองค์ประกอบอื่นๆ เนื่องจากตรรกะเดียวกันนั้น (กำหนดในฟังก์ชันที่ส่งผ่านไปยัง d3.forceCollide().radius()) ถูกนำไปใช้กับองค์ประกอบทั้งหมด วงกลมทั้งหมดจึงมีโซนบัฟเฟอร์ระหว่างองค์ประกอบอย่างน้อย 6

ทันทีที่มีการกำหนดการจำลอง การจำลองจะเริ่มทำงาน สามารถหยุดได้ (ด้วย sim.stop()) และสามารถลงทะเบียนตัวจัดการได้ด้วย — เช่น ตัวจัดการ tick ที่แสดงไว้ที่นี่ หลังจากการวนซ้ำแต่ละครั้งของการจำลอง — เมื่อมีการคำนวณค่าคุณสมบัติ x และ y ใหม่สำหรับองค์ประกอบข้อมูลทั้งหมดแล้ว ฟังก์ชันที่ลงทะเบียนเป็นตัวจัดการเห็บจะถูกเรียก ค่า x และ y ใหม่พร้อมใช้งานและสามารถใช้เพื่อทำ ….. อะไรก็ได้ ทางเลือกหนึ่งคือการอัปเดตการแสดง UI ขององค์ประกอบข้อมูล แต่โปรดจำไว้ว่านี่เป็นทางเลือกโดยสมบูรณ์

พลังที่กำหนดเอง

นอกเหนือจากกองกำลังนอกกรอบที่จัดส่งในรูปแบบ d3-force แล้ว นักพัฒนายังสามารถรวมกองกำลังแบบกำหนดเองไว้ในการจำลองได้อีกด้วย เมื่อการจำลองทำงาน ฟังก์ชันแรงแบบกำหนดเองจะถูกเรียกใช้เพื่อปรับตำแหน่งและความเร็วขององค์ประกอบทั้งหมดในระบบตามที่เห็นสมควร เอฟเฟกต์ของพลังแบบกำหนดเองจะรวมกับเอฟเฟกต์ของพลังอื่น ๆ ที่กำลังเล่นอยู่

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

เพียงเพื่อให้แน่ใจว่า d3-force ไม่ทราบถึงสี่เหลี่ยมสีแดง มันถูกวาดขึ้นเพื่อความสะดวกของคุณเท่านั้น อย่างไรก็ตาม แรงแบบกำหนดเองที่เพิ่มเข้าไปในการจำลองจะแก้ไของค์ประกอบใดๆ ที่เข้ามาในพื้นที่

เราสามารถกำหนดแรงแบบกำหนดเองได้ด้วยตรรกะใดๆ ก็ตามที่เราคิดได้ — และยกตัวอย่าง องค์ประกอบวงกลมที่รวมตัวกันรอบๆ รูปร่างที่น่าสนใจต่างๆ

ทรัพยากร

บทความก่อนหน้านี้ของฉันเอง — บทนำของ SVG และ D3 สำหรับการสร้างเกมง่ายๆ บนเบราว์เซอร์ https://technology.amis.nl/frontend/starting-my-own-game-studio-on-the-ease-and- พลังของ svg/

แหล่งที่มาของการจำลองที่กล่าวถึงในบทความนี้: https://github.com/lucasjellema/code-cafe-intro-to-svg

บทความเกี่ยวกับการบรรจุแบบวงกลม D3 (การจัดกลุ่มรูปร่าง): แรง x,y ที่แตกต่างกันสำหรับแต่ละกลุ่มที่เรามองเห็น — https://www.d3-graph-gallery.com/graph/circularpacking_group.html

เอกสาร D3 บน Force — https://github.com/d3/d3-force

การสาธิตการใช้ d3-force เพื่อจำลองระบบสุริยะ: https://bl.ocks.org/vasturiano/54dd054d22be863da5afe2db02e033e2

เผยแพร่ครั้งแรกที่ https://technology.amis.nl เมื่อวันที่ 24 พฤษภาคม 2021