Как отобразить несколько столбцов с накоплением для каждого диапазона дат в столбце с накоплением

По сути, цель состоит в том, чтобы сравнить, какие категории задач каждый член моей команды выполняет еженедельно.

и я хотел бы добавить номер недели под осями вместо 1.0, 2.0 и 3.0.

Я получаю неправильный результат, так как он показывает только 1 для отлично и для всех неделя 1, неделя 2, неделя 3, неделя 4.

Я выбрал начальный день 12.01.2014, а конечный день — 31.12.2014, поэтому я ожидал, что 1 будет плохим, два — хорошим и три — отличным.

изображение

Это мой PHP-код

<?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); 
        ?>

Вот мой код JavaScript:

       <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>

Я получил уровни, отображаемые на диаграмме с накоплением, и он отлично работает с начальной и конечной датами, которые я выбираю, но я мог отображать этот результат как еженедельный результат. Я хотел бы получить идеи, что мне нужно добавить? Любые идеи, пожалуйста? Есть ли в PHP функция, которая решает эту проблему?

Спасибо.

Обновление

Как вы можете видеть на изображении, цифры в каждой серии относятся к плохому, хорошему, отличному. красный — плохой, хороший — синий, желтый — отличный. введите здесь описание изображения


person Zina Dweeikat    schedule 12.12.2014    source источник
comment
Какую библиотеку jquery вы используете для диаграмм и хотите ли вы отображать данные за последние 3 недели? Неделя 1, неделя 2, неделя 3, например   -  person Hmmm    schedule 12.12.2014
comment
@CodingInsane Я хотел бы отображать неделю1, неделю2, неделю3, неделю4 под осью X, и каждая неделя будет иметь полосу с накоплением. Вот библиотекаjquery.flot.stack.js jquery.flot.valuelabels.js jquery.flot.js   -  person Zina Dweeikat    schedule 12.12.2014


Ответы (1)


Чтобы добавить данные weeks/textual под столбцами, вы должны добавить файл категорий библиотеки jquery.flot.categories.min.js в ваши активы javascript.

Если я вас правильно понял, вы хотите, чтобы диаграмма выглядела так

введите здесь описание изображения

Javascript

Вам нужно добавить эти файлы в

<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>

и инициализируйте библиотеку, о которой мы поговорим $output после этого кода

<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

Сначала вам нужно запросить базу данных, чтобы найти дату между указанными датами, после получения результата вы должны отсортировать данные за каждую неделю в массиве

Например week One => 'good','good','bad','bad', 'week two' => and so on ...

после этого вы можете использовать array_count_values() для подсчета количества вхождений и постройте столбец диаграмм.

Я упростил код, используя functions, чтобы вам было проще

<?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));
}  

теперь вы можете легко использовать эти функции, как это

$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";  

Полный рабочий пример

<!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> 

Редактировать

Просто замените эти две функции, чтобы сделать их совместимыми с 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;
}

а также

   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));
}
person Hmmm    schedule 12.12.2014
comment
@Codinglnsane У меня есть правильный код, но я не знаю, как его создать, нет идей - person Zina Dweeikat; 13.12.2014
comment
@ZinaDweeikat, я отредактирую свой ответ с небольшими изменениями, и он будет работать с вашим началом и концом $_POST, конечно, ваш код подходит для отображения одного столбца. но вы должны получить количество недель между двумя датами и сгруппировать эти недели с их появлением, а затем отобразить данные для каждой недели. это наверняка сложнее, чем ваш код с одним столбцом. - person Hmmm; 13.12.2014
comment
Вы скопировали javascript, как показано в ответе? если скопировать и попробовать. и какая версия php используется? убедитесь, что отчеты об ошибках включены. и в каком формате вы публикуете дату? mm/dd/yyyy или dd/mm/yyyy дайте мне точный формат, чтобы убедиться, что php обрабатывает его правильно - person Hmmm; 13.12.2014
comment
да, у меня проблема, я тестировал код с мм/дд/гггг, поэтому он не работает, я изменю формат в своем коде на дд/мм/гггг - person Hmmm; 13.12.2014
comment
@ZinaDweeikat см. раздел «Редактировать» в моем ответе, просто замените getChartData() и getNumereoWeeks, и все должно быть в порядке. - person Hmmm; 13.12.2014