# Introduction

`ApexCharts` package contains server-side PHP classes the super popular client-side chart library [ApexCharts](https://apexcharts.com/javascript-chart-demos/), which can be used totally offline.

#### [View demo](https://www.koolreport.com/examples/apexcharts/collections)

# Installation

## By downloading .zip file

1. Download zip file from [My Licenses](https://www.koolreport.com/my-licensed-packages)
2. Unzip
3. Copy the folder `apexcharts` into `koolreport` folder, it will look like below:

```bash
koolreport
├── core
├── apexcharts
```

4. Include `koolreport/core/autoload.php` in your index.php file.

## By composer

If you have purchased the package then you can follow these steps to install

1. Login to [koolreport.com](https://www.koolreport.com)
2. Go to [My Licenses](https://www.koolreport.com/my-licensed-packages)
3. Click __Get Token For Composer__ button
4. Copy the text and save to file `auth.json` next to `composer.json`
5. Add the repositories to `composer.json` like below
6. Run `composer update` to install package
7. Include `vendor/autoload.php` in your index.php file.

`composer.json`

```
{
    "repositories":[
        {"type":"composer","url":"https://repo.koolreport.com"}
    ],
    "require":{
        "koolreport/apexcharts":"*",
        ...
    }
}
```

Your `auth.json` will look like this:

```
{
    "http-basic": {
        "repo.koolreport.com": {
            "username": "your@email.com",
            "password": "your-secret-token"
        }
    }
}
```

__*Note:*__ Please add your `auth.json` to `.gitignore` as it contains your secret login information.

# Common settings

## Example

```
<?php
ColumnChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "title"=>"Sale Amount On Each Category"
    "columns"=>array(
        "category",
        "amount"=>array(
            "label"=>"Amount",
            "type"=>"number",
            "prefix"=>'$',
        )
    ),
))
?>
```

In above example, we use datastore `category_amount` as the dataSource for ColumnChart. We set the `title` for the chart to "Sale Amount On Each Category". We specify columns from datastore to be used for drawing chart. The first column `category` will be acted as label for xAxis while `amount` will be value for yAxis. We add extra settings for `amount` columns to make dollar sign appear in front of number.

We may add more data column to `columns`, for each added columns, new chart series will be added.

## Chart settings

|name|type|default|description|
|---|---|---|---|
|`name`|||Specify name of chart, it is optional|
|`dataSource`|||`*required` Specify the source for chart, accept DataStore, DataSource, Process and even array data in table or associate format.|
|`data`|array||An array of data. To be used in case `dataSource` is null|
|`columns`|array/mixed||Specify the list of columns will be used to draw chart|
|`options`|array||Specify extra options for charts, see extra options section for more details.|
|`autoCategoryColumn`|boolean||Use default categories or not|
|`title`|string||Title of the chart|
|`titleAlignment`|string||Title alignment|
|`subtitle`|string||Subtitle of the chart|
|`subtitleAlignment`|string||Subtitle alignment|
|`xTitle`|string||Xaxis title of the chart|
|`yTtle`|string||Yaxis title of the chart|
|`showXaxis`|boolean||show Xaxis or not|
|`showYaxis`|boolean||show Yaxis or not|
|`stacked`|boolean|false|Specify if the series of chart will be stacked.|
|`stackType`|string||Specify if the series of chart will be stacked.|
|`showLegend`|boolean||show legends or not|
|`showLabel`|boolean||show labels or not|
|`showTooltip`|boolean||show tooltips or not|
|`showMarker`|boolean||show markers or not|
|`showStroke`|boolean||show stroke or not|
|`strokeCurve`|string/array||set series' stroke curve type|
|`strokeWidth`|number/array||set series' stroke width |
|`fillType`|string/array||set series' color filling type|
|`fillOpacity`|number/array||set series' color filling opacity|
|`markersSize`|number/array||set series' markers' sizze|
|`width`|string/numer||set chart's width in pixel or relative percentage|
|`height`|string/number||set chart's height in pixel or relative percentage|
|`widthHeightAutoRatio`|number||set chart's width to height ratio in case at least one of them is not fixed in pixel|
|`maxWidth`|string/numer||set chart's maximum width in pixel or relative percentage|
|`sparkline`|boolean||set chart to sparkline mode for small size charts|
|`keepNullValue`|boolean||allow null values in series or not|
|`uniqueCategories`|boolean||set unique or duplicated categories|
|`optionArrayDelimiter`|string||set delimiter/separator for options string properties|
|`cssStyles`|array||set css styles for chart's parent wrapper div element|
|`colorScheme`|array||set colors for single or multiple data series|
|`colors`|array||the same as colorScheme|

## Category column settings

|name|type|default|description|
|---|---|---|---|
|`label`|string||Set label for column|
|`categoryType`|string||Set the type of category to be `category` or `datetime`|

## Data column settings

|name|type|default|description|
|---|---|---|---|
|`label`|string||Set label for column|
|`type`|string||Type of columns `number`,`string`,`datetime`|
|`prefix`|string||Set prefix for value, for example `$`|
|`suffix`|string||Set suffix for value|
|`formatValue`|string/function||Accept string or function. For example: `"formatValue"=>"@value USD"` or `"formatValue"=>function($value){return $value." USD";}`|
|`decimals`|number||The number of number after decimal points|
|`thousandSeparator`|string|`,`|Specify how thousand is seperated|
|`decimalPoint`|string|`.`|Specify decimal point|


## Extra data column settings
|name|type|default|description|
|---|---|---|---|
|`chartType`|string||In case of combo chart, set which type of chart a column/series should be drawn as.|
|`chartColor`|string||Set the color of the column/series|
|`charts`|array||In case of multiple charts classes such as SynchCharts, BrushCharts, this one specifies which subcharts a series belongs to|
|`combination`|array||Used for chart type that requires a vector instead of a number as y value, e.g scatter requires 2-point values, bubble requires 3-point values|
|`seriesGroup`|boolean||Used to convert a data table into multiple series based on the column's unique values|


__Example for column settings:__

```
ColumnChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "category",
        "amount"=>array(
            "label"=>"Amount",
            "type"=>"number",
            "prefix"=>'$',
        )
    ),
));

SynchChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "category",
        "amount"=>array(
            "label"=>"Amount",
            "chartType"=>"line",
            "chartColor=>"blue",
            "charts"=>[1],
        ),
        "profit"=>array(
            "label"=>"Profit",
            "chartType"=>"column",
            "chartColor=>"green",
            "charts" => [2],
        ),        
    ),
));
?>
```

## Chart groups

There are several criteria to divide chart types into main groups. 

### By xaxis category types and non-category

Based on xaxis category types, we have discrete types such as string, integer categories; continuous types such as datetime, real number; or non-category types such as scatter, bubble charts that only requires series of 2-dimension, 3-dimension coordinates. With category charts, the first column is by default the category one. You can set its category type with "categoryType" property:

```
ColumnChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "month" => array( // category column
            "categoryType" => "category", //discrete categories, categoryType value is "category" by default
        ),
        "sales" => array() // data column
    ),
));

ColumnChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "datetime" => array( // category column
            "categoryType" => "datetime", //continuous categories
        ),
        "sales" => array() // data column
    ),
));
```
In case all you have is data columns you can set `autoCategoryColumn` setting to true to create auto numeric categories (1, 2, 3, 4, etc).

With non-category charts, all columns are data columns by default:

```
        \koolreport\apexcharts\ScatterChart::create(array(
            "dataSource" => $data,
            "columns" => array(
                'SAMPLE A' => [ // data column, no category column
                    'combination' => [
                        'SampleA_x',
                        'SampleA_y',
                    ]
                ],
            ),
        ));

```

### By scalar and vector yaxis values

Based on yaxis value, we have scalar value (i.e single, non-vector, numeric values) types that most charts are; 
vector value types such as rangebar, timeline that requires 2-D dimension vectors 
or candlestick, boxplot that requires 4-dimension, 5-dimension vectors. 

Scalar charts are straighforward, each data column is one series. 
Vector charts' columns need to combine several columns to create one series with `combination` column property. 
Here are examples for both types:

```
ColumnChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "month",
        "revenue", //scalar value
        "profit", //scalar value
    ),
));

RangeAreaChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "month",
        "temperature range" => array( // 2-dimension vector value
            "combination" => array(
                "lowest_day_sales",
                "hight_day_sales",
            )
        )
    ),
));

CandleStickChart::create(array(
    "dataSource"=>$this->dataStore("category_amount"),
    "columns"=>array(
        "columns" => array(
            'trade_date',
            'stock_price' => [ // 4-dimension vector value
                'combination' => [
                    'open',
                    'high',
                    'low',
                    'close',
                ]
            ]
        ),
    ),
));
```

## Chart data source structure

All ApexCharts widgets use data source in table structure where one or none column acts as category column and others act as data columns. 
Here's an example of a data source with one category column and two data columns:

```
        $data_line_chart = [
            [
                'year', // category column
                'series-1', // data column
                'series-2', // data column
            ],
            [
                "2001", // category value
                44, // data value
                53 // data value
            ],
            [
                "2002", // category value
                55, // data value
                32 // data value
            ],
            ...
        ];

        $data_scatter_chart = [
            [
                'SampleA_x', // data column
                'SampleA_y' // data column
            ],
            [
                16.4, // data value
                5.4 // data value
            ],
            [
                21.7, // data value
                2 // data value
            ],
            ...
        ];
```

### Helpers to convert data source structure

KoolReport Pro and ApexCharts package provides several methods and properties to convert other data structures into one its widgets can use.

One common case is that instead of single data table, users have multiple tables for multiple categories.
In a lot of those cases they can use the following `mergeDatasets` method to merge multiples tables into one:

```
        $data_bob = [
            [
                'phase',
                'bob_start',
                'bob_end',
            ],
            [
                "Design",
                "2019-3-5",
                "2019-3-8"
            ],
            [
                "Code",
                "2019-3-2",
                "2019-3-5"
            ],
            ...
        ];
        $data_joe = [
            [
                'phase',
                'joe_start',
                'joe_end',
            ],
            [
                "Design",
                "2019-3-2",
                "2019-3-5"
            ],
            [
                "Test",
                "2019-3-6",
                "2019-3-16"
            ],
            ...
        ];
        $data = \koolreport\apexcharts\Chart::mergeDatasets(
            $data_bob,
            $data_joe
        );
        \koolreport\apexcharts\TimeLineChart::create(array(
            "dataSource" => $data,
            "columns" => array(
                "phase" => [],
                "Bob" => [
                    "combination" => [
                        "bob_start",
                        "bob_end",
                    ]
                ],
                "Joe" => [
                    "combination" => [
                        "joe_start",
                        "joe_end",
                    ]
                ],
            ],
            ...
        ]);
```
The common "phase" column will be used as the join column to merge the two datasets.

Another usual situation is when users want to tranpose a data table, 
i.e flip the table across its diagonal line so that the first row becomes the first column and vice versa:

```
        $data = [
            [
                'category',
                "W1",
                "W2",
                "W3",
                "W4",
                "W5"
            ],
            [
                "13:00",
                0,
                63,
                35,
                40,
                85
            ],
            [
                "13:30",
                72,
                78,
                67,
                50,
                75
            ]
            ...
        ];
        $transposeData = \koolreport\core\Utility::transpose($data);
        \koolreport\apexcharts\HeatMapChart::create(array(
            "dataSource" => $transposeData,
            "columns" => $transposeData[0],
            ...
        ));
        /* After tranposed:
        $transposedData = [
            [
                "category",
                "13:00",
                "13:30",
                ...
            ],
            [
                "W1",
                0,
                72,
                ...
            ],
            [
                "W2",
                63,
                78,
                ...
            ],
            [
                "W3",
                35,
                67,
                ...
            ],
            [
                "W4",
                40,
                50,
                ...
            ],
            [
                "W5",
                85,
                75,
                ...
            ],    
        ]
        */
```

Finally, sometimes users want to divide a single data table into multiple data series 
based on a specific column where each of the column's unique value separates a series.
Consider the following example:

```
        $data = [
            [
                'name',
                'position',
                'date_start',
                'date_end',
            ],
            [
                "George Washington",
                "President",
                "1789/4/30",
                "1797/3/4"
            ],
            [
                "John Adams",
                "President",
                "1797/3/4",
                "1801/3/4"
            ],
            [
                "John Adams",
                "Vice President",
                "1789/4/21",
                "1797/3/4"
            ],
            [
                "Thomas Jefferson",
                "President",
                "1801/3/4",
                "1809/3/4"
            ],
            [
                "Thomas Jefferson",
                "Vice President",
                "1797/3/4",
                "1801/3/4"
            ],
            ...
        ];
        \koolreport\apexcharts\TimeLineChart::create(array(
            "dataSource" => $data,
            "columns" => [
                'name' => [
                    'seriesGroup' => true,
                ],
                'position',
                'term' => [
                    'combination' => [
                        'date_start',
                        'date_end',
                    ],
                ],
            ],
            ...
        ));
        /* This data and chart setup is equivalent to the following one:
        $data = [
            [
                'position',
                'George Washington__date_start',
                'George Washington__date_end',
                'John Adams__date_start',
                'John Adams__date_end',
                'Thomas Jefferson__date_start',
                'Thomas Jefferson__date_end',
            ],
            [
                "President",
                "1789/4/30",
                "1797/3/4",
                "1797/3/4",
                "1801/3/4",
                "1801/3/4",
                "1809/3/4"
            ],
            [
                "Vice President",
                null,
                null,
                "1789/4/21",
                "1797/3/4"
                "1797/3/4",
                "1801/3/4"
            ],
        ];
        \koolreport\apexcharts\TimeLineChart::create(array(
            "dataSource" => $data,
            "columns" => [
                'position',
                'George Washington' => [
                    'combination' => [
                        'George Washington__date_start',
                        'George Washington__date_end',
                    ],
                ],
                'John Adams' => [
                    'combination' => [
                        'John Adams__date_start',
                        'John Adams__date_end',
                    ],
                ],
                'Thomas Jefferson' => [
                    'combination' => [
                        'Thomas Jefferson__date_start',
                        'Thomas Jefferson__date_end',
                    ],
                ]
            ],
            ...
        ));
        */
```
The `seriesGroup` column property is a very convenient way to create series dynamically 
instead of knowing the number of series and their names in advance.

## Chart options

Beside a chart's settings, you can set detail options in its `options` array property. 
Full detail options can be found in ApexCharts' documentation link:

[ApexCharts client-side options](https://apexcharts.com/docs/options/)

To use them, convert an option's JSON object to PHP array and put it in ApexCharts widget's `options` like this:

```
\koolreport\apexcharts\LineChart::create(array(
    ...
    "options" => [
        'grid' => [
            'row' => [
                'colors' => [
                    '#f3f3f3',
                    'transparent',
                ],
                'opacity' => 0.5,
            ],
        ],
    ],
    ...
));
```
[https://apexcharts.com/docs/options/grid/#row](https://apexcharts.com/docs/options/grid/#row)

### Flattened options array

As a convenience for ApexCharts users, the package allows flattening options array for deep options like this:

```
\koolreport\apexcharts\LineChart::create(array(
    ...
    "options" => [
        'grid | row | opacity' => 0.5,
        ...
    ],
    ...
));
```

The following options syntaxes are equivalent in this package and one might find one way preferable to others for their specific situation:

```
\koolreport\apexcharts\LineChart::create(array(
    ...
    "options" => [
        'a | b | c | d1 | e | f' => 'value1',
        'a | b | c | d2 | e | f' => 'value2',

        'a | b | c' => [
            'd1 | e | f' => 'value1',
            'd2 | e | f' => 'value2'
        ],
        
        'a' => [
            'b' => [
                'c' => [
                    'd1 | e | f' => 'value1',
                    'd2 | e | f' =>'value2'
                ]
            ]
        ],

        'a | b | c' => [
            'd1' => [
                'e' => [
                    'f' => 'value1'
                ]
            ],
            'd2' => [
                'e' => [
                    'f' => 'value2'
                ]
            ]
        ],

        'a' => [
            'b' => [
                'c' => [
                    'd1' => [
                        'e' => [
                            'f' => 'value1'
                        ]
                    ],
                    'd2' => [
                        'e' => [
                            'f' => 'value2'
                        ]
                    ]
                ]
            ]
        ],
    ],
    ...
));
```

# Support

Please use our forum if you need support, by this way other people can benefit as well. If the support request need privacy, you may send email to us at __support@koolreport.com__.