Skip to content

Instantly share code, notes, and snippets.

@mithicher
Last active November 16, 2021 13:52
Show Gist options
  • Save mithicher/d6e416c5e087f4a0c66e282299479cf9 to your computer and use it in GitHub Desktop.
Save mithicher/d6e416c5e087f4a0c66e282299479cf9 to your computer and use it in GitHub Desktop.
PureCSS Horizontal Bar Chart Laravel Blade Component with AlpineJS and TailwindCSS
{{-- Usage
<x-purecss-horizontal-bar-chart
bar-chart-id="horizontalbar"
bar-color="bg-gradient-to-r from-indigo-300 to-purple-400"
:chart-data='[
[
"label" => "Team A",
"value" => 25,
],
[
"label" => "Team B",
"value" => 10,
],
[
"label" => "Team C",
"value" => 60,
],
[
"label" => "Team D",
"value" => 80,
],
[
"label" => "Team E",
"value" => 35,
],
[
"label" => "Team F",
"value" => 45,
],
[
"label" => "Team G",
"value" => 95,
],
]'
>
<x-slot name="columnData">
<div x-text="`${data.value} wins`"></div>
</x-slot>
<x-slot name="labelData">
<div class="text-right text-sm leading-none font-medium font-mono" x-text="`For ${data.label}`"></div>
</x-slot>
<x-slot name="tooltip">
<div class="bg-gray-800 shadow rounded-md p-1.5 text-white absolute mx-2 leading-none text-xs z-30 -mt-20" x-cloak x-text="`${data.label}: ${data.value} wins`"></div>
</x-slot>
</x-purecss-horizontal-bar-chart>
--}}
@props([
'barColor' => 'bg-blue-600 hover:bg-blue-400',
'barChartId' => md5(Str::random(8)),
'chartData' => []
])
<div x-data="{
chartId: '{{ $barChartId }}',
chartData: {{ collect($chartData) }},
get totalSumOfChartData() {
if (this.chartData.length > 0 || Object.keys(this.chartData).length > 0) {
return this.chartData.map(item => item.value).reduce((acc, value) => value + acc);
}
return 0;
}
}" x-cloak>
<div x-show="chartData.length > 0" class="flex w-full">
<!-- Bar Chart -->
<div class="flex-1">
<div class="relative flex flex-col space-y-4" id="{{ $barChartId }}">
<template x-for="(data, dataIndex) in chartData" :key="dataIndex">
<div class="relative w-full flex items-center h-10">
{{-- Labels --}}
<div class="absolute z-30 left-0 top-0 flex h-full px-4 items-center font-medium text-gray-700 text-sm leading-none md:relative md:text-right md:justify-end">
@isset($labelData)
{{ $labelData }}
@else
<div x-text="data.label" class="w-32"></div>
@endisset
</div>
<div class="relative h-full flex flex-1 w-full items-center">
{{-- Bar --}}
<div
class="bg-gray-100 relative transition ease-in duration-200 relative h-full flex-1 w-full"
x-on:mouseenter="document.getElementById(chartId + dataIndex).className = 'block w-full h-full'"
x-on:mouseleave="document.getElementById(chartId + dataIndex).className = 'hidden'">
<div
:style="`width: ${(data.value/totalSumOfChartData*100).toFixed(2)}%`"
class="transition ease-in duration-200 relative h-full {{ $barColor }}"
></div>
<!-- Tooltip -->
<div class="absolute inset-0 z-40 hidden" :id="chartId + dataIndex">
<div class="flex h-full w-full items-center justify-center">
@isset($tooltip)
{{ $tooltip }}
@else
<div class="bg-gray-800 shadow rounded-md p-1.5 text-white absolute mx-2 leading-none text-sm z-40 -mt-12">
<span x-text="`${data.label}: ${data.value}`"></span>
</div>
@endisset
</div>
</div>
</div>
<div class="pl-3 w-20 leading-none">
@isset($columnData)
{{ $columnData}}
@else
<div x-text="data.value" class="text-center text-gray-800 text-sm"></div>
@endisset
</div>
</div>
</div>
</template>
</div>
</div>
</div>
<div x-show="chartData.length === 0" class="flex w-full">
<div class="flex flex-1 h-full flex-col space-y-4">
<template x-for="i in 6">
<div class="flex flex-1 space-x-4 justify-around">
<div class="w-32">
<div class="h-10 bg-gray-200 ml-auto animate-pulse rounded" :style="`width: ${Math.floor((Math.random() * 100) + 1)}%`"></div>
</div>
<div class="flex-1 flex space-x-4">
<div class="h-10 relative w-full flex flex-1 h-full items-center bg-gray-100 rounded">
<div :style="`width: ${Math.floor((Math.random() * 100) + 1)}%`" class="rounded animate-pulse transition ease-in duration-200 relative h-full bg-gray-200"></div>
</div>
<div class="h-10 w-16 items-center">
<div class="animate-pulse transition ease-in duration-200 relative h-full bg-gray-200 rounded"></div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
@ralphjsmit
Copy link

Could you share a screenshot? Curious how it looks 👀

@mithicher
Copy link
Author

horizontal-bar-chart

@ralphjsmit
Copy link

Wow, that's neat! Great color palette👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment