Forked from breadthe/app%Http%Livewire%Stats%DistanceByYear.php
Created
March 18, 2022 20:56
-
-
Save dave-alvarez/5f3065409d0ceb4d5faa267046b016ee to your computer and use it in GitHub Desktop.
Laravel Livewire + Apexcharts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Livewire\Stats; | |
use Illuminate\Support\Facades\DB; | |
use Livewire\Component; | |
class DistanceByYear extends Component | |
{ | |
public $chartId; | |
public $athlete; | |
public $years; | |
public $distances; | |
public $total; | |
// Filters | |
public $bike; // aka bike_id; looks cleaner in the query string | |
public function render() | |
{ | |
$distancesByYear = $this->getDistancesByYear(); | |
$this->years = $distancesByYear->pluck('year'); | |
$this->distances = $distancesByYear | |
->pluck('total_distance') | |
->map(function ($distance) { | |
return session()->get('unit') === 'feet' | |
? metersToMiles($distance) | |
: metersToKm($distance); | |
}); | |
$this->total = $this->distances->sum(); | |
$this->emit("refreshChartData-{$this->chartId}", [ | |
'seriesData' => $this->distances, | |
'categories' => $this->years, | |
'seriesName' => 'Total distance this year', | |
]); | |
return view('livewire.stats.distance-by-year'); | |
} | |
public function resetFilter($filter) | |
{ | |
$this->{$filter} = null; | |
} | |
private function getDistancesByYear() | |
{ | |
$query = DB::table('activities') | |
->select( | |
DB::raw('YEAR(start_date_local) AS year'), | |
DB::raw('SUM(distance) AS total_distance'), | |
) | |
->where(['athlete_id' => $this->athlete->id]); | |
if ($this->bike > 0) { | |
$query->where('bike_id', $this->bike); | |
} | |
return $query | |
->groupByRaw('YEAR(start_date_local)') | |
->get(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\View\Components; | |
use Illuminate\View\Component; | |
class ApexCharts extends Component | |
{ | |
public string $chartId; | |
public $seriesData; | |
public $categories; | |
public $seriesName; | |
public function __construct($chartId, $seriesData, $categories, $seriesName = '') | |
{ | |
$this->chartId = $chartId; | |
$this->seriesData = $seriesData; | |
$this->categories = $categories; | |
$this->seriesName = $seriesName ?? 'Series'; | |
} | |
public function render() | |
{ | |
return view('components.apex-charts'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="{!! $chartId !!}"></div> | |
@push('scripts') | |
<script> | |
(function () { | |
const options = { | |
chart: { | |
id: `{!! $chartId !!}`, | |
type: 'bar' | |
}, | |
plotOptions: { | |
bar: { | |
barHeight: '100%', | |
distributed: true, | |
dataLabels: { | |
// position: 'bottom' | |
}, | |
} | |
}, | |
xaxis: { | |
type: 'category', | |
categories: {!! $categories !!} | |
}, | |
series: [{ | |
name: `{!! $seriesName !!}`, | |
data: {!! $seriesData !!} | |
}], | |
// colors: ['#5c6ac4', '#007ace'], | |
} | |
const chart = new ApexCharts(document.getElementById(`{!! $chartId !!}`), options); | |
chart.render(); | |
document.addEventListener('livewire:load', () => { | |
@this.on(`refreshChartData-{!! $chartId !!}`, (chartData) => { | |
chart.updateOptions({ | |
xaxis: { | |
categories: chartData.categories | |
} | |
}); | |
chart.updateSeries([{ | |
data: chartData.seriesData, | |
name: chartData.seriesName, | |
}]); | |
}); | |
}); | |
}()); | |
</script> | |
@endpush |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="w-full"> | |
<div class="bg-white shadow-2xl rounded"> | |
<x-section-header> | |
Distance By Year | |
<x-slot name="content"> | |
<span class="text-xl font-normal"> | |
{{$total}} @include('partials.unit._distance') | |
</span> | |
</x-slot> | |
</x-section-header> | |
<section class="p-2"> | |
<!-- Filters --> | |
<!-- Bike --> | |
<div class="flex flex-col"> | |
<label for="bike" class="flex flex-col w-1/4 font-medium text-xs text-black tracking-tight uppercase"> | |
Bike | |
</label> | |
<div class="flex"> | |
<select name="bike" id="bike" class="border px-2 py-1 rounded shadow-inner text-sm" wire:model="bike"> | |
<option>All</option> | |
@foreach($athlete->bikes as $bikeFilter) | |
<option value="{{ $bikeFilter->id }}">{{ $bikeFilter->name }}</option> | |
@endforeach | |
</select> | |
@if(!empty($bike) && $bike !== 'All') | |
<button wire:click="resetFilter('bike')" class="px-2 text-xl" title="Remove Bike filter"> | |
<x-icon icon="teenyicons-x" width=15 height=15 viewBox="15 15" strokeWidth=1 /> | |
</button> | |
@endif | |
</div> | |
</div> | |
<x-apex-charts :chart-id="$chartId" :series-data="$distances" :categories="$years" series-name="Total distance this year"/> | |
</section> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@extends('layouts.connected') | |
@section('connected-content') | |
<div class="grid grid-cols-none xl:grid-cols-2 gap-4 w-full"> | |
<livewire:stats.distance-by-year :athlete="$athlete" chart-id="distance-by-year" key="distance-by-year"/> | |
<livewire:stats.distance-by-month :athlete="$athlete" chart-id="distance-by-month" key="distance-by-month"/> | |
</div> | |
@endsection | |
@prepend('scripts') | |
{{-- Push ApexCharts to the top of the scripts stack --}} | |
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script> | |
@endprepend |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment