{formattedDate}
{" "}
{`${payload[1].value} visitors`}
{" "}
{`${payload[0].value} views`}
{" "}
{`${payload[2].value}% bounce rate`}
);
} else {
return null;
}
}
export default function TimeSeriesChart({
data,
intervalType,
}: TimeSeriesChartProps) {
function xAxisDateFormatter(date: string): string {
const dateObj = dateStringToLocalDateObj(date);
switch (intervalType) {
case "DAY":
return dateObj.toLocaleDateString("en-us", {
weekday: "short",
month: "short",
day: "numeric",
});
case "HOUR":
return dateObj.toLocaleTimeString("en-us", {
hour: "numeric",
minute: "numeric",
});
default:
throw new Error("Invalid interval type");
}
}
const yAxisCountTicks = useMemo(() => {
const MAX_TICKS_TO_SHOW = 4;
// get the max integer value of data views
const maxViews = Math.max(...data.map((item) => item.views));
// determine the magnitude of maxViews to set rounding
const magnitude = Math.floor(Math.log10(maxViews));
const roundTo = Math.pow(10, Math.max(0, magnitude - 1));
const numTicks = Math.min(MAX_TICKS_TO_SHOW, maxViews);
const ticks = [];
// calculate increment and round it up to the nearest roundTo
let increment = Math.floor(maxViews / numTicks);
increment = Math.ceil(increment / roundTo) * roundTo;
// skip 0 and go 1 further
for (let i = 1; i <= numTicks + 1; i++) {
const tick = i * increment;
ticks.push(tick);
}
return ticks;
}, [data]);
// omit first and last
const xAxisTicks = useMemo(
() => data.slice(1, -1).map((entry) => entry.date),
[data],
);
// chart doesn't really work no data points, so just bail out
if (data.length === 0) {
return null;
}
return (