Skip to content

Commit

Permalink
Reimplement bar charts
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonioVdlC committed Aug 6, 2023
1 parent 34cae96 commit 79bfafa
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 83 deletions.
165 changes: 86 additions & 79 deletions app/components/BarChart.client.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,121 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */

import { useState } from "react";
import { useEffect, useState } from "react";
import ReactApexChart from "react-apexcharts";
import { DashboardElement } from "~/types/dashboard";

import type { ApexOptions } from "apexcharts";

type Props = {
categories: string[];
data: number[];
elements: Array<{ id: string }>;
data: DashboardElement[];
limit?: number;
onClick?: (id: string) => void;
};

const VIEW_LIMIT = 5;
const VIEW_LIMIT = 4;

export default function BarChart({
categories,
data,
elements,
limit = VIEW_LIMIT,
onClick = () => null,
}: Props) {
const [viewAll, setViewAll] = useState(false);
const [series, setSeries] = useState<ApexOptions["series"]>([]);
const [options, setOptions] = useState<ApexOptions>({});

const options = {
chart: {
type: "bar",
height: 55 * (viewAll || data.length < limit ? data.length : limit) + 55,
offsetX: -25,
offsetY: -25,
toolbar: {
show: true,
offsetX: -30,
offsetY: -23,
useEffect(() => {
const displayData = viewAll ? data : data.slice(0, limit);

setSeries([
{
name: "Page Views",
data: displayData.map(({ count, label }) => ({ x: label, y: count })),
},
events: {
click(_: never, __: never, config: { dataPointIndex: number }) {
onClick(elements[config.dataPointIndex].id);
]);

setOptions({
chart: {
type: "bar",
height:
55 *
(viewAll || displayData.length < limit
? displayData.length
: limit) +
55,
offsetX: -25,
offsetY: -25,
toolbar: {
show: true,
offsetX: -30,
offsetY: -23,
},
},
},
plotOptions: {
bar: {
borderRadius: 4,
horizontal: true,
barHeight: "80%",
dataLabels: {
position: "bottom",
events: {
click(_: never, __: never, config: { dataPointIndex: number }) {
onClick(data[config.dataPointIndex].id);
},
},
},
},
dataLabels: {
enabled: true,
textAnchor: "start",
style: {
colors: ["#1e293b"],
fontWeight: 400,
},
formatter: function (_: any, opt: any) {
return opt.w.globals.labels[opt.dataPointIndex];
},
offsetX: 10,
dropShadow: {
enabled: false,
},
},
colors: ["#e2e8f0"],
tooltip: {
y: {
formatter(val: number) {
return Math.round(val);
plotOptions: {
bar: {
borderRadius: 4,
horizontal: true,
barHeight: "80%",
dataLabels: {
position: "bottom",
},
},
},
},
xaxis: {
categories,
axisBorder: {
show: true,
color: "#1e293b",
dataLabels: {
enabled: true,
textAnchor: "start",
style: {
colors: ["#1e293b"],
fontWeight: 400,
},
formatter: function (_: any, opt: any) {

Check warning on line 73 in app/components/BarChart.client.tsx

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 73 in app/components/BarChart.client.tsx

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
return opt.w.globals.labels[opt.dataPointIndex];
},
offsetX: 10,
dropShadow: {
enabled: false,
},
},
axisTicks: {
show: false,
colors: ["#e2e8f0"],
tooltip: {
y: {
formatter(val: number) {
return String(Math.round(val));
},
},
},
labels: {
formatter(val: number) {
return Math.round(val);
xaxis: {
categories: displayData.map(({ label }) => label),
axisBorder: {
show: true,
color: "#1e293b",
},
axisTicks: {
show: false,
},
labels: {
formatter(val: string) {
return String(Math.round(Number(val)));
},
},
},
},
yaxis: {
labels: {
show: false,
yaxis: {
labels: {
show: false,
},
},
},
};

const series = [
{
name: "Page Views",
data: viewAll ? data : data.slice(0, limit),
},
];
});
}, [viewAll, data, limit]);

return (
<div className="relative">
{/* @ts-ignore */}
<ReactApexChart
options={options}
series={series}
type={options.chart.type}
height={options.chart.height}
type={"bar"}
height={options.chart?.height || 350}
/>
{data.length > limit ? (
<div className="absolute right-[70px] top-[-20px] text-xs text-slate-500 hover:text-slate-400">
Expand Down
20 changes: 16 additions & 4 deletions app/routes/app/dashboard.$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ export default function DashboardRoute() {
<H2>Pages</H2>
<div className="mt-1 cursor-pointer">
{isMounted ? (
<BarChart dataKey="bar-pages" data={data.paths} />
<BarChart
key={`bar-pages-${data.website.id}`}
data={data.paths}
/>
) : (
<div className="flex flex-col items-center">
<Loading />
Expand All @@ -194,7 +197,10 @@ export default function DashboardRoute() {
<H2>Referrers</H2>
<div className="mt-1 cursor-pointer">
{isMounted ? (
<BarChart dataKey="bar-referrers" data={data.referrers} />
<BarChart
key={`bar-referrers-${data.website.id}`}
data={data.referrers}
/>
) : (
<div className="flex flex-col items-center">
<Loading />
Expand All @@ -206,7 +212,10 @@ export default function DashboardRoute() {
<H2>Browsers</H2>
<div className="mt-1 cursor-pointer">
{isMounted ? (
<BarChart dataKey="bar-browsers" data={data.browsers} />
<BarChart
key={`bar-browsers-${data.website.id}`}
data={data.browsers}
/>
) : (
<div className="flex flex-col items-center">
<Loading />
Expand All @@ -218,7 +227,10 @@ export default function DashboardRoute() {
<H2>Platforms</H2>
<div className="mt-1 cursor-pointer">
{isMounted ? (
<BarChart dataKey="bar-platforms" data={data.platforms} />
<BarChart
key={`bar-platforms-${data.website.id}`}
data={data.platforms}
/>
) : (
<div className="flex flex-col items-center">
<Loading />
Expand Down

0 comments on commit 79bfafa

Please sign in to comment.