/** * creates bar chart of given data * @param array $data data input * @param int $width graphic width * @param int $height graphic height * @param int $barPadding spacing between bars * @param array $dcolors colors of data fields * @param int $zLine a "zero" line * @param array $legende caption */ public function barChart($data, $width, $height, $barPadding, $dsColors, $zLine = null, $legende = null) { $this->data = $data; $this->numSets = count($data); $this->width = $width; $this->height = $height; $this->barPadding = $barPadding; $this->colors = $dsColors; $this->dsLen = count($this->data[0]); if (isset($legende)) { $this->legende = $legende; } else { unset($this->legende); } if (isset($zLine)) { $this->zLine = $zLine; } else { unset($this->zLine); } // count data to find out width of single bar $num = 0; // number of bars $maxY = 0; // highest value $minY = 0; // lowest value foreach ($this->data as $dp) { $num += count($dp); if (count($dp) != $this->dsLen) { echo "Datasets sind verschieden lang!!"; // Datasets are of different length pre($dp); } // search for maximum value $max = max($dp); $min = min($dp); if ($max > $maxY) { $maxY = $max; } if ($min < $minY) { $minY = $min; } } $pl = abs($minY); $h = $maxY + $pl; // mix up Arrays to group datasets if ($this->numSets > 1) { $i = 0; while ($i != $this->dsLen) { foreach ($this->data as $dp) { $dsAll[] = $dp[$i]; } $i++; } } else { $dsAll = $this->data[0]; } // numSets to gain double padding between groups $groupPadding = 4 * $this->barPadding; $padAll = $num * $this->barPadding + ($this->numSets - 1) * $groupPadding; $wBar = ($this->width - $padAll) / $num; // Init Image handle parent::Init($this->width + 1, $this->height, "bars"); parent::imgFill("white", 1, 1); $i = 0; // number overall $b = 0; // to arrange groups $d = 0; // to pick color $offs = 0; // offset is needed for spacing between groups $yz = $this->height - ($this->zLine + $pl) * ($this->height / $h); // Zero Line foreach ($dsAll as $p) { if ($b == $this->dsLen && $this->numSets != 1) { // next group ... $offs += $groupPadding; // ... -> increase offset $b = 0; } if ($d == $this->numSets) { $d = 0; } $x = round($i * $wBar + $i * $this->barPadding + $offs); $y = round($p * ($this->height / $h)) - $this->zLine; parent::imgRect($x, $yz, $wBar, -$y, $this->colors[$d], "filled"); $i++; $b++; $d++; } if (isset($this->zLine)) { $y = $this->height - ($this->zLine + $pl) * ($this->height / $h); parent::imgLine(0, $y, $this->width, $y, "black"); } if (isset($this->legende)) { $xw = 20; $yh = imagefontheight(2) + 2; parent::imgLine(0, $this->height - 1, $this->width, $this->height - 1, "black"); parent::Init($this->width + 1, $yh, "legendeY"); parent::imgFill("white", 1, 1); $i = 1; foreach ($this->legende as $txt) { $center = $this->width / $this->numSets; $fw = imagefontwidth(2) * strlen($txt); $x = $center * $i - $fw / 2 - $center / 2; parent::imgString(2, $x, 1, $txt, "black"); $lx = $center * $i; parent::imgLine($lx, 0, $lx, 5, "black"); $i++; } $fh = imagefontheight(2); if ($this->height > $fh * 2) { parent::Init($xw, $this->height + $yh, "legendeX"); parent::imgFill("white", 1, 1); parent::imgLine($xw - 1, 0, $xw - 1, $this->height - 1, "black"); parent::imgString(2, 2, -3, $maxY, "black"); parent::imgString(2, 2, $this->height - $fh, 0, "black"); } else { $xw = 0; } parent::Init($this->width + 1 + $xw, $this->height + $yh, "container"); parent::imgFill("white", 1, 1); @parent::mergeHandles("container", "legendeX", 0, 0); parent::mergeHandles("container", "bars", $xw, 0); parent::mergeHandles("container", "legendeY", $xw, $this->height); parent::switchHandle("container"); } }