【问题标题】:PHP Array with date/time and duration for highchart带有日期/时间和持续时间的 PHP 数组,用于 highchart
【发布时间】:2013-09-05 07:29:50
【问题描述】:

首先这里是我最终想要实现的 Fiddle:Fiddle

为此,我需要从三个不同的表中获取值:ok_part、reject 和 stoppage。

至于停止,表结构如下:

我图表的 x 轴是一个小时的间隔,第一个 x 轴始终是 8 小时前的时间,最后一个是从现在到下一个完整小时的时间。

我已经成功地将 ok_part 和拒绝数组用于 highchart。

class GraphCalc() {
  .....
  /* calculate time */
  function CalculateTime($diff, $form) {

    $new = new DateTime();
    $new->modify($diff);
    return $form != 0 ? $new->format('Y-m-d H:00') : $new->format('Y-m-d');
  }

  function GraphInterval() {

    $time = strtotime($this->CalculateTime('-8 hours', 1)); // calling function to get time 8 hours ago
    $now = strtotime(date('Y-m-d H:00'));

    /* looping through time (8 hours ago to now) */
    for ($i = $time, $j = $i + 3600; $i <= $now; $i += 3600, $j += 3600) {

        /* puts together array for x Axis */
        $this->xAxis_array[] =  "'".date('H:00', $i).' - '.date('H:00', $j)."'";

        /* queries to sum ok parts and rejects according to time */
        $ok_part_sum[] = MouldingPart::find(
            array(
                'select' => 'SUM(amount) as ok_qty', 
                'conditions' => array(
                    'moulding_product_id IN (?) AND date >= ? AND date <= ?', 
                    $this->product_id, 
                    date('Y-m-d H:00', $i), 
                    date('Y-m-d H:00', $j)
                )
            )
        )->ok_qty;
        $reject_part_sum[] = MouldingReject::find(
            array(
                'select' => 'SUM(amount) as reject_qty', 
                'conditions' => array(
                    'moulding_product_id IN (?) AND date >= ? AND date <= ?', 
                    $this->product_id, 
                    date('Y-m-d H:00', $i), 
                    date('Y-m-d H:00', $j)
                )
            )
        )->reject_qty;
    }

    /* looping through ok_part and reject arrays to add 0 where there's no value */
    for ($i = 0; $i < count($ok_part_sum); $i++) { 
        $this->chart_ok_array[] = $ok_part_sum[$i] == '' ? 0 : $ok_part_sum[$i];
        $this->chart_reject_array[] = $reject_part_sum[$i] == '' ? 0 : $reject_part_sum[$i];
    }
  }

  function xAxis() {
    /* return x Axis values */
    return implode(', ',$this->xAxis_array);
  }

  function yAxisValues() {
    /* put together arrays for highchart */
    $chart_data[] = "{data: [".implode(", ",$this->chart_ok_array)."], name: 'OK', color: '#89A54E'}";
    $chart_data[] = "{data: [".implode(", ",$this->chart_reject_array)."], name: 'PRAAGID', color: '#AA4643'}";


    return $chart_data;
  }
}

我希望获得有关停止数据的解决方案的帮助。 Stoppage 有两个日期需要考虑:start_date 和 end_date。根据 x 轴和停止日期,我需要计算持续时间。有时我可能会使用持续时间字段,但我认为避免它并直接计算它更容易。

这是我想通过停止来实现的示例:

假设 x 轴是 05:00 - 06:00,那么停工持续时间应该是 59 分钟,因为停工表中有一个条目,其 start_date 为 2013-09-05 05:01:00 和 end_date 2013-09-05 09:00:00,但我不能使用停工表值的结束日期,因为我需要使用 06:00 的 x 轴值。

我希望您了解我想要实现的目标,这真的很难解释。

停工表中的数据也可能有所不同。一小时内可能会有多次停工。假设 x 轴是 08:00 - 09:00,在表格中有三个停止:

开始日期:07:54 结束日期:08:15
开始日期:08:19 结束日期:08:38
开始日期:08:45 结束日期:09:47
所以 08:00 - 09:00 的持续时间应该是 49 分钟。

请帮我解决这个问题,我已经被这个问题困扰了好几天了。我试图尽可能地解释它,但我敢打赌它仍然令人困惑。

最后我想得到一个用于 highchart 的数组,就像我使用 ok_part 和拒绝一样。

【问题讨论】:

  • 是的,这有点令人困惑...您可以尝试为您想要的图表制作一张图片(或其他任何东西)?你总是希望酒吧是 100% 吗?您的问题是如何获得stoppage 系列的php 的数组?
  • 我不确定我是否理解。那么...您是否尝试按时间范围将一些数据组装到 bin 中,但您遇到了麻烦,因为停工表已经将一些数据收集到不同的 bin 中?
  • 我想您希望我们完成您的GraphInterval 功能?
  • @Brewal 想要的图表是我分享的小提琴。我认为如果酒吧一直是 100% 就可以了。是的,我的问题是如何获取stoppage系列的php数组。如果你能帮助我使用 GraphInterval 函数会很好:)
  • @alexg 我正在尝试完成图表,但我不知道如何将停止数据收集到数组中。

标签: php


【解决方案1】:

这个想法是使用TIMESTAMPDIFFend_datestart_date 相减:

$stoppage_part_sum[] = MouldingStoppage::find(
    array(
        'select' => 'SUM(
            ABS(TIMESTAMPDIFF(
                MINUTE,
                IF(end_date > \''.date('Y-m-d H:00', $j).'\', \''.date('Y-m-d H:00', $j).'\', end_date),
                IF(start_date < \''.date('Y-m-d H:00', $i).'\', \''.date('Y-m-d H:00', $i).'\', start_date)
            ))
        ) as stoppage_qty', 
        'conditions' => array(
            'moulding_product_id IN (?) AND end_date >= ? AND start_date <= ?', 
            $this->product_id, 
            date('Y-m-d H:00', $i), 
            date('Y-m-d H:00', $j)
        )
    )
)->stoppage_qty;

IF(end_date &gt; ...)IF(start_date &lt; ...) 仅将时间带入当前窗口。然后它将使用它:

start_date: 08:00 end_date: 08:15
start_date: 08:19 end_date: 08:38
start_date: 08:45 end_date: 09:00

那么你只需 TIMESTAMPDIFF end_datestart_dateSUM 他们。

注意匹配相关“停止”的条件。 (start_date j 和 end_date > i

The demo sqlFiddle

尝试更改数据中的日期以查看结果。

【讨论】:

  • 谢谢,我试试看。
  • 非常感谢,工作就像一个魅力。我实在是太感谢你了。
  • 代码中有一个小错字,我比较了sqlFiddle和你这里给出的代码。在第二个 IF 语句中 IF(start_date
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
  • 2012-01-09
  • 2011-01-31
相关资源
最近更新 更多