问题
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.
回答1:
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));
}
来源:https://stackoverflow.com/questions/27443398/how-do-i-display-multiple-stacked-columns-for-each-date-range-in-an-stacked-bar