Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

marcoplus's avatar

Laravel count the first three and for each hour

I am following a post, I managed to receive the response from the server with the code that I took and adapted but I don't understand why I only count the totals and they are not divided, I have to count the first three for each hour and say up, while all the others say down, every hour repeat the same operation, how could i do it?

$uptimeData = Ticket::where('created_at', '>=', '2023-01-01 00:00:00')
                        ->where('created_at', '<=', '2023-01-031 00:00:00')
                        ->orderBy('created_at', 'asc')
                        ->select('ticket_Id', 'created_at')
                        ->get();
        $intervals = \Carbon\CarbonInterval::hours(1)->toPeriod('2023-01-01 00:00:00', '2023-01-31 00:00:00');
        $uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) use ($intervals) {
            $date = Carbon::parse($item->created_at);
            foreach ($intervals as $key => $interval) {
                if ($date->hour == Carbon::parse($interval)->addHours(1)->hour) {
                $actualHour1 = Carbon::parse($interval)->hour;
                if (strlen($actualHour1) == 1) $actualHour1 = "0$actualHour1";
                return $date->format("Y-m-d $actualHour1:00:00");
                }
                else if ($date->hour == Carbon::parse($interval)->addHours(1)->hour) {
                $actualHour2 = Carbon::parse($interval)->subHours(1)->hour;
                if (strlen($actualHour2) == 1) $actualHour2 = "0$actualHour2";
                return $date->format("Y-m-d $actualHour2:00:00");
                }

            }
            return $date->format('Y-m-d H:00:00');
        });

        $uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
            $down = 0;
            $up = 0;
            $total = 0;
            $uptime = 0;
            $fill = '#1fc777';

            foreach($checksInPeriod as $key => $value){
                $total++;
                if(strtotime($value['ticket_Id']) == 'down') $down++;
                if(strtotime($value['ticket_Id']) == 'up') $up++;
            }

            $uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.',','));

            if ($uptime < 100) $fill = '#9deab8';
            if ($uptime < 99) $fill = '#fbaa49';
            if ($uptime < 98) $fill = '#e0465e';

            return [
                'total_ticket_Id' => $total,
                'down_ticket_Id' => $down,
                'up_ticket_Id' => $up,
                'uptime' => $uptime,
                'fill' => $fill
            ];
        });
Illuminate\Support\Collection {#3861 ▼ // app/Http/Controllers/TicketsController.php:112
  #items: array:492 [▶]
  #escapeWhenCastingToString: false
}
0 likes
19 replies
azimidev's avatar
azimidev
Best Answer
Level 55

It's a little hard to understand the error as it's not formatted correctly but I have modified your code a little bit so try this:

$uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
    $down = 0;
    $up = 0;
    $total = 0;
    $uptime = 0;
    $fill = '#1fc777';

	// You have an issue with your loop:
    foreach($checksInPeriod as $key => $value){
        $total++;
        if ($total <= 3) {
            $up++;
        } else {
            $down++;
        }
    }

    $uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.',','));

    if ($uptime < 100) $fill = '#9deab8';
    if ($uptime < 99) $fill = '#fbaa49';
    if ($uptime < 98) $fill = '#e0465e';

    return [
        'total_ticket_Id' => $total,
        'down_ticket_Id' => $down,
        'up_ticket_Id' => $up,
        'uptime' => $uptime,
        'fill' => $fill
    ];
});
1 like
marcoplus's avatar

@azimidev thanks for the support now it splits tickets the right way, I don't understand, however, why it doesn't apply the color I assigned, the lines remain colorless

tisuchi's avatar

@marcoplus I just optimise @azimidev code a bit. It might be a bit clean.

$uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
    $total = count($checksInPeriod);
    $down = $total > 3 ? $total - 3 : 0;
    $up = $total > 3 ? 3 : $total;
    $uptime = number_format(($up / $total) * 100, 2);
    $fill = $uptime >= 98 ? '#1fc777' : ($uptime >= 99 ? '#9deab8' : ($uptime >= 100 ? '#fbaa49' : '#e0465e'));

    return [
        'total_ticket_Id' => $total,
        'down_ticket_Id' => $down,
        'up_ticket_Id' => $up,
        'uptime' => $uptime,
        'fill' => $fill
    ];
});
1 like
marcoplus's avatar

@tisuchi If I don't enter your code I get the correct results when I enter it the results are incorrect depends on what? 715191 03/01/2023 5:51 715205 03/01/2023 6:21

    "2023-01-01 05:00:00" => array:5 [▼
      "total_ticket_Id" => 1
      "down_ticket_Id" => 0
      "up_ticket_Id" => 1
      "uptime" => 100.0
      "fill" => "#1fc777"
    ]

        $uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
            $down = 0;
            $up = 0;
            $total = 0;
            $uptime = 0;
            $fill = '#1fc777';
    "2023-01-01 05:00:00" => array:5 [▼
      "total_ticket_Id" => 2
      "down_ticket_Id" => 0
      "up_ticket_Id" => 2
      "uptime" => 100.0
      "fill" => "#1fc777"
    ]

        $uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
            $total = count($checksInPeriod);
            $down = $total > 3 ? $total - 3 : 0;
            $up = $total > 3 ? 3 : $total;
            $uptime = number_format(($up / $total) * 100, 2);
            $fill = $uptime >= 98 ? '#1fc777' : ($uptime >= 99 ? '#9deab8' : ($uptime >= 100 ? '#fbaa49' : '#e0465e'));
