<x-layouts.app title="Chart Line Interactive">
<div class="flex min-h-svh items-center justify-center p-6">
<div class="w-full max-w-2xl">
<x-ui.card class="py-4 sm:py-0"
x-data="{
active: 'desktop',
chart: null,
ready: false,
labels: { desktop: 'Desktop', mobile: 'Mobile' },
colors: { desktop: 'var(--chart-1)', mobile: 'var(--chart-2)' },
all: [{d:'2024-04-01',desktop:222,mobile:150},{d:'2024-04-02',desktop:97,mobile:180},{d:'2024-04-03',desktop:167,mobile:120},{d:'2024-04-04',desktop:242,mobile:260},{d:'2024-04-05',desktop:373,mobile:290},{d:'2024-04-06',desktop:301,mobile:340},{d:'2024-04-07',desktop:245,mobile:180},{d:'2024-04-08',desktop:409,mobile:320},{d:'2024-04-09',desktop:59,mobile:110},{d:'2024-04-10',desktop:261,mobile:190},{d:'2024-04-11',desktop:327,mobile:350},{d:'2024-04-12',desktop:292,mobile:210},{d:'2024-04-13',desktop:342,mobile:380},{d:'2024-04-14',desktop:137,mobile:220},{d:'2024-04-15',desktop:120,mobile:170},{d:'2024-04-16',desktop:138,mobile:190},{d:'2024-04-17',desktop:446,mobile:360},{d:'2024-04-18',desktop:364,mobile:410},{d:'2024-04-19',desktop:243,mobile:180},{d:'2024-04-20',desktop:89,mobile:150},{d:'2024-04-21',desktop:137,mobile:200},{d:'2024-04-22',desktop:224,mobile:170},{d:'2024-04-23',desktop:138,mobile:230},{d:'2024-04-24',desktop:387,mobile:290},{d:'2024-04-25',desktop:215,mobile:250},{d:'2024-04-26',desktop:75,mobile:130},{d:'2024-04-27',desktop:383,mobile:420},{d:'2024-04-28',desktop:122,mobile:180},{d:'2024-04-29',desktop:315,mobile:240},{d:'2024-04-30',desktop:454,mobile:380},{d:'2024-05-01',desktop:165,mobile:220},{d:'2024-05-02',desktop:293,mobile:310},{d:'2024-05-03',desktop:247,mobile:190},{d:'2024-05-04',desktop:385,mobile:420},{d:'2024-05-05',desktop:481,mobile:390},{d:'2024-05-06',desktop:498,mobile:520},{d:'2024-05-07',desktop:388,mobile:300},{d:'2024-05-08',desktop:149,mobile:210},{d:'2024-05-09',desktop:227,mobile:180},{d:'2024-05-10',desktop:293,mobile:330},{d:'2024-05-11',desktop:335,mobile:270},{d:'2024-05-12',desktop:197,mobile:240},{d:'2024-05-13',desktop:197,mobile:160},{d:'2024-05-14',desktop:448,mobile:490},{d:'2024-05-15',desktop:473,mobile:380},{d:'2024-05-16',desktop:338,mobile:400},{d:'2024-05-17',desktop:499,mobile:420},{d:'2024-05-18',desktop:315,mobile:350},{d:'2024-05-19',desktop:235,mobile:180},{d:'2024-05-20',desktop:177,mobile:230},{d:'2024-05-21',desktop:82,mobile:140},{d:'2024-05-22',desktop:81,mobile:120},{d:'2024-05-23',desktop:252,mobile:290},{d:'2024-05-24',desktop:294,mobile:220},{d:'2024-05-25',desktop:201,mobile:250},{d:'2024-05-26',desktop:213,mobile:170},{d:'2024-05-27',desktop:420,mobile:460},{d:'2024-05-28',desktop:233,mobile:190},{d:'2024-05-29',desktop:78,mobile:130},{d:'2024-05-30',desktop:340,mobile:280},{d:'2024-05-31',desktop:178,mobile:230},{d:'2024-06-01',desktop:178,mobile:200},{d:'2024-06-02',desktop:470,mobile:410},{d:'2024-06-03',desktop:103,mobile:160},{d:'2024-06-04',desktop:439,mobile:380},{d:'2024-06-05',desktop:88,mobile:140},{d:'2024-06-06',desktop:294,mobile:250},{d:'2024-06-07',desktop:323,mobile:370},{d:'2024-06-08',desktop:385,mobile:320},{d:'2024-06-09',desktop:438,mobile:480},{d:'2024-06-10',desktop:155,mobile:200},{d:'2024-06-11',desktop:92,mobile:150},{d:'2024-06-12',desktop:492,mobile:420},{d:'2024-06-13',desktop:81,mobile:130},{d:'2024-06-14',desktop:426,mobile:380},{d:'2024-06-15',desktop:307,mobile:350},{d:'2024-06-16',desktop:371,mobile:310},{d:'2024-06-17',desktop:475,mobile:520},{d:'2024-06-18',desktop:107,mobile:170},{d:'2024-06-19',desktop:341,mobile:290},{d:'2024-06-20',desktop:408,mobile:450},{d:'2024-06-21',desktop:169,mobile:210},{d:'2024-06-22',desktop:317,mobile:270},{d:'2024-06-23',desktop:480,mobile:530},{d:'2024-06-24',desktop:132,mobile:180},{d:'2024-06-25',desktop:141,mobile:190},{d:'2024-06-26',desktop:434,mobile:380},{d:'2024-06-27',desktop:448,mobile:490},{d:'2024-06-28',desktop:149,mobile:200},{d:'2024-06-29',desktop:103,mobile:160},{d:'2024-06-30',desktop:446,mobile:400}],
total() {
return {
desktop: this.all.reduce((a, p) => a + p.desktop, 0),
mobile: this.all.reduce((a, p) => a + p.mobile, 0),
};
},
series() {
return [{
name: this.labels[this.active],
data: this.all.map(p => ({ x: new Date(p.d).getTime(), y: p[this.active] })),
}];
},
options() {
return window.Chart.buildChartOptions({
type: 'line', height: 250, series: this.series(),
colors: [this.colors[this.active]],
options: {
stroke: { width: 2, curve: 'monotone' },
markers: { size: 0 },
xaxis: { type: 'datetime', labels: { datetimeUTC: false, format: 'MMM d' }, tickAmount: 6 },
yaxis: { show: false },
legend: { show: false },
tooltip: { x: { format: 'MMM dd, yyyy' } },
grid: { strokeDashArray: 4, yaxis: { lines: { show: true } }, xaxis: { lines: { show: false } } },
},
});
},
init() {
this.$nextTick(async () => {
const ApexCharts = await window.Chart.load(); this.chart = new ApexCharts(this.$refs.canvas, this.options());
await this.chart.render();
this.ready = true;
window.Chart.observeTheme(() => { if (this.chart && this.ready) try { this.chart.updateOptions(this.options(), false, false); } catch (e) {} });
});
},
setActive(k) {
this.active = k;
if (this.chart && this.ready) {
this.chart.updateOptions(this.options(), false, false);
this.chart.updateSeries(this.series(), true);
}
},
}">
<x-ui.card-header class="flex flex-col items-stretch border-b p-0! sm:flex-row">
<div class="flex flex-1 flex-col justify-center gap-1 px-6 pb-3 sm:pb-0">
<x-ui.card-title>Line Chart - Interactive</x-ui.card-title>
<x-ui.card-description>Showing total visitors for the last 3 months</x-ui.card-description>
</div>
<div class="flex">
@foreach (['desktop' => 'Desktop', 'mobile' => 'Mobile'] as $key => $label)
<button type="button" x-on:click="setActive('{{ $key }}')" ::data-active="active === '{{ $key }}'"
class="data-[active=true]:bg-muted/50 flex flex-1 flex-col justify-center gap-1 border-t px-6 py-4 text-left even:border-l sm:border-t-0 sm:border-l sm:px-8 sm:py-6">
<span class="text-muted-foreground text-xs">{{ $label }}</span>
<span class="text-lg leading-none font-bold sm:text-3xl" x-text="total().{{ $key }}.toLocaleString()"></span>
</button>
@endforeach
</div>
</x-ui.card-header>
<x-ui.card-content class="px-2 sm:p-6">
<div x-ref="canvas" class="aspect-auto h-[250px] w-full"></div>
</x-ui.card-content>
</x-ui.card>
</div>
</div>
</x-layouts.app>