Milk Admin
Chart
Revision: 2026-01-05
The Chart plugin allows you to display graphs or tables with static or dynamic data.
Charts are managed with the Chart.js library and tables with a custom template class. This way the data structure is the same.
For tables, datasets indicate columns, while labels indicate rows. For charts, datasets indicate series, while labels indicate categories.
Quick Start (Module)
Create a module and render a chart or table directly in your page action:
<?php
namespace Modules\ChartDemo;
use App\Abstracts\AbstractModule;
use App\Attributes\RequestAction;
use App\Response;
use App\Get;
class ChartDemoModule extends AbstractModule {
protected function configure($rule): void {
$rule->page('chart-demo')
->title('Chart Demo')
->menu('Chart Demo', '', 'bi bi-graph-up', 50)
->access('admin');
}
#[RequestAction('home')]
public function home(): void {
$data = [
'labels' => ['Jan', 'Feb', 'Mar'],
'datasets' => [
['label' => 'Sales', 'data' => [12, 19, 8], 'type' => 'bar'],
['label' => 'Leads', 'data' => [7, 11, 5], 'type' => 'bar'],
],
];
$chart = Get::themePlugin('chart', [
'id' => 'sales_chart',
'type' => 'bar',
'data' => $data,
'options' => [
'legend_position' => 'top',
'start_by_zero' => true,
],
]);
$table = Get::themePlugin('chart', [
'id' => 'sales_table',
'type' => 'table',
'data' => $data,
'options' => [
'preset' => 'hoverable',
'firstCellText' => '#',
],
]);
Response::render($chart . $table);
}
}
Data Structure
{
"labels": ["A", "B", "C"],
"datasets": [
{ "label": "Series 1", "data": [1, 2, 3], "type": "bar" },
{ "label": "Series 2", "data": [2, 1, 4], "type": "bar" }
]
}
Table Options
firstCellText: text for the first cellpreset: additional class for the table that defines its appearance. Possible values are default, compact, dark, or hoverableshowLabels: show or hide labelscellClass: array of classes applied to individual columnsitemsPerPage: rows per page (0 disables pagination)headerClass: class for the table header
Chart Options (Common)
legend_position: top, left, bottom, rightstart_by_zero: start Y axis from zeroscale_x/scale_y: set axis type or hide withhidetitle_x/title_y: axis titlesheight: fixed height for the chart container (e.g.260px)
You can generate a chart or table through the chart plugin in Ito.
$data = json_decode('{"labels":[0,1,2,3],"datasets":[{"data":["78","66","42","77"],"label":"age","type":"bar"},{"data":["60","70","67","80"],"label":"weight","type":"bar"}]}', true);
echo Get::themePlugin('chart', ['id'=>'table', 'type'=>'table', 'data'=> $data, 'options'=>['preset'=>'hoverable', 'firstCellText' => 'X']]);
echo Get::themePlugin('chart', ['id'=>'chart', 'type'=>'bar', 'data'=> $data ]);
example table
table
Loading...
Card by SQL
Dynamic filterable data
Loading...
Table examples
<?php echo Get::themePlugin('chart', ['id'=>'noLabel', 'type'=>'table', 'data'=> $data,
'options'=>[
'preset'=>'default',
'showLabels' => false,
'cellClass'=>['col-min', ''],
'itemsPerPage' =>2,
'headerClass'=>'thead-dark'
]]); ?>
Table without labels or pagination
Loading...
Page options
Choose the number of rows per page and the pagination positionitemsPerPage: number of rows per page. 0 for no paginationcellClass: array of classes applied to individual columns.showLabels: show or hide labelspreset: additional class for the table that defines its appearance. Possible values are default, compact, dark, or hoverable- Special classes: for columns
.col-minfor minimum width,.thead-darkfor dark header
If you want to update the data after inserting the chart, you can manage the loading state and data update as shown in the example:
var data1 = {"labels":[0,1,2,3,4,5,6,7,8,9],"datasets":[{"data":["78","66","42","77","70","86","58","33","56","61"],"label":"age","type":"bar"},{"data":["60","70","67","80","95","71","68","65","82","84"],"label":"weight","type":"bar"}, {"data":["160","170","167","180","195","171","168","165","182","184"],"label":"height","type":"bar"}]}
function updateData(el) {
el.disabled = true;
itoCharts.getLoader('table').show();
itoCharts.getLoader('chart').show();
setTimeout(() => {
itoCharts.update('table', data1);
itoCharts.update('chart', data1);
itoCharts.getLoader('table').hide();
itoCharts.getLoader('chart').hide();
el.disabled = false;
}, 3000);
}
example table
table
Loading...
Card by SQL
Dynamic filterable data
Loading...
Loading...