Maison  >  Article  >  interface Web  >  Introduction à la méthode de dessin d'un camembert avec canevas (code)

Introduction à la méthode de dessin d'un camembert avec canevas (code)

不言
不言avant
2019-04-03 13:10:454031parcourir

Ce que cet article vous apporte est une introduction à la méthode de dessin d'un diagramme circulaire sur toile (code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

1. Description de la tâche

Utilisez le canvasAPI natif pour dessiner un diagramme circulaire (Nightingale Rose). (Les captures d'écran et les données proviennent de la bibliothèque d'échantillons officielle de Baidu Echarts [Voir l'exemple de lien]).

Introduction à la méthode de dessin d'un camembert avec canevas (code)

2. Conseils importants

Il existe de nombreuses façons de dessiner le diagramme de la rose Nightingale. Les deux méthodes fournies dans Echarts sont le rayon ou la surface différente. modes, cet article prend comme exemple la méthode de dessin proportionnel à la surface, l'algorithme de dessin est le suivant :

  1. Déterminer l'angle de chaque secteur. Puisque les angles de tous les secteurs totalisent 2π, on calcule d'abord l'angle en fonction du rapport de données :

Introduction à la méthode de dessin d'un camembert avec canevas (code)

  1. L'aire de chaque secteur et la superficie totale Le rapport entre eux est le rapport des valeurs. Les valeurs maximales et minimales dans le tableau de paramètres donné options.radius sont utilisées comme données de dessin du secteur avec la plus grande valeur. Remplacez-les dans la formule suivante pour obtenir. la superficie totale S :

Introduction à la méthode de dessin d'un camembert avec canevas (code)

  1. Utilisez ensuite la formule ci-dessus pour calculer le rayon du cercle extérieur correspondant de chaque secteur, tracez le chemin dans la toile et remplissez-le.

3. Exemple de code

Exemple de code de dessin de diagramme de rose rossignol :

//绘制饼图
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);
}

L'effet peut être visualisé dans le navigateur :

Introduction à la méthode de dessin d'un camembert avec canevas (code)

4. L'idée de mise en œuvre du survol en surbrillance

  1. Pendant le processus de dessin, les données de dessin de chaque secteur (rayon, angle de départ par rapport au centre du cercle, angle de secteur) sont montés sur les données du dessin.
  2. Écoute l'événement de mouvement de la souris canvas sur la balise mousemove et convertit les événements de mouvement de la souris event.clientX et event.clientY en valeurs numériques (mouseX,mouseY) par rapport aux coordonnées du canevas dans le fonction de rappel.
  3. est connecté des coordonnées du centre du cercle (paintingCenter.x,paintingCenter.y) à (mouseX,mouseY) en tant que vecteur En fonction de l'angle et du module du vecteur, vous pouvez déterminer si la souris se trouve sur un certain secteur.
  4. S'il est au dessus du secteur, dessinez l'image clé avec l'animation de transition pour faire apparaître l'effet de survol. Modifiez d'abord la couleur context.fillStyle en couleur de surbrillance du secteur correspondant, puis augmentez le rayon de dessin du cercle extérieur à la taille cible (par exemple, 10 %) de manière linéaire image par image, et utilisez le contexte de dessin de la toile pour re -fermez la zone de dessin dans chaque cadre. Tracez simplement la ligne puis remplissez-la.
  5. Lorsque l'effet de survol apparaît, dessinez la zone de dessin en couleur en surbrillance. Lorsque l'effet de survol disparaît, dessinez simplement les secteurs extérieurs blancs image par image en commençant par le cercle extérieur, et enfin dessinez les secteurs de données dans. la couleur d'origine.

[Recommandations associées : Tutoriel vidéo HTML5]

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer