Ein SVG Kreisdiagramm mit PHP Dynamisch erzeugen
PHP
"Hypertext Preprocessor“ Skriptsprache
SVG eignet sich hervorragend für Diagramme und da diese im Web z. B. bei Umfragen häfig aktualisiert werden müssen. In meinen Beispiel werden die Werte in ein HTML-Formular eingeben und von einem PHP-Script ein SVG-Dokument erzeugt, welches das Diagramm enthät.
Der Beispielquellcode index.html
Normales HTML-Formular.
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/xhtml1-strict.dtd">
<head>
<title>SVG Diagramm</title><
style type="text/css">
/* <![CDATA[ */
form {background:#dee; padding:10px; border:1px solid #000;
margin:0 auto; width: 700px;}
form fieldset {width:280px; display:block; border:1px solid #fff;
padding:5px; font-family:verdana, sans-serif;
margin-bottom:0.5em; line-height:1.5em;}
form fieldset#Wert { width: 350px;}
form fieldset#config { width: 350px;}
form fieldset#Name {float: left;}
form fieldset#Farbe {background: url(pinsel.png) no-repeat left center;
float: left;}
form legend {font-family:georgia, sans-serif; font-size:1.1em;
font-weight:bold; border:3px solid #fff;
margin-bottom:5px; padding:3px; background:#fff url(bg.png)
repeat-x center left;}
form label {clear:left; display:block; float:left; width:90px;
text-align:right; padding-right:10px; color:#888;
margin-bottom:0.5em;}
form fieldset#Wert label {width:150px;}
form fieldset#config label {width:150px;}
form input {border:1px solid #fff; background:#fff url(bg.png)
repeat-x top left; padding-left:0.7em; margin-bottom:0.6em;}
form #button1, form #button2 {color:#c00; padding-right:0.5em;
cursor:pointer; width:100px;
margin-left:8px;}
form #button1:hover, form #button2:hover,input:hover
{background-position:center left; color:#000;}
/* ]]> */
</style>
</head>
<body>
<form action="diagramm.php" method="post">
<legend>
SVG Diagramm
</legend>
<fieldset id="Name">
<legend>
Bezeichnung
</legend>
<label for="name[]">1 Name:</label>
<input name="name[]" type="text" />
<br />
<label for="name[]">2 Name:</label>
<input name="name[]" type="text" />
<br />
<label for="name[]">3 Name:</label>
<input name="name[]" type="text" />
<br />
<label for="name[]">4 Name:</label>
<input name="name[]" type="text" />
<br />
<label for="name[]">5 Name:</label>
<input name="name[]" type="text" />
<br />
<label for="name[]">6 Name:</label><
input name="name[]" type="text" />
<br />
<p>
wird als Legende angezeigt
</p>
</fieldset>
<fieldset id="Wert">
<legend>
Wert
</legend>
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<label for="wert[]"> hat den Wert:</label>
<input name="wert[]" type="text" />
<br />
<p>
wird ebenfalls in der Legende angezeigt
</p>
</fieldset>
<fieldset id="Farbe">
<legend>
Farbe
</legend>
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<label for="farbe[]"> </label>
<input type="text" name="farbe[]" value="#" />
<br />
<p>
Farbe als Hex-Tripel-Wert
</p>
</fieldset>
<fieldset id="config">
<legend>
Einstellungen
</legend>
<label for="cx">Mittelpunkt X:</label>
<input type="text" name="cy" value="100" />
<br />
<label for="cy">Mittelpunkt Y:</label>
<input type="text" name="cx" value="100" />
<br />
<label for="cr">Radius:</label>
<input type="text" name="cr" value="90" />
</fieldset>
<p>
<input id="button1" type="submit" value="erstellen" />
<input id="button2" type="reset" value="zurücksetzen" />
</p>
</form>
</body>
Der Beispielquellcode diagramm.php
Für die Kreissegmente verwende das Element
path
dessen Attribute werde mit Trigeometrischenfunktion errechnet. Die Eingaben aus dem Forumluar sin in Arrays gespeichert. Für die Legende gebe ich einfach den Namen und den Wert der einzelen Kreissektoren mit dem Element
text
in einer Schleife aus.
<?php
/*Abgeleitet von Mark Lubkowitz Beispielcode aus
Galileo Computing : Buch : Webseiten programmieren und gestalten
http://www.galileocomputing.de/katalog/buecher/titel/gp/titelID-859
*/
/*Variablen mit den Werten aus dem Formular defenieren */
$cx = $_POST['cx'];
$cy = $_POST['cy'];
$cr = $_POST['cr'];
$werte = $_POST['wert'];
$namen = $_POST['name'];
$farben = $_POST['farbe'];
$werte_summe = 0;
for($i=0; $i<count($werte); $i++)
{
$werte_summe += $werte[$i];
}
/*Ausgabe des Kopfes des SVG Dokument */
header('Content-Type: image/svg+xml');
echo "<?xml version=\"1.0\"?>\n";
echo "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"
\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n";
echo "<svg xmlns=\"http://www.w3.org/2000/svg\">\n";
$winkel_start = 270;
$winkel_end = 270;
/*Berechnung der Kreissektoren durch
Trigeometrischefunktionen und deren Ausgabe*/
for($i=0; $i<count($werte); $i++)
{
$winkel_start = $winkel_end;
$winkel_part = $werte[$i] / $werte_summe * 360;
$winkel_end = $winkel_start + $winkel_part;
$psx = round(cos(deg2rad($winkel_start)) * $cr + $cx);
$psy = round(sin(deg2rad($winkel_start)) * $cr + $cy);
$pex = round(cos(deg2rad($winkel_end)) * $cr + $cx);
$pey = round(sin(deg2rad($winkel_end)) * $cr + $cy);
echo " <path d=\"M $cx,$cy L $psx,$psy A $cr,$cr 0 0,
1 $pex,$pey Z\" fill=\"$farben[$i]\" stroke=\"black\"
stroke-width=\"2\"/>\n";
}
/*Ausgabe der Legende*/
$desc_x = $cx + $cr + 50;
$desc_y = 40;
echo " <text x=\"$desc_x\" y=\"$desc_y\" font-size=\"20\"
fill=\"#000000\">Legende:</text>\n";
$desc_y += 24;
echo " <text x=\"$desc_x+10\" y=\"$desc_y\" font-size=\"12\"
fill=\"#000000\">Bezeichnung - Wert</text>\n";
$desc_y += 16;
for($i=0; $i<count($namen); $i++)
{
echo " <text x=\"$desc_x\" y=\"$desc_y\" font-size=\"14\"
fill=\"$farben[$i]\">$namen[$i] - $werte[$i]</text>\n";
$desc_y += 18;
}
echo '</svg>';
?>
Das Ganze in Aktion.