dataTable switch to next page with no entry - paging issue - javascript

I want to display records from mysql-database on a monitor using a table from dataTables with serverside paging. Maximum rows per side should be 14. When filling up the database and reaching the 14th row the table already starts paging (!) showing the message "no matching records found".... then it switches back to the page with 1-14 rows....
Any clue what I am doing wrong here?
My code is as follows:
php-page creating json array
//fetch.php
$connect = new PDO("mysql:host=localhost;dbname=eflightbook", "root", "");
$column = array("usersName", "usersFirstname", "fldirector");
$query = "SELECT usersName, usersFirstname, TIME(date), fldirector, t1.*
FROM users, flightbook t1
WHERE usersLoginStatus <> 'false'
AND id = anw_id
AND t1.date = (SELECT MAX(t2.date)
FROM users, flightbook t2
WHERE t2.anw_id = t1.anw_id)
";
if(isset($_POST['order']))
{
$query .= 'ORDER BY '.$column[$_POST['order']['0']['column']].' '.$_POST['order']['0']['dir'].' ';
}
else
{
$query .= 'ORDER BY TIME(date) ASC ';
}
$query1 = '';
if($_POST['length'] != -1)
{
$query1 = 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
}
$statement = $connect->prepare($query);
$statement->execute();
$number_filter_row = $statement->rowCount();
$result = $connect->query($query . $query1);
$data = array();
foreach($result as $row)
{
$sub_array = array();
$sub_array[] = $row['usersName'];
$sub_array[] = $row['usersFirstname'];
$sub_array[] = $row['TIME(date)'];
$sub_array[] = ($row['fldirector'] == "1") ? "✔" : "";
$data[] = $sub_array;
}
function count_all_data($connect)
{
$query = "SELECT anw_id, usersName, usersFirstname, TIME(date), fldirector, t1.*
FROM users, flightbook t1
WHERE usersLoginStatus <> 'false'
AND id = anw_id
AND t1.date = (SELECT MAX(t2.date)
FROM users, flightbook t2
WHERE t2.anw_id = t1.anw_id)
";
$statement = $connect->prepare($query);
$statement->execute();
return $statement->rowCount();
}
$output = array(
"draw" => intval($_POST["draw"]),
"recordsTotal" => count_all_data($connect),
"recordsFiltered" => $number_filter_row,
"data" => $data
);
echo json_encode($output);
?>
**Monitor html/php Page**
<script>
// Active Pilots Table
$(document).ready(function(){
function load_data(start, length)
{
var dataTable = $('#datatable').DataTable({
"processing" : false,
"serverSide" : true,
"pageLength" : 14,
"lenghtChange" : false,
"language": {
"emptyTable": "** kein Eintrag **"},
"columnDefs": [
{
targets: -1,
className: 'dt-body-center'
}],
"responsive" : false,
"autoWidth" : false,
"ordering" : false,
"searching" : false,
"scrollCollapse" : true,
"binfo" : false,
"bFilter" : false,
"bLengthChange" : false,
dom: "lfrti",
"order" : [],
"retrieve": true,
"ajax" : {
url:"activep.php",
method:"POST",
data:{start:start, length:length}
},
"drawCallback" : function(settings){
var page_info = dataTable.page.info();
console.log(page_info);
}
});
}
load_data();
var table = $('#datatable').DataTable();
setInterval(function(){
var info = table.page.info();
if (info.start < info.end) {
var page_number = (info.page < info.pages) ? info.page + 1 : 1;
}
else {
page_number = 0;
}
;
table.page(page_number).draw(false);
}, 6000);
});

Your problem is here:
var info = table.page.info();
if (info.start < info.end) {
var page_number = (info.page < info.pages) ? info.page + 1 : 1;
}
else {
page_number = 0;
}
;
table.page(page_number).draw(false);
There are two issues. First, to specifically answer your question: assuming info.page is equal to info.pages (which means you have one page of records) you are setting the page number to 1, but that property is indexed at 0 (and also documentation here), so you are actually forcing it to the second page:
var page_number = (info.page < info.pages) ? info.page + 1 : 1;
and then later, you pass that page number value to your table:
table.page(page_number).draw(false);
And the second issue (which is not the cause of your specific problem but is definitely problematic in terms of variable scope): you define the page_number variable inside the scope of the if statement but then use it outside of that scope. That type of variable declaration should be avoided. You should declare the variable outside of the if statement.

Related

Why does my function return everything except the last item in the array?

With the code below, I am trying to return all the items in item.children. I don't understand why it isn't returning the last item. After logging the results at several places and verifying SQLs, I could finally conclude the part of the code below in a file that is accessed via ajax is creating the array without the last record in the SQL result. I am still unable to find where it is missing the last record to be added to the array $skus.
case 'skuLookup':
$sql = "SELECT i.id, i.sku as parentSku, i.description as parentDescription, sku.item_sku as sku, sku.description FROM sku LEFT JOIN sku_vendor_pivot AS vp ON sku.id = vp.sku_vendor_fk LEFT JOIN sku_internal AS i ON i.id = vp.sku_fk WHERE i.sku LIKE '" . $dbh->escape($call['id']) . "%' AND i.id is not null";
$sql .= " UNION ";
$sql .= "SELECT i.id, i.sku as parentSku, i.description as parentDescription, sku.item_sku as sku, sku.description FROM sku LEFT JOIN sku_vendor_pivot AS vp ON sku.id = vp.sku_vendor_fk LEFT JOIN sku_internal AS i ON i.id = vp.sku_fk WHERE sku.item_sku LIKE '" . $dbh->escape($call['id']) . "%' AND i.id is not null";
if(is_numeric($call['id'])) {
$sql = "SELECT i.id, i.sku as parentSku, i.description as parentDescription, sku.item_sku as sku, sku.description FROM sku LEFT JOIN sku_vendor_pivot AS vp ON sku.id = vp.sku_vendor_fk LEFT JOIN sku_internal AS i ON i.id = vp.sku_fk WHERE i.id = " . $dbh->escape($call['id']) . " AND i.id is not null";
}
$skus = array();
if($dbh->query($sql)) {
$parent = null;
$children = array();
$count = 0;
while($dbh->next_record()) {
$count++;
if($parent == null) {
$parent = $dbh->Record['id'];
}
if($parent != $dbh->Record['id']) {
$sku['children'] = $children;
$skus[] = $sku;
$parent = $dbh->Record['id'];
$children = array();
}
$sku = array(
'description' => $dbh->Record['parentDescription'],
'value' => $dbh->Record['parentSku'],
);
$children[] = $dbh->Record['sku'] . " - " . $dbh->Record['description'];
}
if($count == 1) {
$sku['children'] = $children;
$skus[] = $sku;
}
}
$newData['skuLookup']['data'] = $skus;
error_log("newData['skuLookup']['data'] data:\n" . print_r($newData['skuLookup']['data'], TRUE));
$data = array_merge($data,$newData);
break;
In the loop, the code sets up $sku and appends an element to the $children array:
while($dbh->next_record()) {
$count++;
// ...
$sku = [ ... ];
$children[] = $dbh->Record['sku'] ...;
}
But on the last iteration, those variables are only used if count == 1, ie if there was only 1 record at all:
if($count == 1) {
$sku['children'] = $children;
$skus[] = $sku;
}
If I am understanding correctly, it looks like maybe those values are normally used on the next iteration, inside the if($parent != $dbh->Record['id']) { test. But that won't happen for any values set up on the last record.

How to add a new column for the action button for details with ajax in Codeigniter

How do you add columns to an action button such as the detail button in AJAX? This is my code:
Controller:
public function ajax_list()
{
$list = $this->th_ajaran->get_datatables();
$data = array();
$no = $_POST['start'];
$tools = $_POST['start'];
foreach ($list as $th_ajaran) {
$no++;
$row = array();
$row[] = $no;
$row[] = $th_ajaran->nama_kelas;
$row[] = $th_ajaran->jurusan;
$data[] = $row;
}
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->th_ajaran->count_all(),
"recordsFiltered" => $this->th_ajaran->count_filtered(),
"data" => $data,
);
//output to json format
echo json_encode($output);
}
This is My Model
<?php
class Th_Ajaran_kelas_model extends CI_Model {
var $table = 'th_ajaran';
var $column_order = array(null, 'nama_kelas','jurusan'); //set column field database for datatable orderable
var $column_search = array('nama_kelas','jurusan'); //set column field database for datatable searchable
var $order = array('th_ajaran' => 'asc'); // default order
private function _get_datatables_query()
{
//add custom filter here
if($this->input->post('th_ajaran'))
{
$this->db->where('th_ajaran', $this->input->post('th_ajaran'));
}
if($this->input->post('nama_kelas'))
{
$this->db->like('nama_kelas', $this->input->post('nama_kelas'));
}
if($this->input->post('jurusan'))
{
$this->db->like('jurusan', $this->input->post('jurusan'));
}
$this->db->from($this->table);
$this->db->join('th_ajaran_kelas', 'th_ajaran_kelas.id_th_ajaran = th_ajaran.id_th_ajaran');
$this->db->join('kelas', 'th_ajaran_kelas.id_kelas = kelas.id_kelas');
$i = 0;
foreach ($this->column_search as $item) // loop column
{
if($_POST['search']['value']) // if datatable send POST for search
{
if($i===0) // first loop
{
$this->db->group_start(); // open bracket. query Where with OR clause better with bracket. because maybe can combine with other WHERE with AND.
$this->db->like($item, $_POST['search']['value']);
}
else
{
$this->db->or_like($item, $_POST['search']['value']);
}
if(count($this->column_search) - 1 == $i) //last loop
$this->db->group_end(); //close bracket
}
$i++;
}
if(isset($_POST['order'])) // here order processing
{
$this->db->order_by($this->column_order[$_POST['order']['0']['column']], $_POST['order']['0']['dir']);
}
else if(isset($this->order))
{
$order = $this->order;
$this->db->order_by(key($order), $order[key($order)]);
}
}
public function get_datatables()
{
$this->_get_datatables_query();
if($_POST['length'] != -1)
$this->db->limit($_POST['length'], $_POST['start']);
$query = $this->db->get();
return $query->result();
}
Javascript
var table;
$(document).ready(function() {
//datatables
table = $('#table').DataTable({
"processing": true, //Feature control the processing indicator.
"serverSide": true, //Feature control DataTables' server-side processing mode.
"order": [], //Initial no order.
// Load data for the table's content from an Ajax source
"ajax": {
"url": "",
"type": "POST",
"data": function ( data ) {
data.th_ajaran = $('#th_ajaran').val();
}
},
//Set column definition initialisation properties.
"columnDefs": [
{
"targets": [ 0 ], //first column / numbering column
"orderable": false, //set not orderable
},
],
});
$('#btn-filter').click(function(){ //button filter event click
table.ajax.reload(); //just reload table
});
$('#btn-reset').click(function(){ //button reset event click
$('#form-filter')[0].reset();
table.ajax.reload(); //just reload table
});
});

How to Iterate through Object in JavaScript and PHP

I am having to solve a problem involving code in both JS and PHP. For some reason, whenever this code executes, it puts the first entry in all the rows of the table instead of iterating through each entry and putting all of them in the rows. I would appreciate someone's help in giving me insights into how to fix this issue. Can this be fixed with just a "for in" loop? Thanks in advance.
<?php include('../../functions.php');
$query = "
SELECT
*
FROM
plobby
LEFT JOIN users ON users.UID = plobby.UID
WHERE
`LID` = '". preg_replace("/[^A-Za-z0-9 ]/", '', $_POST['id']) ."';
";
$sql = "SELECT COUNT(`LID`) AS `x` FROM `snipe`.`plobby` WHERE LID = '".$_POST['id']."';";
$result = $db->query($query);
$rst = $db->query($sql);
$cnt = 0;
if($rst->num_rows > 0)
while($row = $rst->fetch_assoc())
$cnt = $row["x"];
if ($result->num_rows > 0)
for($i = 1;$i<= $cnt;$i++)
echo json_encode($result->fetch_assoc());
else
echo json_encode([]);
?>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here is the object to which the above loop is referring:
<script type="text/javascript">
var state = {};
for($i = 1;$i <= <?php echo getLobbytPlayers($_GET['id']);?>;$i++ ){
var reloadTable = function (data) {
if ($.data(state) == $.data(data)) {
return;
}
$('#js-lobby-table').empty();
$.each(data, function (rowNumber, rowData) {
var row = $('<tr>');
console.log(data);
// Player
row.append($('<td>', {
'html': data.eName
}));
// Status
row.append($('<td>', {
'html': data.gameID == "000" ? 'waiting' : 'ingame'
}));
// Win %
row.append($('<td>', {
'html': 'TODO'
}));
// Games
row.append($('<td>', {
'html': 'TODO'
}));
// K/D
row.append($('<td>', {
'html': 'TODO'
}));
$('#js-lobby-table').append(row);
});
// Set the current table state.
state = data;
};
}
setInterval(function () {
$.ajax({
type: 'POST',
url: '/lobby/api/table.php',
data: {
id: '<?= $_GET['id'] ?>'
},
success: reloadTable,
dataType: 'json'
});
}, 10);
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You shouldn't call json_encode() multiple times. The response has to contain a single JSON object, not multiple objects. You need to put all the results in an array, and call json_encode() on that array at the end.
There's also no need to get the count first. Just call fetch_assoc() until you get all the results.
<?php include('../../functions.php');
$query = "
SELECT
*
FROM
plobby
LEFT JOIN users ON users.UID = plobby.UID
WHERE
`LID` = '". preg_replace("/[^A-Za-z0-9 ]/", '', $_POST['id']) ."';
";
$result = $db->query($query);
$rows = [];
while ($row = $result->fetch_assoc()) {
$rows[] = $row;
}
echo json_encode($rows);
?>

jQuery show loading while generating excel report no ajax

I have a form which has a Date From and To Date selector then a generate button, upon clicking generate button, an excel file will be the output. Question how and where do I put the loading script in my code given I'm not using ajax but rather:
$("#btnReport1").click(function() {
var page = 'export-report1?from='+$("#fromDateAll").val()+'&to='+$("#toDateAll").val();
return window.location = page;
});
And my route
Route::get('export-report1', 'ReportController#exportReport1');
function
public function exportReport1()
{
$from = Input::get('from');
$to = Input::get('to');
$query = "SELECT id, phone FROM qcv.forms WHERE calldatetime >= '$from' AND calldatetime <= '$to' ORDER BY id ASC ;";
// $query = "SELECT a.id as form_id, a.phone, b.metrics_id, b.response, c.metrics_name, c.description, c.question
// FROM forms a
// INNER JOIN forms_responses b ON a.id = b.form_id
// INNER JOIN metrics c ON c.id = b.metrics_id LIMIT 10";
$phone = DB::connection('mysql')->select($query);
if(!empty($phone))
{
Excel::create('Laravel Excel', function($excel) use ($phone) {
return $excel->sheet('Excel sheet', function($sheet) use ($phone) {
$sheet->setOrientation('landscape');
$sheet->cell('A9', 'KEY QUALITY METRICS');
$sheet->cell('B9', 'DESCRIPTIONS');
$sheet->cell('C9', 'ASSESSMENT QUESTION');
$sheet->cells('A9:C9', function($cells) {
$cells->setFontWeight('bold');
$cells->setFontColor('#DF013A');
});
$metrics = Metric::all();
$metric_start = 10;
$start = "D";
$count = 10;
foreach ($phone as $key => $value2) // Populate Phone Numbers Horizontally
{
$sheet->cell($start.'9', $value2->phone);
// This will fill the responses for each number
foreach ($metrics as $key => $value)
{
$responses = FormResponses::where('form_id', '=', $value2->id)->where('metrics_id', '=', $value->id)->get();
$sheet->cell($start.$count, $responses[0]->response);
$sheet->cell('C'.$count, $value->question);
$sheet->cell('B'.$count, $value->description);
$sheet->cell('A'.$count, $value->metrics_name);
$count++;
}
$start++;
$count = 10;
}
});
})->export('xls');
}
else
{
return "No records found.";
}
}

How do I display multiple stacked columns for each date range in an stacked Bar

Essentially, the purpose is to compare what categories of tasks each member on my team is performing on a weekly basis.
and I would like to add number of Week underneath the Axes instead of 1.0 , 2.0 and 3.0 .
I am getting wrong result as its only showing 1 for excellent and for all week1, week2, week3, week4
I selected starting day 1/12/2014 and the end date is 31/12/2014 so I was expecting to have 1 for bad and two for good and three for excellent.
This is my PHP code
<?php>
$result = mysqli_query($con,"SELECT * FROM `employees` WHERE `Date` BETWEEN '" . $_POST
['start'] . "' AND '" . $_POST ['end'] . "' ") or die ("Error: ".mysqli_error($con));
$Levels = 0;
$Levelscounter=0;
$countergood=0;
$counterbad=0;
while($row = mysqli_fetch_array($result))
{
$answer = $row['level'];
$bad = 'bad';
$good='good';
$excellent='excellent';
if ($answer == $bad)
{
$counterbad++;
}
if($answer == $good)
{
$countergood++;
}
if($answer == $excellent)
{
$counterexcellent++;
}
$Levelscounter;
}
mysqli_close($con);
?>
Here is my JavaScript Code:
<script type="text/javascript">
(function($) {
var series = [{
data: [[ 1,<?php echo $counterbad; ?>] ],
valueLabels: {
show: true,
valign: 'middle'
} ,
label: "Low"
},
{
data: [[1,<?php echo $countergood; ?>]],
valueLabels: {
show: true,
valign: 'middle'
} ,
label: "Medium"
}, {
data: [[1,<?php echo $counterexcellent; ?>]],
valueLabels: {
show: true,
valign: 'middle'
} ,
label: "High"
}];
var options = {
xaxis: {
minTickSize: 1
},
series: {
bars: {
show: true,
barWidth: .8,
align: "center"
},
stack: true
}
};
$.plot("#placeholder", series, options);
})(jQuery);
</script>
I got the levels displayed in the stacked chart and it is working fine regarding from the start and end date I select but I could display this result as a weekly result.
I would like to get ideas what do I need to add ? Any ideas please ?
Is there a function in PHP that sort out this ?
Thank you.
Updating
As you can see in the image numbers on each series related to bad, good, excellent.
red for bad and good for blue and yellow for excellent.
To add weeks/textual data underneath the columns you have to add the library's categories file jquery.flot.categories.min.js to your javascript assets.
If i understand you correctly you want the chart to look like this
Javascript
You need to add these files in
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jquery.flot.min.js"></script>
<script src="jquery.flot.categories.min.js"></script>
<script src="jquery.flot.stack.min.js"></script>
and initialize the library we will talk about $output after this code
<div id="placeholder" style="width:818px;height:413px" ></div>
<script type="text/javascript">
$(function() {
var series = [<?php echo $output; ?>];
$.plot("#placeholder", series, {
series: {
stack:true,
lines:{fill:true,show:false,steps:false},
bars: {
show: true,
barWidth: 0.8,
align: "middle",
},
},
xaxis: {
mode: "categories",
minTickSize: 1
}
});
});
PHP
First you need to query the database to find the date between the specified dates, after getting the result you have to sort the data for each week in an array
For instance week One => 'good','good','bad','bad', 'week two' => and so on ...
after that you can use array_count_values() to count the number of occurrences and build
the charts column.
I simplified the code using functions to make it easier for you
<?php
$con = mysqli_connect("localhost", 'root','','your db');
function getChartData($con, $startDate, $endDate){
$startDate = date("Y-m-d H:i:s", strtotime($startDate));
$endDate = date("Y-m-d H:i:s", strtotime($endDate));
$query = "SELECT * FROM `employees` WHERE `date` BETWEEN '$startDate' AND '$endDate'";
$result = mysqli_query($con, $query) or die ("Error: ".mysqli_error($con));
// a multidimenional array containing each week with it's
$weeksData = [];
// Group each week with it's data
while($row = mysqli_fetch_array($result)){
$weekNumber = date("W", strtotime($row['date']));
if(isset($weeksData[$weekNumber]))
{
$weeksData[$weekNumber][] = $row['level'];
}
$weeksData[$weekNumber][] = $row['level'];
}
// reset array indexes and sort the array
sort($weeksData);
$data = array();
// using array_count_values to count the number of (good, bad and excellent)
foreach ($weeksData as $key => $week) {
$data[$key] = array_count_values($week);
}
// return all the weeks with number of (good, bad and excellent) occurences
return $data;
}
// build the javascript object {data:['week num', occuerences]}
function buildColumn($data,$label, $numberOfWeeks)
{
$data = array_column($data,strtolower($label));
$balance = $numberOfWeeks - count($data);
if($balance !=0){
for($i=1;$i<=$balance;$i++) {
$data[] = 1;
}
}
$string = '{data: [';
foreach ($data as $key => $value) {
$weekNumber = $key+1;
$string .= '["Week '.$weekNumber.'",'.$value.'],';
}
$string = rtrim($string, ',');
$string .= "],valueLabels: {show: true,valign: 'middle'},label: '$label'}";
return $string;
}
function getNumberofWeeks($startDate, $endDate){
$weeks = array();
$period = new DatePeriod(new DateTime($startDate),
DateInterval::createFromDateString('+1 day'),new DateTime($endDate)
);
foreach ( $period as $dt ) {
$weeks[] = $dt->format( 'W' );
}
return count(array_unique($weeks));
}
now you can easily use these functions like this
$numberOfWeeks = getNumberofWeeks($_POST['start'],$_POST['end']);
// get data of the last number of weeks
$chartData = getChartData($con, $_POST['start'],$_POST['end']);
// bulding columns data for each occurence
$badColumn = buildColumn($chartData,'Bad', $numberOfWeeks);
$goodColumn = buildColumn($chartData,'Good', $numberOfWeeks);
$excellentColumn = buildColumn($chartData,'Excellent', $numberOfWeeks);
// output {data: ...}, {data: ...},{data:....}
$output = "$excellentColumn , $goodColumn , $badColumn";
Full working Example
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jquery.flot.min.js"></script>
<script src="jquery.flot.categories.min.js"></script>
<script src="jquery.flot.stack.min.js"></script>
</head>
<body>
<?php
$con = mysqli_connect("localhost", 'root','','your db');
function getChartData($con, $startDate, $endDate){
$startDate = date("Y-m-d H:i:s", strtotime($startDate));
$endDate = date("Y-m-d H:i:s", strtotime($endDate));
$query = "SELECT * FROM `employees` WHERE `date` BETWEEN '$startDate' AND '$endDate'";
$result = mysqli_query($con, $query) or die ("Error: ".mysqli_error($con));
// a multidimenional array containing each week with it's
$weeksData = [];
// Group each week with it's data
while($row = mysqli_fetch_array($result)){
$weekNumber = date("W", strtotime($row['date']));
if(isset($weeksData[$weekNumber]))
{
$weeksData[$weekNumber][] = $row['level'];
}
$weeksData[$weekNumber][] = $row['level'];
}
// reset array indexes and sort the array
sort($weeksData);
$data = array();
// using array_count_values to count the number of (good, bad and excellent)
foreach ($weeksData as $key => $week) {
$data[$key] = array_count_values($week);
}
// return all the weeks with number of (good, bad and excellent) occurences
return $data;
}
// build the javascript object {data:['week num', occuerences]}
function buildColumn($data,$label, $numberOfWeeks)
{
$data = array_column($data,strtolower($label));
$balance = $numberOfWeeks - count($data);
if($balance !=0){
for($i=1;$i<=$balance;$i++) {
$data[] = 1;
}
}
$string = '{data: [';
foreach ($data as $key => $value) {
$weekNumber = $key+1;
$string .= '["Week '.$weekNumber.'",'.$value.'],';
}
$string = rtrim($string, ',');
$string .= "],valueLabels: {show: true,valign: 'middle'},label: '$label'}";
return $string;
}
function getNumberofWeeks($startDate, $endDate){
$weeks = array();
$period = new DatePeriod(new DateTime($startDate),
DateInterval::createFromDateString('+1 day'),new DateTime($endDate)
);
foreach ( $period as $dt ) {
$weeks[] = $dt->format( 'W' );
}
return count(array_unique($weeks));
}
// the number of weeks that you want to display in the chart
$numberOfWeeks = getNumberofWeeks($_POST['start'],$_POST['end']);
// get data of the last number of weeks
$chartData = getChartData($con, $_POST['start'],$_POST['end']);
// bulding columns data for each occurence
$badColumn = buildColumn($chartData,'Bad', $numberOfWeeks);
$goodColumn = buildColumn($chartData,'Good', $numberOfWeeks);
$excellentColumn = buildColumn($chartData,'Excellent', $numberOfWeeks);
// output {data: ...}, {data: ...},{data:....}
$output = "$excellentColumn , $goodColumn , $badColumn";
?>
<div id="placeholder" style="width:818px;height:413px" ></div>
<script type="text/javascript">
$(function() {
var series = [<?php echo $output; ?>];
$.plot("#placeholder", series, {
series: {
stack:true,
lines:{fill:true,show:false,steps:false},
bars: {
show: true,
barWidth: 0.8,
align: "middle",
},
},
xaxis: {
mode: "categories",
minTickSize: 1
}
});
});
</script>
</body>
</html>
Edit
Just replace these two functions to make it compatible with dd/mm/yyyy
function getChartData($con, $startDate, $endDate){
$startDate = explode('/', $startDate);
$startDate = $startDate[1] . '/' . $startDate[0] . '/' . $startDate[2];
$endDate = explode('/', $endDate);
$endDate = $endDate[1] . '/' . $endDate[0] . '/' . $endDate[2];
$startDate = date("Y-m-d H:i:s", strtotime($startDate));
$endDate = date("Y-m-d H:i:s", strtotime($endDate));
$query = "SELECT * FROM `employees` WHERE `date` BETWEEN '$startDate' AND '$endDate'";
$result = mysqli_query($con, $query) or die ("Error: ".mysqli_error($con));
// a multidimenional array containing each week with it's
$weeksData = [];
// Group each week with it's data
while($row = mysqli_fetch_array($result)){
$weekNumber = date("W", strtotime($row['date']));
if(isset($weeksData[$weekNumber]))
{
$weeksData[$weekNumber][] = $row['level'];
}
$weeksData[$weekNumber][] = $row['level'];
}
// reset array indexes and sort the array
sort($weeksData);
$data = array();
// using array_count_values to count the number of (good, bad and excellent)
foreach ($weeksData as $key => $week) {
$data[$key] = array_count_values($week);
}
// return all the weeks with number of (good, bad and excellent) occurences
return $data;
}
and
function getNumberofWeeks($startDate, $endDate){
$startDate = explode('/', $startDate);
$startDate = $startDate[1] . '/' . $startDate[0] . '/' . $startDate[2];
$endDate = explode('/', $endDate);
$endDate = $endDate[1] . '/' . $endDate[0] . '/' . $endDate[2];
$diff = strtotime($startDate, 0) - strtotime($endDate, 0);
return str_replace('-','', (int)floor($diff / 604800));
}

Categories