HTML - PHP - MySQL - SVG

KERNI's SEITE

Kreisdiagramm

Veröffentlicht am


Kreisdiagramm

 

Ein Kreisdiagramm zu zeichnen ist weniger schwer als man vermuten möchte. Mit ein wenig Javascript werden die vorgegebenen Werte durchlaufen und in die einzelnen Kuchenstücke umgerechnet.

 

 

let colorArr = ["#125e37","#FFF0A5","#FFB03B","#B64926","#8E2800","#338855","#ff0000","#ff00ff"];
let pieData = [20,70,60,280,27,64,230,80];
let sectorAngleArr = [];
let total = 0;
let startAngle = 0;
let endAngle = 0;
let radius = 80;
let x = 100;
let y = 100;
let x1,x2,y1,y2 = 0;
let p;
 
function init(){
   p = document.getElementById("svg1");
   // RECHNE ALLE WERTE ZUSAMMEN
   // CALCULATE THE TOTAL
   for(let k=0; k < pieData.length; k++){
      total += pieData[k];
   }
   // BERECHNUNG DER WINKEL, DIE JEDER SEKTOR EINNIMMT, UND IN ARRAY SPEICHERN
   // CALCULATE THE ANGLES THAT EACH SECTOR SWIPES AND STORE IN AN ARRAY
   for(let i=0; i < pieData.length; i++){
      let angle = (360 * pieData[i] / total);
      sectorAngleArr.push(angle);
   }
   drawArcs();
}
 
function drawArcs(){
 
   let d = '';
   let d2 = '';
   let endline = 0;
   let ta = '';
 
   for(let i=0; i < sectorAngleArr.length; i++){
      startAngle = endAngle;
      endAngle = startAngle + sectorAngleArr[i];
 
      x1 = (x + radius * Math.cos(Math.PI * startAngle / 180));
      y1 = (y + radius * Math.sin(Math.PI * startAngle / 180));
 
      x2 = (x + radius * Math.cos(Math.PI * endAngle / 180));
      y2 = (y + radius * Math.sin(Math.PI * endAngle / 180));         
 
      d = "M"+x+","+y+" L"+x1+","+y1+" A"+radius+","+radius+" 0 0,1 "+x2+","+y2+" z"; // 1 MEANS CLOCKWISE
 
      p.innerHTML = p.innerHTML + "<path d='"+d+"' style='fill:"+colorArr[i]+"; stroke-width:1px; stroke:#000; opacity:1;'></path>";
   }
}

 

Mit ein paar Modifikationen kann auch noch für jedes Kuchenstück ein Beschreibungstext hinzugefügt werden.

 

Jetzt sollte das Diagramm so aussehen. Um die Breite des Textes auf der linken Seite nicht berechnen zu müssen gibt es das text-anchor Attribut. Jeder Text zwischen 90 und 270 Grad ( alle auf der Linken Seite ) bekommen das text-anchor="end". Alle anderen text-anchor="start".

SonstigeRollschuheSegwayAutoPferdSchlittenMotoradBoot

 

Hier noch mal der komplette Code

let startAngle = 0;
let endAngle = 0;
let colorArr = ["#125e37","#FFF0A5","#FFB03B","#B64926","#8E2800","#338855","#ff0000","#ff00ff"];
let pieData = [20,70,60,280,27,64,230,80];
let pieTextData = ["Sonstige","Rollschuhe","Segway","Auto","Pferd","Schlitten","Motorad","Boot"];
let sectorAngleArr = [];
let total = 0;
let radius = 80;
let radius2 = 110;
let x = 150;
let y = 150;
let p;
 
function init(){
   p = document.getElementById("svg1");
   // RECHNE ALLE WERTE ZUSAMMEN
   // CALCULATE THE TOTAL
   for(let k=0; k < pieData.length; k++){
      total += pieData[k];
   }
   // BERECHNUNG DER WINKEL, DIE JEDER SEKTOR EINNIMMT, UND IN ARRAY SPEICHERN
   // CALCULATE THE ANGLES THAT EACH SECTOR SWIPES AND STORE IN AN ARRAY
   for(let i=0; i < pieData.length; i++){
      let angle = (360 * pieData[i] / total);
      sectorAngleArr.push(angle);
   }
   drawArcs();
}
 
function drawArcs(){
 
   let d = '';
   let d2 = '';
   let endline = 0;
   let ta = '';
 
   for(let i=0; i < sectorAngleArr.length; i++){
      startAngle = endAngle;
      endAngle = startAngle + sectorAngleArr[i];
 
      lineAngle = startAngle + sectorAngleArr[i] / 2;
 
      let x1 = (x + radius * Math.cos(Math.PI * startAngle / 180));
      let y1 = (y + radius * Math.sin(Math.PI * startAngle / 180));
 
      let x2 = (x + radius * Math.cos(Math.PI * endAngle / 180));
      let y2 = (y + radius * Math.sin(Math.PI * endAngle / 180));
 
      let x3 = (x + radius * Math.cos(Math.PI * lineAngle / 180));
      let y3 = (y + radius * Math.sin(Math.PI * lineAngle / 180));
 
      let x4 = (x + radius2 * Math.cos(Math.PI * lineAngle / 180));
      let y4 = (y + radius2 * Math.sin(Math.PI * lineAngle / 180));
 
      d = "M"+x+","+y+" L" + x1 + "," + y1 + " A" + radius + "," + radius + " 0 0,1 " + x2 + "," + y2 + " z"; // 1 means clockwise
 
      // Da nur 8 Farben vorgegeben sind: i Modulo 8 ( colorArr[i%8] )
      p.innerHTML = p.innerHTML + "<path d='"+d+"' style='fill:"+colorArr[i%8]+";stroke-width:.5;stroke:#000;opacity:1;'></path>";
 
      if( lineAngle > 90 && lineAngle < 270 ){
         d2 = "M"+x3+","+y3+" "+x4+","+y4+" h -20";
         endline = -25;
         ta = "end";
      }else{
         d2 = "M"+x3+","+y3+" "+x4+","+y4+" h 20";
         endline = 25;
         ta = "start";
      }
      p.innerHTML = p.innerHTML + "<path d='"+d2+"' style='fill:none; stroke-width:.5;stroke:#000;'></path>";
      p.innerHTML = p.innerHTML + "<text x='"+(x4+endline)+"' y='"+(y4+5)+"' text-anchor='"+ta+"'>"+pieTextData[i]+"</text>";
   }
}