คราวนี้ ผมจะแชร์วิธีทำให้ขอบและมุมของส่วนโพลีไลน์ที่วาดออกมาบนผืนผ้าใบเรียบขึ้น ซึ่งก็คือการแทนที่กราฟโพลีไลน์เดิมโดยการส่งเส้นโค้ง Bezier ผ่านจุดวาดแต่ละจุด
เหตุใดจึงต้องมีเซ็กเมนต์โพลีไลน์ที่กระชับเรียบก่อนอื่น มาดูเอฟเฟกต์การเรนเดอร์ของแผนภูมิเส้นใต้ Echarts:
ตอนแรกฉันไม่ได้สังเกตว่าส่วนโพลีไลน์นี้เป็นเส้นโค้งที่ทะลุผ่านจริงๆ ฉันแค่คิดว่ามันเป็นจุดวาดที่เรียบง่าย ดังนั้นเวอร์ชันที่เรียบง่าย (น่าเกลียด) และง่าย (น่าเกลียด) ที่ฉันนำมาใช้ในตอนแรกจึงเป็นดังนี้:
อย่าใส่ใจกับสไตล์ ประเด็นสำคัญคือหลังจากการนำไปใช้ ฉันค้นพบว่าการใช้งาน Echarts ดูเหมือนจะราบรื่นมาก ซึ่งกระตุ้นให้เกิดการอภิปรายในภายหลังด้วย วิธีการวาดเส้นโค้งเรียบสม่ำเสมอ?
การเรนเดอร์
ก่อนอื่นเรามาดูการใช้งานการเลียนแบบขั้นสุดท้าย:
เพราะฉันไม่รู้ว่า Echarts ถูกนำไปใช้ภายในอย่างไร (escape
มันดูกลมมนมาก ใกล้เคียงกับวิสัยทัศน์ดั้งเดิมของเรามาก มาดูกันว่าเส้นโค้งผ่านจุดวาดหรือไม่:
ตกลง! ผลลัพธ์ที่ได้ชัดเจนแล้ว มาดูการใช้งานของเรากันดีกว่า
กระบวนการดำเนินการ
ข้อมูลจำลอง
var data = [Math.random() * 300]; for (var i = 1; i < 50; i++) { //ติดตาม echarts data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1])); } option = { canvas:{ id: 'canvas' }, ซีรี่ส์: { ชื่อ: 'ข้อมูลจำลอง', itemStyle: { color: 'rgb(255, 70, 131)' }, areaStyle: { สี: 'rgb(255, 158, 68)' }, ข้อมูล: ข้อมูล } };วาดแผนภูมิเส้น
ขั้นแรกให้เริ่มต้น Constructor เพื่อวางข้อมูลที่คุณต้องการ:
ฟังก์ชัน LinearGradient(ตัวเลือก) { this.canvas = document.getElementById(option.canvas.id) this.ctx = this.canvas.getContext('2d') this.width = this.canvas.width this.height = this.canvas .height this.tooltip = option.tooltip this.title = option.text this.series = option.series // ข้อมูลการจำลองการจัดเก็บข้อมูล}วาดแผนภูมิเส้น:
LinearGradient.prototype.draw1 = function() { //เส้นอ้างอิงโพลีไลน์... //ควรพิจารณาว่าต้นกำเนิดของผืนผ้าใบอยู่ที่มุมซ้ายบน //ดังนั้นการแปลงบางอย่างจำเป็นต้องทำด้านล่าง //diff คือ x แกน y คือข้อมูล ส่วนเท่ากันของช่วงค่าสูงสุดและค่าต่ำสุด this.series.data.forEach (ฟังก์ชั่น (รายการ, ดัชนี) { var x = diffX * ดัชนี, y = Math.floor (self.height - diffY * (รายการ - dataMin)) self.ctx.lineTo (x, y) // พล็อตจุดข้อมูลแต่ละจุด}) ...} Bezier Curve ฟิตติ้งเรียบลื่นจุดสำคัญของเส้นโค้ง Bezier คือการเลือกจุดควบคุม เว็บไซต์นี้สามารถแสดงเส้นโค้งต่างๆ ที่วาดด้วยจุดควบคุมที่แตกต่างกันแบบไดนามิก และสำหรับการคำนวณจุดควบคุม - ผู้เขียนยังคงเลือกไป่ตู้ เพราะเขาไม่เก่งคณิตศาสตร์ :) นักเรียนที่สนใจอัลกอริทึมเฉพาะสามารถเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้ได้ ตอนนี้เรามาพูดถึงข้อสรุปของการคำนวณจุดควบคุมกัน
สูตรข้างต้นเกี่ยวข้องกับจุดพิกัดสี่จุด จุดปัจจุบัน จุดก่อนหน้า และสองจุดถัดไป เมื่อค่าพิกัดดังแสดงในรูปด้านล่าง เส้นโค้งที่วาดจะเป็นดังนี้:
อย่างไรก็ตาม มีปัญหาคือไม่สามารถใช้สูตรนี้สำหรับจุดเริ่มต้นและจุดสุดท้ายได้ แต่บทความนั้นยังให้วิธีการประมวลผลค่าขอบเขตด้วย:
ดังนั้นเมื่อเปลี่ยนเส้นหลายเส้นเป็นเส้นโค้งเรียบ ให้คำนวณค่าขอบเขตและจุดควบคุมอื่นๆ แล้วแทนที่ลงในฟังก์ชัน Bessel:
//การใช้งานหลัก this.series.data.forEach(function(item, index) { //ค้นหาจุดควบคุมระหว่างจุดก่อนหน้าและจุดถัดไป var scale = 0.1 //สำหรับจำนวนบวกของจุดควบคุม ab คุณสามารถ ปรับ var Last1X = diffX * (ดัชนี - 1), Last1Y = Math.floor(self.height - diffY * (self.series.data[index - 1] - dataMin)) //พิกัดของจุดก่อนหน้า Last2X = diffX * (ดัชนี - 2), Last2Y = Math.floor(self.height - diffY * (self.series.data[index - 2] - dataMin)) // พิกัดสองจุดแรกตอนนี้ X = diffX * (ดัชนี) , nowY = Math.floor(self.height - diffY * (self.series.data[index] - dataMin)), //พิกัดจุดปัจจุบัน nextX = diffX * (ดัชนี + 1), nextY = Math.floor(self.height - diffY * (self.series.data[index + 1] - dataMin)), //พิกัดจุดถัดไป cAx = Last1X + (nowX - Last2X) * สเกล, cAy = Last1Y + (ตอนนี้ Y - Last2Y) * สเกล, cBx = ตอนนี้ X - (nextX - Last1X) * สเกล, cBy = ตอนนี้ Y - (ถัดไป - Last1Y) * สเกลถ้า (ดัชนี === 0) { self.ctx.lineTo(nowX, nowY) return } else if(index ===1) { cAx = Last1X + (nowX - 0) * scale cAy = Last1Y + (nowY - self.height) * scale } else ถ้า (index === self.series.data.length - 1) { cBx = nowX - (nowX - Last1X) * สเกล cBy = nowY - (ตอนนี้ Y - Last1Y) * สเกล } self.ctx.bezierCurveTo(cAx, cay, cBx, cBy, nowX, nowY); // วาดเส้นโค้ง Bezier จากจุดก่อนหน้าไปยังจุดปัจจุบัน})เนื่องจากจุดที่ฉันสำรวจในแต่ละครั้งคือจุดปัจจุบัน แต่สูตรที่ให้ไว้ในบทความคืออัลกอริธึมจุดควบคุมที่คำนวณจุดถัดไป ดังนั้นในการใช้งานโค้ด ฉันจึงย้ายการคำนวณของจุดทั้งหมดไปข้างหน้าที่เดียว เมื่อดัชนี = 0 ซึ่งเป็นจุดเริ่มต้น ไม่จำเป็นต้องวาดเส้นโค้ง เนื่องจากเรากำลังวาดเส้นโค้งจากจุดก่อนหน้าไปยังจุดปัจจุบัน และไม่มีเส้นโค้งถึง 0 ที่ต้องวาด เริ่มต้นจากดัชนี = 1 เราสามารถเริ่มวาดเส้นโค้งได้ตามปกติตั้งแต่ 0 ถึง 1 เนื่องจากไม่มีจุดที่สองอยู่ข้างหน้า เมื่อดัชนี = 1 เป็นจุดค่าขอบเขตซึ่งต้องใช้การคำนวณพิเศษ และสุดท้ายคือจุด A . สำหรับส่วนที่เหลือ ให้คำนวณพิกัด xy ของ AB ตามสูตรปกติแล้วแทนที่ลงในฟังก์ชัน Bessel
ในที่สุดดูซอร์สโค้ดที่นี่
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network