Initial xentral_oss_20.3.c9ffacf

This commit is contained in:
Alex
2021-05-21 08:49:41 +02:00
parent 5406e4a551
commit 34e5ac43d9
18884 changed files with 2109867 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace Xentral\Widgets\Chart;
/**
* Spezielles Dataset für Balkendiagramme
*
* Besonderheiten:
* * Balkenhintergrund und -rahmen haben keine Transparenz
*/
class BarDataset extends Dataset
{
/** @var array $defaultAlphaValues Transparenz-Werte */
protected static $defaultAlphaValues = [
'borderColor' => 1.0,
'backgroundColor' => 1.0,
'hoverBorderColor' => 1.0,
];
}
+277
View File
@@ -0,0 +1,277 @@
<?php
namespace Xentral\Widgets\Chart;
use InvalidArgumentException;
class Chart
{
/** @var array $validTypes */
private static $validTypes = [
'line',
'bar',
'radar',
'pie',
'doughnut',
'polarArea',
//'bubble',
//'scatter',
];
/** @var array $defaultColors In RGB */
private static $defaultColors = [
[162, 197, 90],
[69, 185, 211],
[246, 158, 6],
[14, 131, 148],
];
/** @var array $defaultOptions */
private static $defaultOptions = [
'responsive' => true,
'responsiveAnimationDuration' => 0,
'maintainAspectRatio' => true,
'tooltips' => [
'enabled' => true,
'mode' => 'nearest',
'backgroundColor' => 'rgba(0, 0, 0, 0.5)',
],
'legend' => [
'display' => true,
],
'animation' => [
'duration' => 1000,
'animateRotate' => true, // Pie + Doughnut
],
'scales' => [
'xAxes' => [
[
'display' => true,
],
],
'yAxes' => [
[
'display' => true,
'ticks' => [
'beginAtZero' => true,
],
],
],
],
];
protected $type;
protected $labels;
protected $datasets;
protected $options;
/** @var int $currentColor Zähler für die letzte Default-Farbe die verwendet wurde */
private $currentColor;
/**
* @param string $type Chart-Typ
* @param array $labels
* @param array|Dataset[] $datasets
* @param array $options chart.js Optionen
*/
public function __construct($type = 'line', $labels = [], array $datasets = [], array $options = [])
{
if (!in_array($type, self::$validTypes, true)) {
throw new InvalidArgumentException(sprintf('Chart type "%s" is not valid.', $type));
}
// Ungültige Werte in leeres Array wandeln
if (!is_array($labels)) {
$labels = [];
}
$this->type = $type;
$this->labels = $labels;
$this->datasets = $datasets;
$this->options = array_replace_recursive(self::$defaultOptions, $options);
if ($type === 'line') {
$this->options['tooltips']['mode'] = 'index';
}
if ($type === 'doughnut' || $type === 'pie') {
$this->options['scales']['xAxes'][0]['display'] = false;
$this->options['scales']['yAxes'][0]['display'] = false;
}
}
/**
* @param array $labels
*
* @return void
*/
public function addLabels($labels)
{
// Ungültige Werte in leeres Array wandeln
if (!is_array($labels)) {
$labels = [];
}
foreach ($labels as $label) {
$this->addLabel($label);
}
}
/**
* @param string $label
*
* @return void
*/
public function addLabel($label)
{
$this->labels[] = (string)$label;
}
/**
* @param Dataset $dataset
*
* @return void
*/
public function addDataset(Dataset $dataset)
{
$this->datasets[] = $dataset;
}
/**
* Wie setYAxis(), nur dass das Dataset zusätzlich noch zum Chart hinzugefügt wird
*
* @see setYAxis()
*
* @param Dataset $dataset
* @param string $position
* @param string $type
*
* @return void
*/
public function addDatasetAsYAxis(Dataset $dataset, $position = 'left', $type = 'linear')
{
$this->setYAxis($dataset, $position, $type);
$this->addDataset($dataset);
}
/**
* Übergebenes Dataset für die Anzeige der Y-Achse verwenden
*
* * Mehrere Y-Achsen sind möglich
* * Dataset wird aber nicht zum Chart hinzugefügt; muss über addDataset() passieren
*
* @param Dataset $dataset
* @param string $position
* @param string $type
*
* @return void
*/
public function setYAxis(Dataset $dataset, $position = 'left', $type = 'linear')
{
// Falls vorher noch kein Dataset als y-Achse definiert wurde, Default-y-Achsen-Config löschen.
// (Ansonsten wird eine y-Achse zu viel angezeigt)
$hasMultipleAxesConfig = array_key_exists('id', $this->options['scales']['yAxes'][0]);
if (!$hasMultipleAxesConfig) {
unset($this->options['scales']['yAxes']);
}
$id = $dataset->generateYAxisId();
$this->options['scales']['yAxes'][] = [
'id' => $id,
'display' => true,
'type' => $type,
'position' => $position,
'ticks' => [
'beginAtZero' => true,
],
];
}
/**
* @return void
*/
public function accumulateData()
{
foreach ($this->datasets as $dataset) {
$dataset->accumulateData();
}
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @return array
*/
public function getData()
{
foreach ($this->datasets as $dataset) {
/** @var Dataset $dataset */
// Default-Farben durchiterieren, wenn noch keine Farbe gesetzt
if (!$dataset->hasColorAssigned()) {
$color = $this->getNextDefaultColor();
$dataset->setColorByRgb(...$color);
}
}
return [
'labels' => $this->labels,
'datasets' => $this->datasets,
];
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @return string
*/
public function toJson()
{
return json_encode([
'type' => $this->getType(),
'data' => $this->getData(),
'options' => $this->getOptions(),
]);
}
/**
* Liefert bei jedem Aufruf die nächste Farbe aus den Standard-Farben
*
* @return array Array mit drei Farbwerten [R, G, B]
*/
private function getNextDefaultColor()
{
// Bei jedem Aufruf Index hochzählen
$this->currentColor = $this->currentColor === null ? 0 : $this->currentColor + 1;
// Wieder vorne anfangen wenn letzte Farbe ausgeliefert wurde
if ($this->currentColor >= count(self::$defaultColors)) {
$this->currentColor = 0;
}
return self::$defaultColors[$this->currentColor];
}
/**
* Beim Klonen die Dataset-Objekte einzeln klonen
*
* Ansonsten beinhaltet das geklonte Chart-Objekt die Referenzen zum Ursprungsobjekt!
*
* @return void
*/
public function __clone()
{
foreach ($this->datasets as $key => $dataset) {
$this->datasets[$key] = clone $dataset;
}
}
}
+225
View File
@@ -0,0 +1,225 @@
<?php
namespace Xentral\Widgets\Chart;
use InvalidArgumentException;
use JsonSerializable;
class Color implements JsonSerializable
{
private $red;
private $green;
private $blue;
private $alpha;
/**
* @param int $red Farbwert von 0 bis 255
* @param int $green Farbwert von 0 bis 255
* @param int $blue Farbwert von 0 bis 255
* @param float $alpha Transparenzwert von 0 bis 1
*/
public function __construct($red = 0, $green = 0, $blue = 0, $alpha = 0.1)
{
$this->red = $this->ensureColorValue($red);
$this->green = $this->ensureColorValue($green);
$this->blue = $this->ensureColorValue($blue);
$this->setAlpha($alpha);
}
/**
* @param string $hexColor Beispiel: "#112233"
*
* @return self
*/
public static function createFromHex($hexColor)
{
$hexColor = str_replace('#', '', $hexColor);
if (strlen($hexColor) !== 6) {
throw new InvalidArgumentException('Only full length hex values are supported.');
}
$parts = str_split($hexColor, 2);
$red = hexdec($parts[0]);
$green = hexdec($parts[1]);
$blue = hexdec($parts[2]);
return new self($red, $green, $blue, 1);
}
/**
* @param string $cssRgba Beispiel: rgba(255, 128, 0, 0.5)
*
* @return self
*/
public static function createFromCssRgba($cssRgba)
{
$cssRgba = str_replace(' ', '', $cssRgba);
preg_match('/^rgba\((\d+),(\d+),(\d+),([\d\.]+)\);?/i', $cssRgba, $colors);
return new self((int)$colors[1], (int)$colors[2], (int)$colors[3], (float)$colors[4]);
}
/**
* @param string $cssRgb Beispiel: "rgb(255, 128, 0)"
*
* @return self
*/
public static function createFromCssRgb($cssRgb)
{
$cssRgb = str_replace(' ', '', $cssRgb);
preg_match('/^rgb\((\d+),(\d+),(\d+)\);?/i', $cssRgb, $colors);
return new self((int)$colors[1], (int)$colors[2], (int)$colors[3], 1.0);
}
/**
* @param int $value
*
* @return int
*/
private function ensureColorValue($value)
{
$value = (int)$value;
if ($value < 0) {
$value = 0;
}
if ($value > 255) {
$value = 255;
}
return $value;
}
/**
* @param float $alpha Wert zwischen 0 und 1
*
* @return void
*/
public function setAlpha($alpha)
{
$alpha = (float)$alpha;
if ($alpha < 0.0) {
$alpha = 0.0;
}
if ($alpha > 1.0) {
$alpha = 1.0;
}
$this->alpha = $alpha;
}
/**
* Farbwerte per Zufall variieren
*
* @param int $difference
*
* @return void
*/
public function makeVariant($difference)
{
$difference = (int)$difference;
$redVariant = $this->red + mt_rand($difference * -1, $difference);
$this->red = $this->ensureColorValue($redVariant);
$greenVariant = $this->green + mt_rand($difference * -1, $difference);
$this->green = $this->ensureColorValue($greenVariant);
$blueVariant = $this->blue + mt_rand($difference * -1, $difference);
$this->blue = $this->ensureColorValue($blueVariant);
}
/**
* Farbe heller machen; verändert nicht die Transparenz
*
* @param float $percent
*
* @return void
*/
public function makeLighter($percent = 10.0)
{
$percent = (float)$percent;
$difference = (int)($percent * 2.55 / 2);
$this->red = $this->ensureColorValue($this->red + $difference);
$this->blue = $this->ensureColorValue($this->blue + $difference);
$this->green = $this->ensureColorValue($this->green + $difference);
}
/**
* Farbe dunkler machen; verändert nicht die Transparenz
*
* @param float $percent
*
* @return void
*/
public function makeDarker($percent = 10.0)
{
$percent = (float)$percent;
$difference = (int)($percent * 2.55 / 2);
$this->red = $this->ensureColorValue($this->red - $difference);
$this->blue = $this->ensureColorValue($this->blue - $difference);
$this->green = $this->ensureColorValue($this->green - $difference);
}
/**
* Ausgabe in CSS rgba() Notation
*
* @return string
*/
public function toCssRgba()
{
return sprintf(
'rgba(%s, %s, %s, %s)',
$this->red,
$this->green,
$this->blue,
number_format($this->alpha, 3, '.', '')
);
}
/**
* Ausgabe in CSS rgb() Notation; Transparenz geht verloren
*
* @return string
*/
public function toCssRgb()
{
return sprintf(
'rgb(%s, %s, %s)',
$this->red,
$this->green,
$this->blue
);
}
/**
* Ausgabe als Hex-Farbwert; Transparenz geht verloren
*
* @return string
*/
public function toHex()
{
return sprintf(
'#%s%s%s',
str_pad(dechex($this->red), 2, '0', STR_PAD_LEFT),
str_pad(dechex($this->green), 2, '0', STR_PAD_LEFT),
str_pad(dechex($this->blue), 2, '0', STR_PAD_LEFT)
);
}
/**
* @return string
*/
public function jsonSerialize()
{
return $this->__toString();
}
/**
* @return string
*/
public function __toString()
{
return $this->toCssRgba();
}
}
+281
View File
@@ -0,0 +1,281 @@
<?php
namespace Xentral\Widgets\Chart;
use InvalidArgumentException;
use JsonSerializable;
class Dataset implements JsonSerializable
{
const LINE_STYLE_SOLID = 'solid';
const LINE_STYLE_DASHED = 'dashed';
const LINE_STYLE_DOTTED = 'dotted';
const COLOR_GREEN = 'green';
const COLOR_BLUE = 'blue';
const COLOR_ORANGE = 'orange';
const COLOR_DARKBLUE = 'darkblue';
/** @var array $validLineStyles */
protected static $validLineStyles = [
self::LINE_STYLE_SOLID,
self::LINE_STYLE_DOTTED,
self::LINE_STYLE_DASHED,
];
/** @var array $colorMap */
protected static $colorMap = [
self::COLOR_GREEN => [162, 197, 90],
self::COLOR_BLUE => [69, 185, 211],
self::COLOR_ORANGE => [246, 158, 6],
self::COLOR_DARKBLUE => [14, 131, 148],
];
/** @var array $defaultOptions Standardwerte für Dataset-Optionen */
protected static $defaultOptions = [
'pointBorderWidth' => 1,
'pointHoverBorderWidth' => 2,
'pointRadius' => 1,
'pointHoverRadius' => 5,
'pointHitRadius' => 15,
'lineTension' => 0.2,
'fill' => true,
'borderWidth' => 3,
'borderDash' => [],
'borderCapStyle' => 'butt',
'borderColor' => 'rgba(0, 0, 0, 0.1)',
'backgroundColor' => 'rgba(0, 0, 0, 0.1)',
'pointBackgroundColor' => 'rgba(0, 0, 0, 0.1)',
];
/** @var array $defaultAlphaValues Transparenz-Werte */
protected static $defaultAlphaValues = [
'borderColor' => 1.0,
'backgroundColor' => 0.1,
'pointBackgroundColor' => 1.0,
];
protected $data;
protected $label;
protected $options;
/** @var bool $isDataAccumulated Gibt an ob Daten bereits kumuliert wurden */
protected $isDataAccumulated = false;
/** @var bool $hasColorSet Gibt an ob bereits eine Farbe manuell gesetzt wurde */
protected $hasColorAssigned = false;
/**
* @param string $label
* @param array $data
* @param array $options
*/
public function __construct($label, $data, array $options = [])
{
// Ungültige Werte in leeres Array wandeln
if (!is_array($data)) {
$data = [];
}
$this->data = $data;
$this->label = $label;
$this->options = array_replace(self::$defaultOptions, $options);
$defaultColor = new Color(0, 0, 0, 0.1);
if (!is_object($this->options['borderColor'])) {
$this->options['borderColor'] = $defaultColor;
}
if (!is_object($this->options['backgroundColor'])) {
$this->options['backgroundColor'] = $defaultColor;
}
if (!is_object($this->options['pointBackgroundColor'])) {
$this->options['pointBackgroundColor'] = $defaultColor;
}
}
/**
* @return int
*/
public function getDataCount()
{
return count($this->data);
}
/**
* @return bool Wurde bereits eine Farbe gesetzt
*/
public function hasColorAssigned()
{
return $this->hasColorAssigned;
}
/**
* @return void
*/
public function accumulateData()
{
if ($this->isDataAccumulated === true) {
return;
}
$sum = 0;
foreach ($this->data as $key => $value) {
$sum += (float)$value;
$this->data[$key] = $sum;
}
$this->isDataAccumulated = true;
}
/**
* @param string $lineStyle
*
* @return void
*/
public function setLineStyle($lineStyle)
{
if (!in_array($lineStyle, self::$validLineStyles, true)) {
throw new InvalidArgumentException(sprintf(
'Line style "%s" is not valid.', $lineStyle
));
}
if ($lineStyle === self::LINE_STYLE_DOTTED) {
$this->options['borderDash'] = [1, 15];
$this->options['borderCapStyle'] = 'round';
}
if ($lineStyle === self::LINE_STYLE_DASHED) {
$this->options['borderDash'] = [15, 10];
$this->options['borderCapStyle'] = 'butt';
}
if ($lineStyle === self::LINE_STYLE_SOLID) {
$this->options['borderDash'] = [];
$this->options['borderCapStyle'] = 'butt';
}
}
/**
* @param Color $color
*
* @return void
*/
public function setColor(Color $color)
{
$borderColor = clone $color;
$backgroundColor = clone $color;
$pointBackgroundColor = clone $color;
$borderColor->setAlpha($this->getDefaultAlphaValue('borderColor'));
$backgroundColor->setAlpha($this->getDefaultAlphaValue('backgroundColor'));
$pointBackgroundColor->setAlpha($this->getDefaultAlphaValue('pointBackgroundColor'));
$this->options['borderColor'] = $borderColor;
$this->options['backgroundColor'] = $backgroundColor;
$this->options['pointBackgroundColor'] = $pointBackgroundColor;
$this->hasColorAssigned = true;
}
/**
* @param int $red
* @param int $green
* @param int $blue
*
* @return void
*/
public function setColorByRgb($red, $green, $blue)
{
$this->setColor(new Color($red, $green, $blue, 1.0));
}
/**
* @param string $hexColor
*
* @return void
*/
public function setColorByHex($hexColor)
{
$hexColor = str_replace('#', '', $hexColor);
if (strlen($hexColor) !== 6) {
throw new InvalidArgumentException('Only full length hex values are supported.');
}
$parts = str_split($hexColor, 2);
$red = hexdec($parts[0]);
$green = hexdec($parts[1]);
$blue = hexdec($parts[2]);
$this->setColorByRgb($red, $green, $blue);
}
/**
* @param string $colorName
*
* @return void
*/
public function setColorByName($colorName)
{
if (!isset(self::$colorMap[$colorName])) {
throw new InvalidArgumentException(sprintf(
'Color name "%s" is not valid.', $colorName
));
}
$rgb = self::$colorMap[$colorName];
$this->setColorByRgb(...$rgb);
}
/**
* Zufällige ID generieren; wird für Multiple Axes Config benötigt
*
* @see http://www.chartjs.org/docs/latest/axes/cartesian/#axis-id
*
* @return string
*/
public function generateYAxisId()
{
if (!isset($this->options['yAxisID'])) {
$this->options['yAxisID'] = uniqid('', false);
}
return $this->options['yAxisID'];
}
/**
* @return array
*/
public function jsonSerialize()
{
return $this->toArray();
}
/**
* @return array
*/
public function toArray()
{
$result = $this->options;
$result['data'] = $this->data;
if (!empty($this->label)) {
$result['label'] = $this->label;
}
return $result;
}
/**
* @param string $colorType
*
* @return float
*/
protected function getDefaultAlphaValue($colorType)
{
if (!isset(static::$defaultAlphaValues[$colorType])) {
return 1.0;
}
// Wichtig: static nicht self!
// Sonst hat Überschreiben von $defaultAlphaValues in abgeleiteten Klassen keine Auswirkung.
return static::$defaultAlphaValues[$colorType];
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace Xentral\Widgets\Chart;
class HtmlRenderer
{
/** @var Chart $chart */
protected $chart;
/** @var string $title */
protected $title;
/** @var int $width */
protected $width;
/** @var int $height */
protected $height;
/** @var array $attributes */
protected $attributes;
/**
* @param Chart $chart
* @param string $title
* @param int $width
* @param int $height
* @param array $attributes Zusätzliche HTML-Attribute als assoziatives Array
*/
public function __construct(Chart $chart, $title = '', $width = 400, $height = 200, array $attributes = [])
{
$this->chart = $chart;
$this->title = $title;
$this->width = (int)$width;
$this->height = (int)$height;
$this->attributes = $attributes;
}
/**
* @return string
*/
public function render()
{
return sprintf(
'<div class="chart-wrapper" %s>%s' .
' <div class="chart-content">' .
' <canvas data-graph-id="%s" width="%s" height="%s"></canvas>' .
' <script type="application/json">%s</script>' .
' </div>' .
'</div>',
$this->renderAttributes(),
$this->renderTitle(),
uniqid(null, false),
$this->width,
$this->height,
$this->chart->toJson()
);
}
/**
* @return string
*/
protected function renderAttributes()
{
$result = '';
foreach ($this->attributes as $key => $value) {
$result .= sprintf(' %s="%s"', $key, $value);
}
return trim($result);
}
/**
* @return string
*/
protected function renderTitle()
{
if (empty($this->title)) {
return '';
}
return sprintf('<div class="chart-title">%s</div>', $this->title);
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace Xentral\Widgets\Chart;
use DateInterval;
use DatePeriod;
use DateTimeInterface;
class PeriodMatcher
{
/** @var DateTimeInterface $start */
protected $start;
/** @var DateTimeInterface $end */
protected $end;
/** @var DateInterval $interval */
protected $interval;
/** @var string $format */
protected $format;
/** @var DatePeriod $range */
protected $range;
/**
* @param DateTimeInterface $start
* @param DateTimeInterface $end
* @param DateInterval $interval
* @param string $format Formate der PHP date()-Funktion
*/
public function __construct(
DateTimeInterface $start,
DateTimeInterface $end,
DateInterval $interval,
$format = 'Y.m.d'
) {
$this->start = $start;
$this->end = $end;
$this->interval = $interval;
$this->format = $format;
$this->range = new DatePeriod($start, $interval, $end);
}
/**
* @param array $data
* @param string $dateKey
* @param string $valueKey
*
* @return array
*/
public function matchData($data, $dateKey, $valueKey)
{
if ($data === null) {
$data = [];
}
$dates = array_column($data, $dateKey);
$values = array_column($data, $valueKey);
$result = [];
foreach ($this->getDates() as $date) {
$matchedKey = array_search($date, $dates, true);
$result[] = $matchedKey !== false ? (float)$values[$matchedKey] : 0.0;
}
return $result;
}
/**
* @param string $format Datumsformat überschreiben
*
* @return array
*/
public function getDates($format = null)
{
$result = [];
/** @var DateTimeInterface $date */
foreach ($this->range as $date) {
$result[] = $date->format($format !== null ? $format : $this->format);
}
return $result;
}
}
+125
View File
@@ -0,0 +1,125 @@
<?php
namespace Xentral\Widgets\Chart;
/**
* Spezielles Dataset für Pie-/Doughnut-Charts
*
* Besonderheiten:
* * Farben müssen als Array angegeben werden; pro Wert eine Farbe
* * Strichbreiten ('borderWidth') müssen als Array angegeben werden; pro Wert eine Breite
*
* http://www.chartjs.org/docs/master/charts/doughnut.html#dataset-properties
*/
class PieDataset extends Dataset
{
/** @var array $defaultAlphaValues Transparenz-Werte */
protected static $defaultAlphaValues = [
'borderColor' => 1.0,
'backgroundColor' => 1.0,
'hoverBorderColor' => 1.0,
];
/** @var int $colorPointer Merkt sich die zuletzt verwendete Default-Color */
private $colorPointer = 0;
/**
* @inheritdoc
*/
public function __construct($label, $data, array $options = [])
{
parent::__construct($label, $data, $options);
$this->options['borderWidth'] = 3;
unset($this->options['pointBackgroundColor']);
}
/**
* @param Color $color
*
* @return void
*/
public function setColor(Color $color)
{
$backgroundColor = clone $color;
$borderColor = new Color(255, 255, 255);
$hoverBorderColor = new Color(255, 255, 255);
$borderColor->setAlpha($this->getDefaultAlphaValue('borderColor'));
$backgroundColor->setAlpha($this->getDefaultAlphaValue('backgroundColor'));
$hoverBorderColor->setAlpha($this->getDefaultAlphaValue('hoverBorderColors'));
// Hintergrundfarbe als Array setzen
// Pro Datensatz Farbe etwas heller machen
$backgroundColors = [];
$dataCount = $this->getDataCount();
foreach ($this->data as $key => $value) {
$difference = $key * 75 / $dataCount;
$backgroundColorLighter = clone $backgroundColor;
$backgroundColorLighter->makeLighter($difference);
$backgroundColors[$key] = $backgroundColorLighter;
}
$this->options['borderColor'] = $borderColor;
$this->options['backgroundColor'] = $backgroundColors;
$this->options['hoverBorderColor'] = $hoverBorderColor;
$this->hasColorAssigned = true;
}
/**
* Hintergrundfarben pro Wert hinterlegen
*
* Die Anzahl der Farben sollte der Anzahl der Daten entsprechen
*
* @param array|string[] $colors Hexadecimal- oder RGB-Schreibweise
*
* @return void
*/
public function setColors(array $colors)
{
// Rahmenfarbe auf Weiß setzen
$borderColor = new Color(255, 255, 255);
$hoverBorderColor = new Color(255, 255, 255);
$borderColor->setAlpha($this->getDefaultAlphaValue('borderColor'));
$hoverBorderColor->setAlpha($this->getDefaultAlphaValue('hoverBorderColors'));
// Nur Hintergrundfarbe/Füllfarbe variieren
$backgroundColors = [];
//foreach ($colors as $color) {
foreach ($this->data as $key => $value) {
$color = $colors[$key];
if (strpos($color, '#', 0) === 0) {
$backgroundColor = Color::createFromHex($color);
} else {
$rgb = $this->getNextDefaultColor();
$backgroundColor = new Color($rgb[0], $rgb[1], $rgb[2], 1);
}
$backgroundColor->setAlpha($this->getDefaultAlphaValue('backgroundColor'));
$backgroundColors[] = $backgroundColor;
}
$this->options['borderColor'] = $borderColor;
$this->options['hoverBorderColor'] = $hoverBorderColor;
$this->options['backgroundColor'] = $backgroundColors;
$this->hasColorAssigned = true;
}
/**
* @return array RGB-Array
*/
private function getNextDefaultColor()
{
$this->colorPointer++;
if ($this->colorPointer >= count(self::$colorMap)) {
$this->colorPointer = 0;
}
$colors = array_values(self::$colorMap);
return $colors[$this->colorPointer];
}
}