diff --git a/components/PageviewsChart.js b/components/PageviewsChart.js index 576e5997..36710154 100644 --- a/components/PageviewsChart.js +++ b/components/PageviewsChart.js @@ -1,9 +1,49 @@ -import React, { useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, useCallback } from 'react'; import ChartJS from 'chart.js'; +import { format } from 'date-fns'; +import styles from './PageviewsChart.module.css'; -export default function PageviewsChart({ data }) { +export default function PageviewsChart({ data, unit }) { const canvas = useRef(); const chart = useRef(); + const [tooltip, setTooltip] = useState({}); + + const renderLabel = useCallback( + (label, index, values) => { + const d = new Date(values[index].value); + switch (unit) { + case 'day': + if (data.pageviews.length > 7) { + return index % 2 !== 0 ? format(d, 'MMM d') : ''; + } + return format(d, 'EEE M/d'); + default: + return label; + } + }, + [unit, data], + ); + + const renderTooltip = model => { + const { caretX, caretY, opacity, title, body, labelColors } = model; + console.log(model); + + if (!opacity) { + setTooltip({ opacity }); + } else { + const [label, value] = body[0].lines[0].split(':'); + + setTooltip({ + top: caretY, + left: caretX, + opacity, + title: title[0], + value, + label, + labelColor: labelColors[0].backgroundColor, + }); + } + }; function draw() { if (!canvas.current) return; @@ -17,16 +57,16 @@ export default function PageviewsChart({ data }) { label: 'unique visitors', data: data.uniques, lineTension: 0, - backgroundColor: 'rgb(146, 86, 217, 0.2)', - borderColor: 'rgb(122, 66, 191, 0.3)', + backgroundColor: 'rgb(146, 86, 217, 0.4)', + borderColor: 'rgb(122, 66, 191, 0.4)', borderWidth: 1, }, { label: 'page views', data: data.pageviews, lineTension: 0, - backgroundColor: 'rgb(38, 128, 235, 0.2)', - borderColor: 'rgb(13, 102, 208, 0.3)', + backgroundColor: 'rgb(38, 128, 235, 0.4)', + borderColor: 'rgb(13, 102, 208, 0.4)', borderWidth: 1, }, ], @@ -36,7 +76,8 @@ export default function PageviewsChart({ data }) { duration: 300, }, tooltips: { - intersect: false, + enabled: false, + custom: renderTooltip, }, hover: { animationDuration: 0, @@ -46,16 +87,18 @@ export default function PageviewsChart({ data }) { { type: 'time', distribution: 'series', - offset: true, time: { - displayFormats: { - day: 'ddd M/DD', - }, - tooltipFormat: 'ddd M/DD hA', + unit, + tooltipFormat: 'ddd MMMM DD YYYY', + }, + ticks: { + callback: renderLabel, + maxRotation: 0, }, gridLines: { display: false, }, + offset: true, stacked: true, }, ], @@ -71,8 +114,16 @@ export default function PageviewsChart({ data }) { }, }); } else { - chart.current.data.datasets[0].data = data.uniques; - chart.current.data.datasets[1].data = data.pageviews; + const { + data: { datasets }, + options, + } = chart.current; + + datasets[0].data = data.uniques; + datasets[1].data = data.pageviews; + options.scales.xAxes[0].time.unit = unit; + options.scales.xAxes[0].ticks.callback = renderLabel; + chart.current.update(); } } @@ -84,8 +135,21 @@ export default function PageviewsChart({ data }) { }, [data]); return ( -
+
+
); } + +const Tootip = ({ top, left, opacity, title, value, label, labelColor }) => ( +
+
+
{title}
+
+
+ {value} {label} +
+
+
+); diff --git a/components/PageviewsChart.module.css b/components/PageviewsChart.module.css new file mode 100644 index 00000000..8e3636c9 --- /dev/null +++ b/components/PageviewsChart.module.css @@ -0,0 +1,56 @@ +.chart { + position: relative; +} + +.tooltip { + opacity: 0; + position: absolute; + pointer-events: none; +} + +.content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + color: #000; + text-shadow: -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, 1px 1px 0 #fff; + text-align: center; + width: 150px; + height: 50px; + transform: translate(-50%, -60px); +} + +.content:after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + background: #000; + opacity: 0.05; + border-radius: 10px; +} + +.title { + font-size: 12px; + font-weight: 600; +} + +.metric { + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; + font-weight: 600; +} + +.dot { + width: 10px; + height: 10px; + border-radius: 100%; + border: 1px solid #fff; + margin-right: 10px; +} diff --git a/components/WebsiteStats.js b/components/WebsiteStats.js index 24498743..0f3314a8 100644 --- a/components/WebsiteStats.js +++ b/components/WebsiteStats.js @@ -34,7 +34,7 @@ export default function WebsiteStats({ websiteId, startDate, endDate, unit }) { return (
- +
); }