diff --git a/app/components/BarChart.client.tsx b/app/components/BarChart.client.tsx
index ac3a85e..95c3655 100644
--- a/app/components/BarChart.client.tsx
+++ b/app/components/BarChart.client.tsx
@@ -26,7 +26,7 @@ export default function BarChart({
setSeries([
{
- name: "Page Views",
+ name: "Views",
data: displayData.map(({ count, label }) => ({ x: label, y: count })),
},
]);
@@ -87,7 +87,6 @@ export default function BarChart({
},
},
xaxis: {
- categories: displayData.map(({ label }) => label),
axisBorder: {
show: true,
color: "#1e293b",
diff --git a/app/components/BrushChart.client.tsx b/app/components/BrushChart.client.tsx
deleted file mode 100644
index 6c30068..0000000
--- a/app/components/BrushChart.client.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-/* eslint-disable @typescript-eslint/ban-ts-comment */
-
-import ReactApexChart from "react-apexcharts";
-
-type Props = {
- data: number[][];
-};
-
-export default function BrushChart({ data }: Props) {
- const range = Math.min(
- 7 * 24 * 60 * 60 * 1000,
- data[data.length - 1][0] - data[0][0]
- );
-
- const options = {
- chart: {
- id: "chart2",
- type: "line",
- height: 230,
- offsetX: -10,
- offsetY: 0,
- toolbar: {
- show: true,
- autoSelected: "selection",
- tools: {
- download: true,
- selection: true,
- zoom: true,
- zoomin: true,
- zoomout: true,
- pan: false,
- reset: false,
- },
- },
- events: {
- mounted: function (
- _: never,
- { config }: { config: { xaxis: { range: number | undefined } } }
- ) {
- config.xaxis.range = undefined;
- },
- },
- },
- colors: ["#64748b"],
- fill: {
- opacity: 1,
- },
- stroke: {
- width: 3,
- curve: "smooth",
- colors: ["#64748b"],
- },
- grid: {
- show: false,
- },
- dataLabels: {
- enabled: false,
- },
- markers: {
- size: 0,
- },
- plotOptions: {
- area: {
- fillTo: "origin",
- },
- },
- tooltip: {
- x: {
- format: "dd MMM yyyy",
- },
- },
- xaxis: {
- type: "datetime",
- labels: {
- datetimeFormatter: {
- year: "yyyy",
- month: "MMM 'yy",
- day: "dd MMM 'yy",
- hour: "",
- },
- },
- axisBorder: {
- show: true,
- color: "#1e293b",
- },
- axisTicks: {
- show: false,
- },
- range,
- },
- yaxis: {
- min: 0,
- max: Math.max(...data.map((d) => d[1])) + 1,
- forceNiceScale: true,
- labels: {
- formatter(val: number) {
- return Math.round(val);
- },
- },
- axisBorder: {
- show: true,
- color: "#1e293b",
- },
- axisTicks: {
- show: false,
- },
- tickAmount: 4,
- },
- };
-
- const optionsLine = {
- chart: {
- id: "chart1",
- height: 130,
- type: "area",
- brush: {
- target: "chart2",
- enabled: true,
- },
- selection: {
- enabled: true,
- fill: {
- color: "transparent",
- opacity: 0.1,
- },
- stroke: {
- width: 1,
- dashArray: 3,
- color: "#475569",
- opacity: 0.4,
- },
- xaxis: {
- min: data[0][0],
- max: data[data.length - 1][0],
- },
- },
- },
- colors: ["#0284C7"],
- fill: {
- type: "gradient",
- gradient: {
- opacityFrom: 0.91,
- opacityTo: 0.1,
- },
- },
- xaxis: {
- type: "datetime",
- tooltip: {
- enabled: false,
- },
- labels: {
- formatter: function (_: never, timestamp: number) {
- const date = new Date(new Date(timestamp).setHours(0, 0, 0, 0));
- return date.toLocaleDateString(undefined, {
- year: "2-digit",
- month: "short",
- day: "numeric",
- });
- },
- },
- },
- yaxis: {
- show: false,
- },
- };
-
- const series = [
- {
- name: "Page Views",
- data: data,
- },
- ];
-
- return (
-
-
- {/* @ts-ignore */}
-
-
-
- {/* @ts-ignore */}
-
-
-
- );
-}
diff --git a/app/components/TimeSeriesChart.client.tsx b/app/components/TimeSeriesChart.client.tsx
new file mode 100644
index 0000000..237dcce
--- /dev/null
+++ b/app/components/TimeSeriesChart.client.tsx
@@ -0,0 +1,118 @@
+import type { ApexOptions } from "apexcharts";
+import { useEffect, useState } from "react";
+import ReactApexChart from "react-apexcharts";
+import { DashboardElement } from "~/types/dashboard";
+
+type Props = {
+ data: Omit[];
+};
+
+export default function TimeSeriesChart({ data }: Props) {
+ const [series, setSeries] = useState([]);
+ const [options, setOptions] = useState({});
+
+ useEffect(() => {
+ const seriesData = data.map(({ count, label }) => [
+ new Date(label).getTime(),
+ count,
+ ]);
+
+ setSeries([
+ {
+ name: "Page Views",
+ data: seriesData,
+ },
+ ]);
+
+ setOptions({
+ chart: {
+ id: "chart2",
+ type: "line",
+ zoom: {
+ type: "x",
+ enabled: true,
+ autoScaleYaxis: true,
+ },
+ height: 230,
+ offsetX: -10,
+ offsetY: 0,
+ toolbar: {
+ show: true,
+ autoSelected: "selection",
+ },
+ },
+ colors: ["#64748b"],
+ fill: {
+ opacity: 1,
+ },
+ stroke: {
+ width: 3,
+ curve: "smooth",
+ colors: ["#64748b"],
+ },
+ grid: {
+ show: false,
+ },
+ dataLabels: {
+ enabled: false,
+ },
+ markers: {
+ size: 0,
+ },
+ plotOptions: {
+ area: {
+ fillTo: "origin",
+ },
+ },
+ xaxis: {
+ type: "datetime",
+ tickAmount: 8,
+ labels: {
+ formatter(val) {
+ return new Date(val).toLocaleDateString(undefined, {
+ year: "2-digit",
+ month: "short",
+ day: "numeric",
+ });
+ },
+ },
+ axisBorder: {
+ show: true,
+ color: "#1e293b",
+ },
+ axisTicks: {
+ show: false,
+ },
+ },
+ yaxis: {
+ min: 0,
+ max: Math.max(...seriesData.map((d) => d[1])) + 1,
+ forceNiceScale: true,
+ labels: {
+ formatter(val) {
+ return String(Math.round(val));
+ },
+ },
+ axisBorder: {
+ show: true,
+ color: "#1e293b",
+ },
+ axisTicks: {
+ show: false,
+ },
+ tickAmount: 4,
+ },
+ });
+ }, [data]);
+
+ return (
+
+
+
+ );
+}
diff --git a/app/routes/app/dashboard.$id.tsx b/app/routes/app/dashboard.$id.tsx
index 006511a..b64fc19 100644
--- a/app/routes/app/dashboard.$id.tsx
+++ b/app/routes/app/dashboard.$id.tsx
@@ -16,7 +16,7 @@ import classNames from "~/utils/class-names";
import { generateWebsiteColor, generateWebsiteInitials } from "~/utils/website";
import BarChart from "~/components/BarChart.client";
-// import BrushChart from "~/components/BrushChart.client";
+import TimeSeriesChart from "~/components/TimeSeriesChart.client";
import Button from "~/components/Button";
import H2 from "~/components/SectionHeader";
import LayoutGrid from "~/components/LayoutGrid";
@@ -30,7 +30,7 @@ type LoaderData = {
website: Website;
element: Path | Browser | Platform | Referrer | undefined;
paths: DashboardElement[];
- periods: DashboardElement[];
+ periods: Omit[];
browsers: DashboardElement[];
platforms: DashboardElement[];
referrers: DashboardElement[];
@@ -53,13 +53,12 @@ export const loader: LoaderFunction = async ({ request, params }) => {
const [periods, browsers, paths, platforms, referrers] = await Promise.all([
db.$queryRaw`
SELECT
- "Period"."id",
MAKE_DATE("Period"."year", "Period"."month", "Period"."day") as "label",
COUNT(*) as "count"
FROM "Event" INNER JOIN "Period" ON "Event"."periodId" = "Period"."id"
WHERE "Event"."websiteId" = ${website.id}
- GROUP BY 1, 2
- ORDER BY 2 ASC`,
+ GROUP BY 1
+ ORDER BY 1`,
db.$queryRaw`
SELECT
"Browser"."id",
@@ -159,14 +158,10 @@ export default function DashboardRoute() {
Page Views Chart
{isMounted ? (
- //
[
- // new Date(period.value).getTime(),
- // period.count,
- // ])}
- // />
-
+
) : (