UNPKG

@rsc-labs/medusa-store-analytics-v2

Version:
217 lines (216 loc) 9.95 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { Text, Container, Heading } from "@medusajs/ui"; import { calculateResolution, getChartDateName, getLegendName, compareDatesBasedOnResolutionType, ChartResolutionType, getChartTooltipDate } from "./utils/chartUtils.js"; import { AreaChart, CartesianGrid, XAxis, YAxis, Tooltip, Area, Legend } from "recharts"; import { useState, useEffect } from "react"; import { Box, Grid } from "@mui/material"; const incrementDate = (date, resolutionType) => { switch (resolutionType) { case ChartResolutionType.DayMonth: date.setDate(date.getDate() + 1); break; case ChartResolutionType.Month: date.setMonth(date.getMonth() + 1); break; default: date.setDate(date.getDate() + 1); } }; const generateChartData = (data, fromDate, toDate, chartResolutionType, toCompareDate, connectEmptyPointsUsingPreviousValue) => { const currentData = data.current; const previousData = data.previous; const startFromDate = new Date(fromDate); const offsetTime = toDate.getTime() - (toCompareDate ? toCompareDate.getTime() : fromDate.getTime()); const dataPoints = []; let currentDataValue; let previousDataValue; while (startFromDate.getTime() < toDate.getTime() || compareDatesBasedOnResolutionType(startFromDate, toDate, chartResolutionType)) { const currentOrder = currentData.find((order) => compareDatesBasedOnResolutionType(new Date(order.date), startFromDate, chartResolutionType)); const offsetDate = new Date(startFromDate); offsetDate.setTime(offsetDate.getTime() - offsetTime); const previousOrder = previousData.find((previous) => compareDatesBasedOnResolutionType(new Date(previous.date), offsetDate, chartResolutionType)); if (connectEmptyPointsUsingPreviousValue) { if (currentOrder) { currentDataValue = parseInt(currentOrder.value); } if (previousOrder) { previousDataValue = parseInt(previousOrder.value); } dataPoints.push({ current: { date: new Date(startFromDate), value: currentOrder ? parseInt(currentOrder.value) : currentDataValue ? currentDataValue : void 0 }, previous: { date: new Date(offsetDate), value: previousOrder ? parseInt(previousOrder.value) : previousDataValue ? previousDataValue : void 0 } }); } else { dataPoints.push({ current: { date: new Date(startFromDate), value: currentOrder ? parseInt(currentOrder.value) : 0 }, previous: { date: new Date(offsetDate), value: previousOrder ? parseInt(previousOrder.value) : 0 } }); } incrementDate(startFromDate, chartResolutionType); } if (connectEmptyPointsUsingPreviousValue) { for (let i = dataPoints.length - 1; i >= 0; i--) { if (dataPoints[i].current.value === void 0) { if (dataPoints[dataPoints.length - 1].previous.value) { dataPoints[i].current.value = dataPoints[dataPoints.length - 1].previous.value; } else { dataPoints[i].current.value = 0; } } if (dataPoints[i].previous.value) { previousDataValue = dataPoints[i].previous.value; } else { dataPoints[i].previous.value = previousDataValue; } } } return dataPoints; }; const ChartCustomTooltip = ({ active, payload, label, resolutionType }) => { if (active && payload && payload.length) { switch (resolutionType) { case ChartResolutionType.DayMonth: return /* @__PURE__ */ jsxs(Container, { children: [ /* @__PURE__ */ jsxs(Heading, { level: "h3", style: { color: payload[0].color }, children: [ `${getChartTooltipDate(payload[0].payload.current.date, resolutionType)}`, " : ", payload[0].payload.current.value ] }), payload[1] !== void 0 && /* @__PURE__ */ jsxs(Heading, { level: "h3", style: { color: payload[1].color }, children: [ `${getChartTooltipDate(payload[1].payload.previous.date, resolutionType)}`, " : ", payload[1].payload.previous.value ] }) ] }); case ChartResolutionType.Month: return /* @__PURE__ */ jsxs(Container, { children: [ /* @__PURE__ */ jsxs(Heading, { level: "h3", style: { color: payload[0].color }, children: [ `${getChartTooltipDate(payload[0].payload.current.date, resolutionType)}`, " : ", payload[0].payload.current.value ] }), payload[1] !== void 0 && /* @__PURE__ */ jsxs(Heading, { level: "h3", style: { color: payload[1].color }, children: [ `${getChartTooltipDate(payload[1].payload.previous.date, resolutionType)}`, " : ", payload[1].payload.previous.value ] }) ] }); } } return null; }; const areRangesTheSame = (fromDate, toDate, fromCompareDate, toCompareDate) => { function isToday(date) { const today = /* @__PURE__ */ new Date(); today.setHours(0, 0, 0, 0); const givenDate = new Date(date); givenDate.setHours(0, 0, 0, 0); return today.getTime() === givenDate.getTime(); } if (fromCompareDate) { const oneDay = 24 * 60 * 60 * 1e3; if (toCompareDate) { if (isToday(toDate)) { const diffBase3 = Math.ceil(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay)); const diffCompare3 = Math.round(Math.abs((toCompareDate.getTime() - fromCompareDate.getTime()) / oneDay)); return diffBase3 == diffCompare3; } const diffBase2 = Math.round(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay)); const diffCompare2 = Math.round(Math.abs((toCompareDate.getTime() - fromCompareDate.getTime()) / oneDay)); return diffBase2 == diffCompare2; } const diffBase = Math.ceil(Math.abs((toDate.getTime() - fromDate.getTime()) / oneDay)); const diffCompare = Math.ceil(Math.abs((Date.now() - fromCompareDate.getTime()) / oneDay)); return diffBase == diffCompare; } return true; }; const ChartCurrentPrevious = ({ rawChartData, fromDate, toDate, fromCompareDate, toCompareDate, compareEnabled, connectEmptyPointsUsingPreviousValue }) => { const [chartDataPoints, setChartData] = useState([]); const resolutionType = calculateResolution(fromDate, toDate); useEffect(() => { const chartDataPoints2 = generateChartData( rawChartData, fromDate, toDate, resolutionType, toCompareDate, connectEmptyPointsUsingPreviousValue ); setChartData(chartDataPoints2); }, [rawChartData, fromDate, toDate]); if (!areRangesTheSame(fromDate, toDate, fromCompareDate, toCompareDate)) { const currentPeriodInDays = Math.ceil((toDate.getTime() - fromDate.getTime()) / (24 * 60 * 60 * 1e3)); let precedingPeriodInDays = 0; if (fromCompareDate) { if (toCompareDate) { precedingPeriodInDays = Math.ceil((toCompareDate.getTime() - fromCompareDate.getTime()) / (24 * 60 * 60 * 1e3)); } else { precedingPeriodInDays = Math.ceil((new Date(Date.now()).getTime() - fromCompareDate.getTime()) / (24 * 60 * 60 * 1e3)); } } return /* @__PURE__ */ jsx( Box, { width: 500, height: 400, display: "flex", alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ jsxs(Grid, { container: true, direction: "column", justifyContent: "center", alignItems: "center", children: [ /* @__PURE__ */ jsx(Grid, { item: true, children: /* @__PURE__ */ jsx(Text, { children: "Chart can be shown only for the same length of ranges." }) }), /* @__PURE__ */ jsx(Grid, { item: true, children: /* @__PURE__ */ jsx(Text, { children: `You are comparing ${currentPeriodInDays} days to ${precedingPeriodInDays} days` }) }) ] }) } ); } return /* @__PURE__ */ jsxs( AreaChart, { width: 500, height: 400, data: chartDataPoints, margin: { top: 20, right: 0, left: 0, bottom: 0 }, children: [ /* @__PURE__ */ jsx(CartesianGrid, { strokeDasharray: "3 3" }), /* @__PURE__ */ jsxs("defs", { children: [ /* @__PURE__ */ jsxs("linearGradient", { id: "colorPrevious", x1: "0", y1: "0", x2: "0", y2: "1", children: [ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#8884d8", stopOpacity: 0.8 }), /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#8884d8", stopOpacity: 0 }) ] }), /* @__PURE__ */ jsxs("linearGradient", { id: "colorCurrent", x1: "0", y1: "0", x2: "0", y2: "1", children: [ /* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: "#82ca9d", stopOpacity: 0.8 }), /* @__PURE__ */ jsx("stop", { offset: "95%", stopColor: "#82ca9d", stopOpacity: 0 }) ] }) ] }), /* @__PURE__ */ jsx(XAxis, { dataKey: (value) => getChartDateName(value.current.date, resolutionType, fromDate, toDate), minTickGap: 15, interval: "preserveStartEnd" }), /* @__PURE__ */ jsx(YAxis, {}), /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(ChartCustomTooltip, { active: false, payload: [], label: "", resolutionType }) }), /* @__PURE__ */ jsx(Area, { name: compareEnabled && fromCompareDate ? getLegendName(true) : void 0, type: "monotone", dataKey: "current.value", stroke: "#82ca9d", fillOpacity: 1, fill: "url(#colorCurrent)" }), compareEnabled && fromCompareDate && /* @__PURE__ */ jsx(Area, { name: getLegendName(false), type: "monotone", dataKey: "previous.value", stroke: "#8884d8", fillOpacity: 1, fill: "url(#colorPrevious)" }), compareEnabled && fromCompareDate && /* @__PURE__ */ jsx(Legend, { verticalAlign: "bottom", height: 36, iconType: "circle" }) ] } ); }; export { ChartCurrentPrevious, ChartCustomTooltip };