<?php
|
/*---------------------------------------------------------------*/
|
/*
|
Titre : Creer un camembert 2D facilement
|
|
URL : https://phpsources.net/code_s.php?id=514
|
Auteur : MwOuAaa
|
Date édition : 20 Mai 2009
|
Date mise à jour : 11 Aout 2019
|
Rapport de la maj:
|
- modification de la description
|
*/
|
/*---------------------------------------------------------------*/
|
function Camembert($value, $autoVal = false, $legend = false, $legendVal = false
|
, $title = false, $key = false, $width = false, $height = false, $marge_x =
|
false, $marge_y = false, $width_legend = false) {
|
// Analyse des valeurs
|
$somme = 0;
|
for($t=0;$t<count($value);$t++) {
|
$somme += $value[$t];
|
}
|
|
// Si $autoVal est vrai, calcul du pourcentage automatique
|
if($autoVal) {
|
$tab_val = $value;
|
$value = '';
|
$value = array();
|
/* EDIT */
|
for($p=0;$p<count($tab_val);$p++) {
|
$calc = ($tab_val[$p] * 100) / $somme;
|
if($calc>0.1239) {
|
$value[] = ($tab_val[$p] * 100) / $somme;
|
};
|
}
|
/* FIN DE L'EDIT */
|
} else {
|
// Sinon verification de la somme
|
if($somme!=100) {
|
echo
|
'<strong>Erreur:</strong> La somme des valeurs n\'est pas egale a 100% !<br />';
|
echo
|
'<strong>Notice:</strong> Vous pouvez calculer les valeurs en placant la' .
|
' variable <em>$autoVal</em> a <strong>true</strong>.';
|
return false;
|
};
|
};
|
|
// Definition de la taille
|
if(!$width) {
|
$width = 300;
|
};
|
if(!$height) {
|
$height = 300;
|
};
|
if(!$width_legend) {
|
$width_legend = 200;
|
};
|
|
// Creation des marges
|
if(!$marge_x) {
|
$marge_x = 20;
|
};
|
if(!$marge_y) {
|
$marge_y = 20;
|
};
|
|
// Creation de la ressource
|
$graf = imagecreatetruecolor($width, $height);
|
|
// Creation du tableau de couleur
|
$Couleur = array();
|
|
// Definition des polices
|
// A ADAPTER A VOS BESOIN !
|
|
// Dans le cas présent les fichier TTF sont situé dans un dossier fonts
|
$Font['HypatiaSansPro'] = realpath('fonts/HypatiaSansPro-Bold.otf');
|
$Font['Verdana'] = realpath('fonts/verdana.ttf');
|
$Font['Verdana_Bold'] = realpath('fonts/verdanab.ttf');
|
|
// Definition des couleurs principales
|
$Couleur['Blanc'] = imagecolorallocate($graf, 0xFF, 0xFF, 0xFF);
|
$Couleur['Noir'] = imagecolorallocate($graf, 0x00, 0x00, 0x00);
|
|
// Definition des couleurs de portions
|
$ColorHex = array();
|
$ColorHex['Red'] = array(0x00, 0xCA, 0x00, 0x00, 0xF7, 0xA1, 0x00, 0x0E,
|
0x00, 0xFF);
|
$ColorHex['Green'] = array(0x00, 0x00, 0x00, 0xCA, 0xBA, 0x03, 0x79, 0x00,
|
0xFF, 0xF2);
|
$ColorHex['Blue'] = array(0x00, 0x00, 0xCA, 0x00, 0x00, 0x79, 0x00, 0x00,
|
0xFF, 0xBD);
|
$Couleur_Portion = array();
|
|
for($c=0;$c<count($ColorHex['Red']);$c++) {
|
$Couleur_Portion[$c] = imagecolorallocate($graf, $ColorHex['Red'][$c],
|
$ColorHex['Green'][$c], $ColorHex['Blue'][$c]);
|
}
|
|
// Fond de l'image
|
imagefilledrectangle($graf, 0, 0, $width, $height, $Couleur['Blanc']);
|
|
// Dessine le contour du camembert
|
imagefilledellipse($graf, $width / 2, $height / 2, $width - $marge_x + 2,
|
$height - $marge_y + 2, $Couleur['Noir']);
|
|
// Dessin des portions
|
$start = 0;
|
$array_col = array();
|
$color_id = 0;
|
for($v=0;$v<count($value);$v++) {
|
if($color_id==count($ColorHex['Red'])) {
|
$color_id = 0;
|
} else {
|
$color_id++;
|
};
|
|
$array_col[] = $color_id;
|
|
$end = round($start + (($value[$v] * 360) / 100));
|
imagefilledarc($graf, $width / 2, $height / 2, $width - $marge_x,
|
$height - $marge_y, $start, $end, $Couleur_Portion[$color_id],
|
'IMG_ARC_NOFILL IMG_ARC_EDGED');
|
$start = $end;
|
}
|
|
header('Content-Type: image/png');
|
|
// Si on choisi d'afficher la legende
|
if($legend) {
|
// Si les clefs ne sont pas defini
|
if(!$key) {
|
echo
|
'<strong>Erreur:</strong> Vous ne pouvez pas afficher la legende sans' .
|
' indiquer les clefs de valeur.';
|
return false;
|
} else {
|
// Si le nombre de clef ne correspond pas au nombre de valeur
|
if(count($key)!=count($value)) {
|
echo
|
'<strong>Erreur:</strong> Le nombre de clefs est different du nombre de valeur';
|
return false;
|
};
|
};
|
|
// Creation de la ressource
|
$legend = imagecreatetruecolor($width_legend, $height);
|
|
// Definition des couleurs
|
$LegCouleur['Noir'] = imagecolorallocate($legend, 0x00, 0x00, 0x00);
|
$LegCouleur['Blanc'] = imagecolorallocate($legend, 0xFF, 0xFF, 0xFF);
|
$LegCouleur_Portion = array();
|
for($l=0;$l<count($ColorHex['Red']);$l++) {
|
$LegCouleur_Portion[$l] = imagecolorallocate($legend, $ColorHex[
|
'Red'][$l], $ColorHex['Green'][$l], $ColorHex['Blue'][$l]);
|
}
|
|
// Couleur du fond
|
imagefilledrectangle($legend, 0, 0, $width_legend, $height, $LegCouleur[
|
'Blanc']);
|
|
// Place une marge en haut
|
$yActual = $marge_y;
|
|
// Si on a un titre
|
if($title) {
|
// Taille maxi du titre
|
$FontSize = 14;
|
$GoodSize = false;
|
|
// Tant que le titre ne rentre pas
|
while(!$GoodSize) {
|
// Calcul de la largeur du titre
|
$TitleBox = imagettfbbox($FontSize, 0, $Font['HypatiaSansPro'],
|
$title);
|
$TitleWidth = $TitleBox[0] + $TitleBox[2];
|
$TitleHeight = $TitleBox[1] + $TitleBox[3];
|
|
// Si le titre rentre dans la boite
|
if($TitleWidth<=($width_legend - 20)) {
|
$GoodSize = true;
|
} else {
|
// Sinon on reduit la taille de la police
|
$FontSize--;
|
};
|
}
|
|
// Centrage du titre
|
$xActual = ($width_legend - $TitleWidth) / 2;
|
imagettftext($legend, $FontSize, 0, $xActual, $yActual, $LegCouleur[
|
'Noir'], $Font['HypatiaSansPro'], $title);
|
|
// Saut de ligne sous le titre
|
$yActual += 20;
|
};
|
|
$LegBloc_height = 20;
|
$LegBloc_saut = 10;
|
$Good_LegBlocHeight = false;
|
|
$max_height = $height - $yActual - $marge_y;
|
while(!$Good_LegBlocHeight) {
|
$Total_Height = ($LegBloc_height + $LegBloc_saut) * count($key);
|
if($Total_Height>$max_height) {
|
$LegBloc_height--;
|
$LegBloc_saut--;
|
} else {
|
$Good_LegBlocHeight = true;
|
};
|
}
|
|
// Dessin et texte des legendes
|
for($k=0;$k<count($key);$k++) {
|
imagefilledrectangle($legend, 20, $yActual, 50, $yActual +
|
$LegBloc_height, $LegCouleur_Portion[$array_col[$k]]);
|
imagerectangle($legend, 20, $yActual, 50, $yActual + $LegBloc_height
|
, $LegCouleur['Noir']);
|
|
if($legendVal) {
|
$legend_valeur = $key[$k].' ('.round($value[$k], 2).'%)';
|
} else {
|
$legend_valeur = $key[$k];
|
};
|
|
$Legend_FontSize = 10;
|
$Legend_GoodSize = false;
|
|
// Tant que la legende ne rentre pas
|
while(!$Legend_GoodSize) {
|
// Calcul de la largeur du titre
|
$LegendBox = imagettfbbox($Legend_FontSize, 0, $Font['Verdana'],
|
$legend_valeur);
|
$LegendWidth = $LegendBox[0] + $LegendBox[2];
|
$LegendHeight = $LegendBox[1] + $LegendBox[3];
|
|
// Si le titre rentre dans la boite
|
if($LegendWidth<=($width_legend - 60)) {
|
$Legend_GoodSize = true;
|
} else {
|
// Sinon on reduit la taille de la police
|
$Legend_FontSize--;
|
};
|
}
|
|
imagettftext($legend, $Legend_FontSize, 0, 60, $yActual +
|
$LegBloc_height, $LegCouleur['Noir'], $Font['Verdana'], $legend_valeur);
|
|
$yActual += $LegBloc_height + $LegBloc_saut;
|
}
|
|
// Creation de l'image Graphique + Legende
|
$GrafTotal = imagecreatetruecolor($width + $width_legend, $height);
|
// Copie de l'image Graphique temporaire
|
imagecopyresized($GrafTotal, $graf, 0, 0, 0, 0, $width, $height, $width
|
, $height);
|
// Libération de la mémoire
|
imagedestroy($graf);
|
// Copie de l'image Legende temporaire
|
imagecopyresized($GrafTotal, $legend, $width, 0, 0, 0, $width_legend,
|
$height, $width_legend, $height);
|
// Libération de la mémoire
|
imagedestroy($legend);
|
|
// Envoi de l'image au navigateur
|
imagepng($GrafTotal);
|
// Libération de la mémoire
|
imagedestroy($GrafTotal);
|
} else {
|
// Envoi de l'image au navigateur
|
imagepng($graf);
|
// Libération de la mémoire
|
imagedestroy($graf);
|
};
|
}
|
|
$valeur = array(41, 174, 5410, 110, 547, 20, 654, 564, 864, 15);
|
$key = array('Valeur de clef 1', 'Texte long 2', 'Val 3', 'Val 4', 'Val 5',
|
'Val 6', 'Val 7','Val 1', 'Val 2', 'Val 3');
|
|
Camembert($valeur, true, true, true, 'Mon graf !', $key);
|
?>
|
|
|
Invité
30 Aout 2010 à 23:28Merci pour cette page très utile ! Juste une suggestion : depuis quelques temps, imagefilledarc ne fonctionnait plus du tout, et je me retrouvais avec un camembert complètement noir. J'ai résolu le problème en remplaçant
'IMG_ARC_NOFILL IMG_ARC_EDGED'
par
IMG_ARC_PIE J'espère que ça pourra être utile à d'autres qui pourraient avoir le même problème.