'3C5A69', self::SLICE_COLOR_KEY . '2' => '679BB5', self::SLICE_COLOR_KEY . '3' => '695A3C', self::SLICE_COLOR_KEY . '4' => 'B58E67', self::SLICE_COLOR_KEY . '5' => '8AA68A', self::SLICE_COLOR_KEY . '6' => 'A4D2A6', ); } protected function initPieGraph($showLegend) { $this->truncateSmallValues(); $this->initpData(); $this->initpImage(); if ($this->height > $this->width) { $radius = ($this->width / 2) - self::RADIUS_MARGIN; } else { $radius = ($this->height / 2) - self::RADIUS_MARGIN; } $this->pieChart = new Pie($this->pImage, $this->pData); $numberOfSlices = count($this->abscissaSeries); $numberOfAvailableColors = count($this->colors); for ($i = 0; $i < $numberOfSlices; $i++) { $this->pieChart->setSliceColor($i, $this->colors[self::SLICE_COLOR_KEY . (($i % $numberOfAvailableColors) + 1)]); } // max abscissa label width is used to set the pie right margin list($abscissaMaxWidth, $abscissaMaxHeight) = $this->getMaximumTextWidthHeight($this->abscissaSeries); $this->xPosition = $this->width - $radius - $abscissaMaxWidth - self::PIE_RIGHT_MARGIN; $this->yPosition = $this->height / 2; if ($showLegend) { $this->pieChart->drawPieLegend(15, 40, array("Alpha" => 20)); } $this->pieConfig = array( 'Radius' => $radius, 'DrawLabels' => true, 'DataGapAngle' => self::SECTOR_GAP, 'DataGapRadius' => self::SECTOR_GAP, ); } /** * this method logic is close to Piwik's core filter_truncate. * it uses a threshold to determine if an abscissa value should be drawn on the PIE * discarded abscissa values are summed in the 'other' abscissa value * * if this process is not perform, CpChart will draw pie slices that are too small to see */ private function truncateSmallValues() { $metricColumns = array_keys($this->ordinateSeries); $metricColumn = $metricColumns[0]; $ordinateValuesSum = 0; foreach ($this->ordinateSeries[$metricColumn] as $ordinateValue) { $ordinateValuesSum += $ordinateValue; } $truncatedOrdinateSeries[$metricColumn] = array(); $truncatedAbscissaSeries = array(); $smallValuesSum = 0; $ordinateValuesCount = count($this->ordinateSeries[$metricColumn]); for ($i = 0; $i < $ordinateValuesCount - 1; $i++) { $ordinateValue = $this->ordinateSeries[$metricColumn][$i]; if ($ordinateValue / $ordinateValuesSum > 0.01) { $truncatedOrdinateSeries[$metricColumn][] = $ordinateValue; $truncatedAbscissaSeries[] = $this->abscissaSeries[$i]; } else { $smallValuesSum += $ordinateValue; } } $smallValuesSum += $this->ordinateSeries[$metricColumn][$ordinateValuesCount - 1]; if (($smallValuesSum / $ordinateValuesSum) > 0.01) { $truncatedOrdinateSeries[$metricColumn][] = $smallValuesSum; $truncatedAbscissaSeries[] = end($this->abscissaSeries); } $this->ordinateSeries = $truncatedOrdinateSeries; $this->abscissaSeries = $truncatedAbscissaSeries; } }