/** * Overriding getOption function to pull config options from calendar array. * (Thanks google) * * @param string $o Which option to fetch * @throws InvalidConfigValue * @return mixed */ public function getOption($o) { if (is_string($o) && array_key_exists($o, $this->options['calendar'])) { return $this->options['calendar'][$o]; } else { if (is_string($o) && array_key_exists($o, $this->options)) { return $this->options[$o]; } else { $calendarOptions = $this->options['calendar']; $nonCalendarOptions = array_diff($this->options, $calendarOptions); $options = array_merge($calendarOptions, $nonCalendarOptions); throw $this->invalidConfigValue(__FUNCTION__, 'string', 'must be one of ' . Utils::arrayToPipedString(array_keys($options))); } } }
/** * Sets the value of a string option from an array of choices. * * @param string $option Option to set. * @param string $value Value of the option. * @param array $validValues Array of valid values * @return \Khill\Lavacharts\JsonConfig * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue * @throws \Khill\Lavacharts\Exceptions\InvalidOption */ protected function setStringInArrayOption($option, $value, $validValues = []) { if (Utils::nonEmptyStringInArray($value, $validValues) === false) { throw new InvalidConfigValue(static::TYPE . '->' . $option, 'string', 'Whose value is one of ' . Utils::arrayToPipedString($validValues)); } $this->options->set($option, $value); return $this; }
/** * Animation Easing * * The easing function applied to the animation. The following options are available: * 'linear' - Constant speed. * 'in' - Ease in - Start slow and speed up. * 'out' - Ease out - Start fast and slow down. * 'inAndOut' - Ease in and out - Start slow, speed up, then slow down. * * @param string $easing * * @return Chart */ public function animationEasing($easing = 'linear') { $values = array('linear', 'in', 'out', 'inAndOut'); if (in_array($easing, $values)) { $this->easing = $easing; } else { $this->error('Invalid animationEasing value, must be (string) ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Controls the curve of the lines when the line width is not zero. * * Can be one of the following: * 'none' - Straight lines without curve. * 'function' - The angles of the line will be smoothed. * * @param string $curveType * @throws InvalidConfigValue * @return LineChart */ public function curveType($curveType) { $values = array('none', 'function'); if (is_string($curveType) && in_array($curveType, $values)) { $this->addOption(array('curveType' => $curveType)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Where to place the axis titles, compared to the chart area. Supported values: * in - Draw the axis titles inside the the chart area. * out - Draw the axis titles outside the chart area. * none - Omit the axis titles. * * @param string $position * @return ColumnChart */ public function axisTitlesPosition($position) { $values = array('in', 'out', 'none'); if (is_string($position) && in_array($position, $values)) { $this->addOption(array('axisTitlesPosition' => $position)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * The method of filtering the string: * * exact - The pattern matches the string exactly. * prefix - The pattern is found at the beginning of the string. * any - The pattern is found anywhere in the string. * * @param string $position * @throws InvalidConfigValue * @return StringFilter */ public function matchType($type) { $values = array('exact', 'prefix', 'any'); if (is_string($type) && in_array($type, $values)) { $this->addOption(array(__FUNCTION__ => $type)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * If set to true, stacks the elements for all series at each domain value. * * Note: In Column, Area, and SteppedArea charts, Google Charts reverses the order * of legend items to better correspond with the stacking of the series elements * (E.g. series 0 will be the bottom-most legend item). This does not apply to Bar Charts. * * The isStacked option also supports 100% stacking, where the stacks * of elements at each domain value are rescaled to add up to 100%. * * The options for isStacked are: * * false — elements will not stack. This is the default option. * true — stacks elements for all series at each domain value. * 'percent' — stacks elements for all series at each domain value * and rescales them such that they add up to 100%, with each element's * value calculated as a percentage of 100%. * 'relative' — stacks elements for all series at each domain value * and rescales them such that they add up to 1, with each element's * value calculated as a fraction of 1. * 'absolute' — functions the same as isStacked: true. * * For 100% stacking, the calculated value for each element will appear * in the tooltip after its actual value. * * The target axis will default to tick values based on the relative * 0-1 scale as fractions of 1 for 'relative', and 0-100% for 'percent' * (Note: when using the 'percent' option, the axis/tick values are * displayed as percentages, however the actual values are the relative * 0-1 scale values. This is because the percentage axis ticks are the * result of applying a format of "#.##%" to the relative 0-1 scale values. * When using isStacked: 'percent', be sure to specify any ticks/gridlines * using the relative 0-1 scale values). You can customize the gridlines/tick * values and formatting using the appropriate hAxis/vAxis options. * * 100% stacking only supports data values of type number, and must have a baseline of zero. * * @param bool|string $isStacked * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue * @return \Khill\Lavacharts\Charts\Chart */ public function isStacked($isStacked) { $values = ['relative', 'absolute']; if (is_bool($isStacked) === true) { return $this->setBoolOption(__FUNCTION__, $isStacked); } elseif (is_string($isStacked) === true) { return $this->setStringInArrayOption(__FUNCTION__, $isStacked, $values); } else { throw new InvalidConfigValue(static::TYPE . '->' . __FUNCTION__, 'bool|string', 'Whose value is one of ' . Utils::arrayToPipedString($values)); } }
/** * Builds the ConfigOptions object. * * Passing an array of key value pairs will set the configuration for each * child object created from this parent object. * * @param mixed $child Child ConfigOption object. * @param array $config Array of options. * @throws InvalidConfigValue * @throws InvalidConfigProperty * @return mixed */ public function __construct($child, $config) { $class = new \ReflectionClass($child); $this->options = array_map(function ($prop) { return $prop->name; }, $class->getProperties(\ReflectionProperty::IS_PUBLIC)); if (is_array($config)) { foreach ($config as $option => $value) { if (in_array($option, $this->options)) { $this->{$option}($value); } else { throw new InvalidConfigProperty($child::TYPE, __FUNCTION__, $option, $this->options); } } } else { throw new InvalidConfigValue(__FUNCTION__, 'array', 'with valid keys as ' . Utils::arrayToPipedString($this->options)); } }
/** * The slider orientation. Either 'horizontal' or 'vertical'. * * @access public * @param string $orientation * @return Ui */ public function orientation($orientation) { $values = array('horizontal', 'vertical'); if (is_string($orientation) && in_array($orientation, $values)) { $this->orientation = $orientation; } else { throw new InvalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Sets a specified option for the paging buttons. The options are as follows: * both - enable prev and next buttons * prev - only prev button is enabled * next - only next button is enabled * auto - the buttons are enabled according to the current page. On the first page only next * is shown. On the last page only prev is shown. Otherwise both are enabled. * number - the number of paging buttons to show. This explicit number will override computed number from pageSize. * * @access public * @param string|int $paging * @return \Khill\Lavacharts\Charts\TableChart * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue */ public function pagingButtons($paging) { $values = ['both', 'prev', 'next', 'auto']; if (Utils::nonEmptyStringInArray($paging, $values) === false || is_int($paging) === false) { throw new InvalidConfigValue(__FUNCTION__, 'string|int', 'must be int or one of ' . Utils::arrayToPipedString($values)); } return $this->setOption(__FUNCTION__, $paging); }
/** * The default line type for any series not specified in the series property. * Available values are: * 'line', 'area', 'bars', 'candlesticks' and 'steppedArea' * * @param string $type * @throws InvalidConfigValue * @return Series */ public function type($type) { $values = array('line', 'area', 'bars', 'candlesticks', 'steppedArea'); if (in_array($type, $values)) { $this->type = $type; } else { throw new InvalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * A theme is a set of predefined option values that work together to achieve a specific chart * behavior or visual effect. Currently only one theme is available: * 'maximized' - Maximizes the area of the chart, and draws the legend and all of the * labels inside the chart area. Sets the following options: * * chartArea: {width: '100%', height: '100%'}, * legend: {position: 'in'}, * titlePosition: 'in', axisTitlesPosition: 'in', * hAxis: {textPosition: 'in'}, vAxis: {textPosition: 'in'} * * @param string $t * @return BarChart */ public function theme($t) { $values = array('maximized'); if (Utils::nonEmptyStringInArray($t, $values)) { $this->addOption(array(__FUNCTION__ => $t)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'must be one of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Specifies how to scale the axis to render the values within * the chart area. The following string values are supported: * * 'pretty' - Scale the values so that the maximum and minimum * data values are rendered a bit inside the left and right of the chart area. * 'maximized' - Scale the values so that the maximum and minimum * data values touch the left and right of the chart area. * 'explicit' - Specify the left and right scale values of the chart area. * Data values outside these values will be cropped. You must specify an * axis.viewWindow array describing the maximum and minimum values to show. * * This option is only supported for a continuous axis. * * @param string $viewMode * @throws InvalidConfigValue * @return Axis */ public function viewWindowMode($viewMode) { $values = array('pretty', 'maximized', 'explicit'); if (Utils::nonEmptyString($viewMode) && in_array($viewMode, $values)) { $this->viewWindowMode = $viewMode; } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Sets the alignment of the legend. * * Can be one of the following: * 'start' - Aligned to the start of the area allocated for the legend. * 'center' - Centered in the area allocated for the legend. * 'end' - Aligned to the end of the area allocated for the legend. * * Start, center, and end are relative to the style -- vertical or horizontal -- of the legend. * For example, in a 'right' legend, 'start' and 'end' are at the top and bottom, respectively; * for a 'top' legend, 'start' and 'end' would be at the left and right of the area, respectively. * * The default value depends on the legend's position. For 'bottom' legends, * the default is 'center'; other legends default to 'start'. * * @param string $alignment Alignment of the legend. * @return Legend */ public function alignment($alignment) { $values = array('start', 'center', 'end'); if (is_string($alignment) && in_array($alignment, $values)) { $this->alignment = $alignment; } else { throw new InvalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Sets The user interaction that causes the tooltip to be displayed. * * 'focus' - The tooltip will be displayed when the user hovers over an element. * 'none' - The tooltip will not be displayed. * * @param string $trigger Type of trigger. * @throws InvalidConfigValue * @return Tooltip */ public function trigger($trigger) { $values = array('focus', 'none'); if (in_array($trigger, $values)) { $this->trigger = $trigger; } else { throw new InvalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Supplemental function to add columns from strings. * * @param array $type * @param array $label * @param array $id * @param array $format * @throws InvalidConfigValue * @return DataTable */ private function addColumnFromStrings($type, $label = '', $id = '', $format = null) { $colIndex = $this->getNumberOfColumns(); if (in_array($type, $this->colCellTypes)) { if (Utils::nonEmptyString($type)) { $descArray['type'] = $type; } else { throw new InvalidConfigValue(__FUNCTION__, 'string'); } if (Utils::nonEmptyString($label)) { $descArray['label'] = $label; } if (Utils::nonEmptyString($id)) { $descArray['id'] = $id; } if (!is_null($format)) { $this->formats[$colIndex] = $format; } } else { throw new InvalidConfigProperty(__FUNCTION__, 'string', Utils::arrayToPipedString($this->colCellTypes)); } $this->cols[$colIndex] = $descArray; }
/** * The default line type for any series not specified in the series property. * Available values are: * 'line', 'area', 'bars', 'candlesticks' and 'steppedArea' * * @param string $t * @throws InvalidConfigValue * @return ComboChart */ public function seriesType($t) { $v = array('line', 'area', 'bars', 'candlesticks', 'steppedArea'); if (in_array($t, $v)) { return $this->addOption(array(__FUNCTION__ => $t)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($v)); } }
/** * The content of the text displayed on the slice. Can be one of the following: * * 'percentage' - The percentage of the slice size out of the total. * 'value' - The quantitative value of the slice. * 'label' - The name of the slice. * 'none' - No text is displayed. * * @param string $pieSliceText * @throws InvalidConfigValue * @return PieChart */ public function pieSliceText($pieSliceText) { $values = array('percentage', 'value', 'label', 'none'); if (is_string($pieSliceText) && in_array($pieSliceText, $values)) { $this->addOption(array('pieSliceText' => $pieSliceText)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Sets global configuration options for the whole Lavachart library. * * Accepted config options include: * errorPrepend: An html string * * @access public * @since v2.0.0 * * @param array $config Array of configurations options * @throws InvalidConfigProperty * @return void */ public function setOptions($config) { if (is_array($config)) { foreach ($config as $option => $value) { if (in_array($option, $this->validGlobals)) { $this->config[$option] = $value; } else { throw new InvalidConfigProperty(__METHOD__, $option, Utils::arrayToPipedString($this->validGlobals)); } } } else { throw new InvalidConfigValue(__METHOD__, 'array'); } }
/** * The easing function applied to the animation. * * The following options are available: * 'linear' - Constant speed. * 'in' - Ease in - Start slow and speed up. * 'out' - Ease out - Start fast and slow down. * 'inAndOut' - Ease in and out - Start slow, speed up, then slow down. * * @param string $e * @return Animation */ public function easing($e) { $values = array('linear', 'in', 'out', 'inAndOut'); if (Utils::nonEmptyStringInArray($e, $values)) { $this->easing = $e; } else { throw new InvalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * The resolution of the map borders. Choose one of the following values: * * 'countries' - Supported for all regions, except for US state regions. * 'provinces' - Supported only for country regions and US state regions. * Not supported for all countries; please test a country to * see whether this option is supported. * 'metros' - Supported for the US country region and US state regions only. * * @param string $r * @throws InvalidConfigValue * @return GeoChart */ public function resolution($r) { $v = array('countries', 'provinces', 'metros'); if (is_string($r) && in_array($r, $v)) { $this->addOption(array(__FUNCTION__ => $r)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($v)); } return $this; }
public function testArrayStringWithNonArray() { $this->assertFalse(Utils::arrayToPipedString('test1')); }
/** * The type of the entity that receives focus on mouse hover. * * Also affects which entity is selected by mouse click, and which data table * element is associated with events. Can be one of the following: * 'datum' - Focus on a single data point. Correlates to a cell in the data table. * 'category' - Focus on a grouping of all data points along the major axis. * Correlates to a row in the data table. * * In focusTarget 'category' the tooltip displays all the category values. * This may be useful for comparing values of different series. * * @since v2.4.1 * @param string $ft * @return AreaChart */ public function focusTarget($ft) { $values = array('datum', 'category'); if (Utils::nonEmptyStringInArray($ft, $values)) { $this->addOption(array(__FUNCTION__ => $ft)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'must be one of ' . Utils::arrayToPipedString($values)); } return $this; }
/** * Where to place the chart title, compared to the chart area. Supported values: * 'in' - Draw the title inside the chart area. * 'out' - Draw the title outside the chart area. * 'none' - Omit the title. * * @param string $tp * @throws InvalidConfigValue * * @return Chart */ public function titlePosition($tp) { $values = array('in', 'out', 'none'); if (is_string($tp) && in_array($tp, $values)) { return $this->addOption(array(__FUNCTION__ => $tp)); } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', 'with a value of ' . Utils::arrayToPipedString($values)); } }
/** * Overrides the default format for various aspects of date/datetime/timeofday data types. * * Allows formatting for years, months, days, hours, minutes, seconds, and milliseconds. * * @param array $units * @return \Khill\Lavacharts\Configs\Gridlines * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue */ public function units($units) { $unitFormats = []; $unitValues = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds']; if (is_array($units) === false) { throw new InvalidConfigValue(__FUNCTION__, 'array'); } foreach ($units as $unit => $format) { if (is_string($unit) === false || in_array($unit, $unitValues) === false) { throw new InvalidConfigValue(__FUNCTION__, 'string', 'Valid unit values are ' . Utils::arrayToPipedString($unitValues)); } if (Utils::nonEmptyString($format) === false) { throw new InvalidConfigValue(__FUNCTION__, 'string'); } $unitFormats[$unit] = $format; } return $this->setOption(__FUNCTION__, $unitFormats); }
/** * Parses a csv file into a DataTable. * * Pass in a filepath to a csv file and an array of column types: * ['date', 'number', 'number', 'number'] for example and a DataTable * will be built. * * @access public * @since 1.0.0 * @param string $filepath Path location to a csv file * @param array $columnTypes Array of column types to apply to the csv values * @throws \Khill\Lavacharts\Exceptions\InvalidFunctionParam * @return \Khill\Lavacharts\DataTable */ public function parseCsvFile($filepath, $columnTypes = null) { if (Utils::nonEmptyString($filepath) === false) { throw new InvalidFunctionParam($filepath, __FUNCTION__, 'string'); } $this->addNewColumns($columnTypes); $this->setReader(Reader::createFromPath($filepath)); $this->reader->setFlags(\SplFileObject::READ_AHEAD | \SplFileObject::SKIP_EMPTY); $csvColumns = $this->reader->fetchOne(); foreach ($this->newColumns as $index => $column) { if (in_array($column, $this->columnTypes, true) === false) { throw new InvalidColumnType($column, Utils::arrayToPipedString($this->columnTypes)); } $this->addColumnFromStrings($columnTypes[$index], $csvColumns[$index]); } $csvRows = $this->reader->setOffset(1)->fetchAll(function ($row) { return array_map(function ($cell) { if (is_numeric($cell)) { return $cell + 0; } else { return $cell; } }, $row); }); return $this->addRows($csvRows); }
/** * Overriding getOption function to pull config options from calendar array. * (Thanks google) * * @param string $option Which option to fetch * @return mixed * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue */ public function __get($option) { if ($this->options->get('calendar')->hasOption($option)) { return $this->options->get('calendar')->get($option); } elseif ($this->options->hasOption($option)) { return $this->options->get($option); } else { $calendarOptions = $this->options->get('calendar')->getOptions(); $nonCalendarOptions = $this->options->getOptions(); $options = array_merge($calendarOptions, $nonCalendarOptions); throw new InvalidConfigValue(static::TYPE . '->' . __FUNCTION__, 'string', 'must be one of ' . Utils::arrayToPipedString($options)); } }
/** * Register javascript callbacks for specific events. * * Set with an associative array where the keys are events and the values are the * javascript callback functions. * * Valid events are: * [ animationfinish | error | onmouseover | onmouseout | ready | select | statechange ] * * @access public * @param array $events Array of events associated to a callback * @return \Khill\Lavacharts\Charts\Chart * @throws \Khill\Lavacharts\Exceptions\InvalidConfigValue */ public function events($events) { if (is_array($events) === false) { throw new InvalidConfigValue(static::TYPE . '->' . __FUNCTION__, 'array', 'who\'s keys are one of ' . Utils::arrayToPipedString($this->defaultEvents)); } foreach ($events as $event => $callback) { if (Utils::nonEmptyString($callback) === false) { throw new InvalidConfigValue(static::TYPE . '->' . __FUNCTION__, 'string'); } $this->events->set($event, $callback); } return $this; }
/** * Gets a specific option from the array. * * @param string $o Which option to fetch * @throws InvalidConfigValue * @return mixed */ public function getOption($o) { if (is_string($o) && array_key_exists($o, $this->options)) { return $this->options[$o]; } else { throw $this->invalidConfigValue(__FUNCTION__, 'string', "must be one of " . Utils::arrayToPipedString($this->defaults)); } }