azimidev's avatar

have you used the $fill variable in your code to specify the color of the lines. Maybe you need to add additional code to display the color, or change the way the lines are being displayed in your code. Without more context, it's difficult to say exactly what is missing.

marcoplus's avatar

@azimidev i'm trying for now i'm displaying the down,up and totals correctly, i'm trying to display the ticket_id number and date, for now i'm not successful yet, and the color either. In the blade I have inserted this

                                        <thead>
                                            <tr>
                                                <th>
                                                    Ticket Total
                                                </th>
                                                <th>
                                                    Ticket UP
                                                </th>
                                                <th>
                                                    Ticket OUT
                                                </th>
                                                <th>
                                                    Time
                                                </th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            @foreach($uptimeDataTimeline as $ticket)
                                                <tr>
                                                    <td>
                                                        {{$ticket['total_ticket_Id']}}
                                                    </td>
                                                    <td>
                                                        {{ $ticket['up_ticket_Id'] }}
                                                    </td>
                                                    <td>
                                                        {{ $ticket['down_ticket_Id'] }}
                                                    </td>
                                                    <td>
                                                        {{ $ticket['uptime'] }}
                                                    </td>
                                                </tr>
                                            @endforeach
                                        </tbody>
azimidev's avatar

@marcoplus The issue is that you're only applying the color $fill to the array element and not actually using it to set the color of the rows in your table. To display the color for each row in the table, you'll need to add a CSS class to the element and set the background color based on the $fill value.

.bg-red {
  background-color: #e0465e;
}

.bg-yellow {
  background-color: #fbaa49;
}

.bg-green-light {
  background-color: #9deab8;
}

.bg-green {
  background-color: #1fc777;
}

And modify your HTML code to include the CSS class based on the value of $fill:

<tbody>
  @foreach($uptimeDataTimeline as $ticket)
    <tr class="{{ $ticket['fill'] }}">
      <td>{{$ticket['total_ticket_Id']}}</td>
      <td>{{ $ticket['up_ticket_Id'] }}</td>
      <td>{{ $ticket['down_ticket_Id'] }}</td>
      <td>{{ $ticket['uptime'] }}</td>
    </tr>
  @endforeach
</tbody>

how many best answers I should give you? ;)

1 like
marcoplus's avatar

@azimidev sorry I removed only because he wrote me solved but I haven't solved everything yet that's why I removed, then I put it back

marcoplus's avatar

@azimidev created the css file and inserted everything but nothing changes the color does not assign it, how can I do to display the ticket_id number and also the date? where do I enter to view them?

azimidev's avatar

@marcoplus Your initial question was solved, you've asked the following question, you can mark the best answers and create another thread with all your code.

Yorki's avatar

Either you change this to assign css classes (@azimidev posted) to $fill variable:

$uptimeDataTimeline = $uptimeDataTimeline->map(function($checksInPeriod, $key){
    $down = 0;
    $up = 0;
    $total = 0;
    $uptime = 0;
    $fill = 'bg-green';

    foreach ($checksInPeriod as $key => $value){
        $total++;
        if ($total <= 3) {
            $up++;
        } else {
            $down++;
        }
    }

    $uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.',','));

    if ($uptime < 100) $fill = 'bg-green-light';
    if ($uptime < 99) $fill = 'bg-yellow';
    if ($uptime < 98) $fill = 'bg-red';

    return [
        'total_ticket_Id' => $total,
        'down_ticket_Id' => $down,
        'up_ticket_Id' => $up,
        'uptime' => $uptime,
        'fill' => $fill
    ];
});

or use style instead of class attribute on tr element:

<tbody>
  @foreach($uptimeDataTimeline as $ticket)
    <tr style="background: {{ $ticket['fill'] }}">
      <td>{{$ticket['total_ticket_Id']}}</td>
      <td>{{ $ticket['up_ticket_Id'] }}</td>
      <td>{{ $ticket['down_ticket_Id'] }}</td>
      <td>{{ $ticket['uptime'] }}</td>
    </tr>
  @endforeach
</tbody>
1 like
marcoplus's avatar

How can I also display ticket_Id and created_at in table with count results?

Yorki's avatar

@marcoplus I'd recommend mark the correct reply and thread as solved and opening new one in which paste current code and the results you expect to prevent doing mess

1 like

Please or to participate in this conversation.