Files
BE_IBL/application/controllers/tools/sas/ChartV2.php
2026-04-15 15:23:57 +07:00

410 lines
15 KiB
PHP

<?php
class Chartv2 extends MY_Controller
{
var $url_renderer;
function __construct()
{
parent::__construct();
$this->url_renderer = "http://devkedungdoro.aplikasi.web.id:3000/chart";
}
function all($sdate,$edate)
{
// $sql = "SELECT project_name, sum(unit_amount) as s_hour
// FROM one_support.odoo_timesheet
// WHERE date_trx BETWEEN '{$sdate}' AND '{$edate}'";
// get total hour and employee between start and end date
$sql = "SELECT
COUNT(employee_name) as n_employee,
IFNULL(SUM(s_hour), 0) as total
FROM
(SELECT employee_name,
project_name, sum(unit_amount) as s_hour
FROM one_support.odoo_timesheet
WHERE
date_trx BETWEEN '{$sdate}' AND '{$edate}'
GROUP BY employee_name
) as x";
$qry = $this->db->query($sql);
$this->check_error($qry, "get project_name");
$rows = $qry->result_array();
if (count($rows) == 0) {
$this->chart_error("No data found");
}
// get total weekdays between start and end date
$sql_weekdays = "SELECT
COUNT(day_code) as tot_weekday
FROM
(SELECT
WEEKDAY(date_trx) as day_code
FROM
one_support.odoo_timesheet
WHERE
date_trx BETWEEN '{$sdate}' AND '{$edate}'
GROUP BY date_trx
) as x
WHERE x.day_code != 6 AND x.day_code != 5";
$wk_qry = $this->db->query($sql_weekdays);
$this->check_error($wk_qry, "get project_name");
$row_wk = $wk_qry->result_array();
if (count($row_wk) == 0) {
$this->chart_error("No data found");
}
// calc percentage total hour / n_weekday * 8 * n_employee
$week_hour = $row_wk[0]['tot_weekday'] * 8 * $rows[0]['n_employee'];
$value = ($rows[0]['total'] / $week_hour) * 100;
$formatted = number_format($value, 2, '.', '');
$option = [
'series' => [
[
'type' => 'gauge',
'max' => 150,
'splitNumber' => 15,
'radius' => '97%',
'center' => ['50%', '57%'],
'axisLine' => [
'lineStyle' => [
'width' => 25,
'color' => [
[0.2, '#27CF2F'],
[0.8, '#37a2da'],
[1, '#fd666d']
]
]
],
'pointer' => [
'itemStyle' => [
'color' => 'auto'
]
],
'axisTick' => [
'distance' => -30,
'length' => 8,
'lineStyle' => [
'color' => '#fff',
'width' => 2
]
],
'splitLine' => [
'distance' => -30,
'length' => 30,
'lineStyle' => [
'color' => '#fff',
'width' => 4
]
],
'axisLabel' => [
'color' => 'inherit',
'distance' => 40,
'fontSize' => 15
],
'title' => [
'offsetCenter' => [0, '55%'],
'fontSize' => 15,
],
'detail' => [
'valueAnimation' => true,
'color' => 'inherit',
'formatter' => '{value} %',
'fontSize' => 18,
'offsetCenter' => ['0%', '70%']
],
'data' => [
[
'name' => 'Percent Hour',
'value' => $formatted,
]
]
]
]
];
// 3. encapsulate in config attribute and json encode
$config = ["config" => $option];
$j_param = json_encode($config);
header("Content-Type: image/png");
// 4. post to chart renderer
echo $this->post($this->url_renderer, $j_param);
}
function project_group($sdate,$edate)
{
$sql = "SELECT project_name, sum(unit_amount) as s_hour
FROM one_support.odoo_timesheet
WHERE date_trx BETWEEN '{$sdate}' AND '{$edate}'
GROUP BY project_name
ORDER BY s_hour DESC";
$qry = $this->db->query($sql);
$this->check_error($qry, "get project_name");
$rows = $qry->result_array();
if (count($rows) == 0) {
$this->chart_error("No data found");
}
$param = array(
'tooltip' => array(
'trigger' => 'item',
'formatter' => '{b}: {c} ({d}%)'
),
'legend' => array(
'orient' => 'vertical',
'right' => '10%',
'top' => 'center'
),
'series' => array(
array(
'name' => 'Access From',
'type' => 'pie',
'radius' => '70%',
'center' => ['40%', '50%'],
'labelLine' => array(
'show' => false
),
'label' => array(
'show' => true,
'position' => 'inside',
'formatter' => '{d}%',
'backgroundColor' => 'rgba(0, 0, 0, 0.5)',
'borderRadius' => 5,
'padding' => 4,
'color' => '#fff'
),
'itemStyle' => array(
'normal' => array(
'shadowBlur' => 20,
'shadowOffsetX' => 0,
'shadowColor' => 'rgba(0, 0, 0, 0.5)'
)
),
'emphasis' => array(
'itemStyle' => array(
'shadowBlur' => 30,
'shadowOffsetX' => 0,
'shadowColor' => 'rgba(0, 0, 0, 0.7)'
)
),
'data' => array()
)
)
);
$other_val = 0.0;
for ($i = 0; $i < count($rows); $i++) {
if ($i <= 3) {
$param['series'][0]['data'][] = array(
'value' => $rows[$i]['s_hour'],
'name' => $rows[$i]['project_name'],
);
} else {
$other_val = $other_val + $rows[$i]['s_hour'];
}
}
$param['series'][0]['data'][] = array(
'value' => $other_val,
'name' => 'Others',
);
// 3. encapsulate in config attribute and json encode
$config = ["config" => $param];
$j_param = json_encode($config);
header("Content-Type: image/png");
// 4. post to chart renderer
echo $this->post($this->url_renderer, $j_param);
}
function staff($sdate,$edate,$employee_id)
{
// 1. prepare the data using sql
$sql = "SELECT COUNT(*) AS total, employee_name, SUM(unit_amount) as unit_amount,project_name
FROM one_support.odoo_timesheet
WHERE date_trx BETWEEN '{$sdate}' AND '{$edate}'
AND employee_id = {$employee_id}
GROUP BY project_name";
$qry_total_data = $this->db->query($sql, [$id]);
$this->check_error($qry_total_data, "get xTotalAll mcu");
$rows = $qry_total_data->result_array();
if (count($rows) == 0) {
$this->chart_error("No data found");
}
// $rows = array(
//fungsi mengatur pembagian label / text
function wrapText($text, $maxLength)
{
return wordwrap($text, $maxLength, "\n", true); // Memecah teks menjadi beberapa baris dengan panjang maksimum dan menggunakan newline sebagai pemisah
}
// 2. generate parameter for the chart
$color = ['#36A2EB', '#FF5733', '#FFC300', '#4BC0C0', '#9966FF'];
// Mendapatkan nilai unik dari 'project_name' dan 'employee_name' serta mengatur ulang indeks array
$uniqueProjects = array_values(array_unique(array_column($rows, 'project_name')));
$uniqueStaffs = array_values(array_unique(array_column($rows, 'employee_name')));
$param = array(
'title' => array(
'text' => 'Project By Staff',
'left' => 'center', // Menempatkan legend di tengah secara horizontal,
'top' => 'top',
'orient' => 'vertical'
),
'dataset' => array(
'source' => array(
array('score', 'amount', 'product'),
)
),
//menampilkan nama bagian tiap-tiap chart
'legend' => array(
'data' => $uniqueProjects,
'left' => 'center',
'bottom' => 'bottom',
'orient' => 'horizontal'
),
'grid' => array('containLabel' => true),
'yAxis' => array('type' => 'value'),
'xAxis' => array(
'type' => 'category',
'axisTick' => array('show' => false),
'data' => $uniqueStaffs,
),
'visualMap' => array(
'orient' => 'horizontal',
'show' => false,
'left' => 'center',
'min' => 0,
'max' => 100,
'dimension' => 0,
'inRange' => array(
// 'color' => array('#0000FF', '#00eaf2', '#035bff')
)
),
'series' => array()
);
// Memetakan warna tiap bar sesuai dengan kategori project_name
$colorMapping = array();
foreach ($uniqueProjects as $index => $project_name) {
$colorMapping[$project_name] = $color[$index % count($color)]; // Menggunakan modulus untuk memastikan palet warna diulang jika jumlah kategori lebih banyak daripada warna yang tersedia
}
foreach ($uniqueProjects as $project_name) {
$data = array_fill(0, count($uniqueStaffs), null); // Inisialisasi data untuk setiap lokasi
foreach ($rows as $row) {
if ($row['project_name'] == $project_name) {
// Menemukan indeks lokasi dalam $uniqueStaffs
$employee_nameIndex = array_search($row['employee_name'], $uniqueStaffs);
if ($employee_nameIndex !== false) {
$data[$employee_nameIndex] = $row['unit_amount'] ?? 0; // Handling null values
}
}
}
$param['series'][] = array(
'name' => $project_name,
'type' => 'bar',
'barGap' => 0.5,
'label' => array(
'show' => true,
'position' => 'top',
'distance' => 25,
'fontSize' => 12, // Menyesuaikan ukuran font
'formatter' => '', // Menggunakan formatter untuk memisahkan baris
'rich' => array('name' => array()),
),
'itemStyle' => array( // Menentukan gaya item untuk bar, termasuk warnanya
'color' => $colorMapping[$project_name]
),
'data' => $data
);
}
// 3. encapsulate in config attribute and json encode
$config = ["config" => $param];
$j_param = json_encode($config);
// echo $j_param;
header("Content-Type: image/png");
// 4. post to chart renderer
echo $this->post($this->url_renderer, $j_param);
}
function check_error($qry, $stage)
{
if (!$qry) {
$errMsg = $stage . "<br/>" . $this->db->error()["messge"];
print_r($errMsg);
$this->chart_error($errMsg);
}
}
function chart_error($msg)
{
$param = array(
'title' => array(
'show' => true,
'textStyle' => array(
'color' => 'grey',
'fontSize' => 20
),
'text' => $msg,
'left' => 'center',
'top' => 'center'
),
'xAxis' => array(
'show' => false
),
'yAxis' => array(
'show' => false
),
'series' => array()
);
header("Content-Type: image/png");
$config = ["config" => $param];
$j_param = json_encode($config);
echo $this->post($this->url_renderer, $j_param);
exit;
}
function post($url, $data)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, j120);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"Content-Length: " . strlen($data),
]);
$result = curl_exec($ch);
if (curl_errno($ch) > 0) {
return [
"status" => "ERR",
"message" => curl_error($ch),
];
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode != 200) {
return [
"status" => "ERR",
"message" => "Http Response : $httpCode",
];
}
return $result;
}
function getMaxValue($value) {
$multiple = 150;
return ceil($value / $multiple) * $multiple;
}
}