Dieses Mal werde ich Ihnen zeigen, wie Sie die Kanten und Ecken der gezeichneten Polyliniensegmente auf der Leinwand glätten, d. h. das ursprüngliche Polyliniendiagramm ersetzen, indem Sie die Bezier-Kurve durch jeden Zeichenpunkt führen.
Warum passende Polyliniensegmente glätten?Schauen wir uns zunächst den Rendering-Effekt des Liniendiagramms unter Echarts an:
Zuerst war mir nicht aufgefallen, dass es sich bei diesem Polyliniensegment tatsächlich um eine durchlaufende Kurve handelte. Ich dachte nur, es sei eine einfache Punktzeichnung, also sah die einfache (hässliche) und einfache (hässliche) Version zunächst so aus:
Achten Sie nicht auf den Stil. Der entscheidende Punkt ist, dass ich nach der Implementierung festgestellt habe, dass die Implementierung von Echarts sehr reibungslos zu sein scheint, was auch zu späteren Diskussionen geführt hat. Wie zeichnet man regelmäßig glatte Kurven?
Darstellungen
Schauen wir uns zunächst die Implementierung der endgültigen Nachahmung an:
Weil ich nicht weiß, wie Echarts intern implementiert ist (escape
Es sieht bereits sehr rund aus, sehr nah an unserer ursprünglichen Vision. Schauen wir mal, ob die Kurve durch den Zeichenpunkt verläuft:
OK! Das Ergebnis ist offensichtlich. Schauen wir uns nun unsere Umsetzung an.
Implementierungsprozess
simulierte Daten
var data = [Math.random() * 300]; for (var i = 1; i < 50; i++) { //Folge echarts data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1])); } option = { canvas:{ id: 'canvas' }, series: { name: 'Simulated data', itemStyle: { color: 'rgb(255, 70, 131)' }, areaStyle: { color: 'rgb(255, 158, 68)' }, data: data } };Zeichnen Sie ein Liniendiagramm
Initialisieren Sie zunächst einen Konstruktor, um die benötigten Daten zu platzieren:
function LinearGradient(option) { 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 //Speichersimulationsdaten}Zeichnen Sie ein Liniendiagramm:
LinearGradient.prototype.draw1 = function() { //Polylinien-Referenzlinie... //Es sollte berücksichtigt werden, dass der Ursprung der Leinwand die obere linke Ecke ist, //Daher müssen unten einige Konvertierungen durchgeführt werden, //diff ist x, y-Achse sind die Daten Die gleichen Teile des Bereichs der Maximal- und Minimalwerte. this.series.data.forEach(function(item, index) { var x = diffX * index, y = Math.floor(self.height - diffY * (item - dataMin)) self.ctx.lineTo(x, y) //Einzelne Datenpunkte grafisch darstellen}) ...} Glatte Anpassung der Bezier-KurveDer entscheidende Punkt der Bezier-Kurve ist die Auswahl der Kontrollpunkte. Auf dieser Website können verschiedene Kurven dynamisch angezeigt werden, die mit unterschiedlichen Kontrollpunkten gezeichnet wurden. Und zur Berechnung von Kontrollpunkten. . Der Autor hat sich immer noch für Baidu entschieden, schließlich ist er nicht gut in Mathematik :). Studierende, die sich für den spezifischen Algorithmus interessieren, können mehr darüber erfahren. Lassen Sie uns nun über die Schlussfolgerung der Berechnung von Kontrollpunkten sprechen.
Die obige Formel umfasst vier Koordinatenpunkte, den aktuellen Punkt, den vorherigen Punkt und die nächsten beiden Punkte. Wenn die Koordinatenwerte wie in der folgenden Abbildung dargestellt sind, sieht die gezeichnete Kurve wie folgt aus:
Allerdings besteht das Problem, dass diese Formel nicht für den Startpunkt und den Endpunkt verwendet werden kann, dieser Artikel aber auch eine Methode zur Verarbeitung von Grenzwerten angibt:
Wenn Sie also die Polylinie in eine glatte Kurve ändern, berechnen Sie die Grenzwerte und andere Kontrollpunkte und ersetzen Sie sie in der Bessel-Funktion:
//Kernimplementierung this.series.data.forEach(function(item, index) { //Finden Sie den Kontrollpunkt zwischen dem vorherigen Punkt und dem nächsten Punkt. var scale = 0.1 //Für eine positive Zahl von ab-Kontrollpunkten ist dies möglich Passen Sie var last1X = diffX * (index - 1), last1Y = Math.floor(self.height - diffY * (self.series.data[index - 1] - dataMin)), //Die Koordinaten des vorherigen Punkts last2X = an diffX * (index - 2), last2Y = Math.floor(self.height - diffY * (self.series.data[index - 2] - dataMin)), //Die ersten beiden Punktkoordinaten nowX = diffX * (index) , nowY = Math.floor(self.height - diffY * (self.series.data[index] - dataMin)), //Aktuelle Punktkoordinaten nextX = diffX * (index + 1), nextY = Math.floor(self.height - diffY * (self.series.data[index + 1] - dataMin)), //Nächste Punktkoordinate cAx = last1X + (nowX - last2X) * Maßstab, cAy = last1Y + (nowY - last2Y) * Skala, cBx = nowX - (nextX - last1X) * Skala, cBy = nowY - (nextY - last1Y) * Skala if(index === 0) { self.ctx.lineTo(nowX, nowY) return } else if(index ===1) { cAx = last1X + (nowX - 0) * Scale cAy = last1Y + (nowY - self.height) * Scale } else if (index === self.series.data.length - 1) { cBx = nowX - (nowX - last1X) * Scale cBy = nowY - (nowY - last1Y) * Scale } self.ctx.bezierCurveTo(cAx, cAy, cBx, cBy, nowX, nowY); //Zeichne die Bezier-Kurve vom vorherigen Punkt zum aktuellen Punkt})Da der Punkt, den ich jedes Mal überquere, der aktuelle Punkt ist, die im Artikel angegebene Formel jedoch ein Kontrollpunktalgorithmus ist, der den nächsten Punkt berechnet, habe ich in der Codeimplementierung die Berechnung aller Punkte um eine Stelle nach vorne verschoben. Wenn Index = 0 ist, was der Anfangspunkt ist, muss keine Kurve gezeichnet werden, da wir eine Kurve vom vorherigen Punkt zum aktuellen Punkt zeichnen und es keine Kurve zu 0 gibt, die gezeichnet werden muss. Ab Index = 1 können wir normal mit dem Zeichnen der Kurve von 0 bis 1 beginnen, da sich bei Index = 1 kein zweiter Punkt davor befindet, sondern ein Grenzwertpunkt, der eine spezielle Berechnung erfordert, und schließlich ein Punkt . Im Übrigen berechnen Sie einfach die xy-Koordinaten von AB gemäß der normalen Formel und setzen sie in die Bessel-Funktion ein.
endlichDen Quellcode finden Sie hier
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.