如何在堆叠栏中为每个日期范围显示多个堆叠列

Posted

技术标签:

【中文标题】如何在堆叠栏中为每个日期范围显示多个堆叠列【英文标题】:How do I display multiple stacked columns for each date range in an stacked Bar 【发布时间】:2014-12-12 12:10:15 【问题描述】:

本质上,目的是比较我团队中每个成员每周执行的任务类别。

我想在轴下方添加周数,而不是 1.0 、 2.0 和 3.0 。

我得到了错误的结果,因为它只显示 1 表示优秀,并且在第 1 周、第 2 周、第 3 周、第 4 周都显示为 1

我选择从 2014 年 1 月 12 日开始,结束日期是 2014 年 12 月 31 日,所以我预计 1 表示差,2 表示好,3 表示优。

这是我的 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中有一个函数可以解决这个问题吗?

谢谢。

更新

正如您在每个系列的图片编号中看到的,与坏、好、优秀相关。 红色代表不好,蓝色代表好,黄色代表优秀。

【问题讨论】:

你用什么 jquery 库来做图表,你想显示过去 3 周的数据吗?例如第 1 周、第 2 周、第 3 周 @CodingInsane 我想在 x 轴下方显示第 1 周、第 2 周、第 3 周、第 4 周,并且每周都会有一个堆积条。这里是库 jquery.flot.stack.js jquery.flot.valuelabels .js jquery.flot.js 【参考方案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 =&gt; 'good','good','bad','bad', 'week two' =&gt; 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));

【讨论】:

@Codinglnsane 我有正确的代码,但我不知道如何构建它没有想法 @ZinaDweeikat 我将编辑我的答案,只需进行一些小改动,它将适用于您的 $_POST 开始和结束,当然您的代码对于显示一列是正确的。但是您必须获取两个日期之间的周数,并将这些周与它们的出现分组,然后显示每周的数据。这肯定比你的一列代码更复杂。 您是否复制了答案中显示的javascript?如果复制它并尝试它。什么 php 版本正在使用?确保启用错误报告。您以什么格式发布日期? mm/dd/yyyy 或 dd/mm/yyyy 给我确切的格式,以确保 php 正确处理它 是的,我遇到了问题,我用 mm/dd/yyyy 测试了代码,这就是为什么它不起作用我将代码中的格式更改为 dd/mm/yyyy @ZinaDweeikat 请参阅我回答中的编辑部分,只需替换 getChartData()getNumereoWeeks 就可以了

以上是关于如何在堆叠栏中为每个日期范围显示多个堆叠列的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中为具有多个索引的数据框制作堆叠图?

如何在单次访问报告中将 3 个连续行放入 3 个堆叠行中

在Highcharts中为堆叠列图中的列禁用堆栈标签

在 Telerik GridDateTimeColumn 中垂直堆叠日期范围过滤器

更改片段后如何取消显示堆叠的吐司?

Flutter 中的索引堆叠。如何在所有其他小部件之上显示容器?