Heim  >  Artikel  >  Web-Frontend  >  Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

不言
不言nach vorne
2019-04-03 13:10:454031Durchsuche

Der Inhalt dieses Artikels ist eine Einführung in die Methode zum Zeichnen von Kreisdiagrammen auf Leinwand (Code). Ich hoffe, dass er für Sie hilfreich ist.

1. Aufgabenbeschreibung

Verwenden Sie natives canvasAPI, um ein Kreisdiagramm (Nightingale Rose) zu zeichnen. (Screenshots und Daten stammen aus der offiziellen Beispielbibliothek von Baidu Echarts [Beispiellink anzeigen]).

Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

2. Wichtige Tipps

Es gibt viele Möglichkeiten, das Nachtigall-Rosendiagramm zu zeichnen. Die beiden in Echarts bereitgestellten Methoden sind unterschiedlich In diesem Artikel wird als Beispiel die flächenproportionale Zeichenmethode verwendet. Der Zeichenalgorithmus lautet wie folgt:

  1. Bestimmen Sie den Winkel jedes Sektors. Da sich die Winkel aller Sektoren zu 2π addieren, berechnen wir zunächst den Winkel gemäß dem Datenverhältnis:

Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

  1. Die Fläche jedes Sektors und die Gesamtfläche Das Verhältnis zwischen ihnen ist das Verhältnis der Werte im angegebenen Parameterarray options.radius werden als Zeichnungsdaten des Sektors mit dem größten Wert verwendet die Gesamtfläche S:

Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

  1. Verwenden Sie dann die obige Formel, um den entsprechenden Außenkreisradius jedes Sektors zu berechnen, und zeichnen Sie den Pfad auf der Leinwand und fülle es.

3. Beispielcode

Beispielcode für die Zeichnung eines Nachtigall-Rosendiagramms:

//绘制饼图
drawPieChart(options);
    
/**
 * 绘制饼图
 * @param  {[type]} options [description]
 * @return {[type]}         [description]
 */
function drawPieChart(options) {
   //记录最大数值以反求面积总和
   options.maxValue = 0;
   //求数据集总和以在后续计算每个扇形的角度比例
   options.totalNum = options.data.reduce((pre,cur)=>{
     if (cur.value > options.maxValue) {
         options.maxValue = cur.value;
     }
     return pre+cur.value;
   },0);
    /*以最大值对应最大半径来计算面积总和,并覆盖原值
    *使得最大的一块扇形外圆半径为options.radius[0]
    *内圆半径为options.radius[1]
    */
    let Rmin = options.radius[0];
    let Rmax = options.radius[1];
    let r = Math.sqrt((Rmax*Rmax - Rmin*Rmin)*options.totalNum / options.maxValue + Rmin*Rmin);
    options.radius[1] = r;
    //移动坐标系原点至绘图中心
   let paintingCenter={
     x:parseInt(options.center[0],10)/100 * (options.chartZone[2] - options.chartZone[0]) + options.chartZone[0],
     y:parseInt(options.center[1],10)/100 * (options.chartZone[3] - options.chartZone[1]) + options.chartZone[1]
   }
   context.translate(paintingCenter.x, paintingCenter.y);
    //绘制每个扇形,过程中累加旋转角度
   let allAngle = options.data.reduce((prev,cur,index)=>{
       context.fillStyle = options.colorPool[index]
       let angle = calcPaintingData(cur,options);
       return prev + angle;
   },0);
   //绘制中空白色圆
   context.beginPath();
   context.fillStyle = 'white';
   context.arc(0,0,options.radius[0],0,2*Math.PI,false);
   context.fill();
}

/**
 * 计算每个扇形所需要的绘图参数
 */
function calcPaintingData(data,options) {
    let scale = data.value / options.totalNum; 
    let angle = scale * 2 * Math.PI;
    let Rmin = options.radius[0];
    let Rmax = options.radius[1];
    let r = Math.sqrt(scale * (Rmax*Rmax - Rmin*Rmin) + Rmin*Rmin);
    data.r = r;
    //绘制扇形
    paintFan({
        r:r,
        angle:angle,
        data:data,
        options:options
    });
    return angle;//将角度值返回给外层函数以供累加
}

//绘制扇形
function paintFan(opt) {
    context.beginPath();
    context.lineTo(opt.r,0);
    context.arc(0,0,opt.r,0,opt.angle,false);
    context.lineTo(0,0);
    context.closePath();
    context.fill();
    context.rotate(opt.angle);
}

Der Effekt kann im Browser angezeigt werden:

Einführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code)

4. Die Implementierungsidee der Hover-Hervorhebung

  1. Während des Zeichenvorgangs werden die Zeichendaten jedes Sektors (Radius, Startwinkel relativ zum Mittelpunkt des Kreises, Sektorwinkel) werden auf den Zeichnungsdaten montiert.
  2. Hört das Mausbewegungsereignis canvas auf dem mousemove-Tag und wandelt die Mausbewegungsereignisse event.clientX und event.clientY in numerische Werte (mouseX,mouseY) relativ zu den Leinwandkoordinaten im um Rückruffunktion.
  3. wird von den Kreismittelpunktkoordinaten (paintingCenter.x,paintingCenter.y) mit (mouseX,mouseY) als Vektor verbunden. Anhand des Winkels und des Moduls des Vektors können Sie feststellen, ob sich die Maus auf einem bestimmten Sektor befindet.
  4. Wenn es sich über dem Sektor befindet, zeichnen Sie den Keyframe mit Übergangsanimation, damit der Hover-Effekt erscheint. Ändern Sie zunächst die context.fillStyle-Farbe in die Hervorhebungsfarbe des entsprechenden Sektors, erhöhen Sie dann den Zeichnungsradius des äußeren Kreises linear auf die Zielgröße (z. B. 10 %) Bild für Bild und verwenden Sie den Zeichenkontext der Leinwand, um erneut zu zeichnen -Schließen Sie den Zeichenbereich in jedem Rahmen. Zeichnen Sie einfach die Linie und füllen Sie sie dann aus.
  5. Wenn der Hover-Effekt erscheint, zeichnen Sie den hervorgehobenen Farbzeichenbereich. Wenn der Hover-Effekt verschwindet, zeichnen Sie einfach die weißen äußeren Sektoren Bild für Bild, beginnend mit dem äußeren Kreis, und zeichnen Sie schließlich die Datensektoren hinein die Originalfarbe.

[Verwandte Empfehlungen: HTML5-Video-Tutorial]

Das obige ist der detaillierte Inhalt vonEinführung in die Methode zum Zeichnen von Kreisdiagrammen mit Canvas (Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen