PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.4.0
GiveWP – Donation Plugin and Fundraising Platform v4.4.0
4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / Admin / components / Charts / TimeSeriesChart.tsx
give / src / Admin / components / Charts Last commit date
TimeSeriesChart.tsx 1 year ago
TimeSeriesChart.tsx
137 lines
1 import React, {useEffect, useState} from 'react';
2 import Chart from 'react-apexcharts';
3 import {ApexOptions} from 'apexcharts';
4 import apiFetch from '@wordpress/api-fetch';
5
6 /**
7 * @since 4.4.0
8 */
9 type TimeSeriesChartProps = {
10 endpoint: string;
11 amountFormatter: Intl.NumberFormat;
12 title?: string;
13 };
14
15 /**
16 * @since 4.4.0
17 */
18 type Donation = {
19 createdAt: {
20 date: string;
21 };
22 amount: {
23 value: string;
24 };
25 };
26
27 /**
28 * @since 4.4.0
29 */
30 type DataPoint = {
31 x: string;
32 y: number;
33 };
34
35 /**
36 * @since 4.4.0
37 * Generates a range of dates around a target date for displaying a single donation graph.
38 */
39 const getCenteredGraphRange = (targetDate: string) => {
40 const result = [];
41 const date = new Date(targetDate);
42
43 for (let i = -3; i <= 3; i++) {
44 const currentDate = new Date(date);
45 currentDate.setDate(date.getDate() + i);
46 result.push(currentDate.toISOString().split('T')[0]);
47 }
48 return result;
49 };
50
51 /**
52 * @since 4.4.0
53 */
54 const normalizeData = (donations: Donation[]): DataPoint[] => {
55 const map = new Map<string, number>();
56
57 // Group donations by date with sum amounts - fill missing dates with 0.
58 donations.forEach((donation) => {
59 const date = donation.createdAt.date.split(' ')[0];
60 const amount = parseFloat(donation.amount.value);
61 map.set(date, (map.get(date) || 0) + amount);
62 });
63
64 // Set graph range & points for single donations.
65 if (map.size === 1) {
66 const donationDate = donations[0]?.createdAt.date.split(' ')[0];
67 const graphRange = getCenteredGraphRange(donationDate);
68
69 return graphRange.map((date) => ({
70 x: date,
71 y: map.get(date) || 0,
72 }));
73 }
74
75 // Convert to sorted array of data points.
76 return Array.from(map.entries())
77 .map(([date, amount]) => ({
78 x: date,
79 y: amount,
80 }))
81 .sort((a, b) => a.x.localeCompare(b.x));
82 };
83
84 /**
85 * @since 4.4.0
86 */
87 export default function TimeSeriesChart({endpoint, amountFormatter, title = ''}: TimeSeriesChartProps) {
88 const [series, setSeries] = useState([{name: title, data: []}]);
89
90 useEffect(() => {
91 apiFetch<Donation[]>({path: endpoint}).then((data) => {
92 const normalized = normalizeData(data);
93 setSeries([{name: title, data: normalized}]);
94 });
95 }, [endpoint]);
96
97 const options: ApexOptions = {
98 chart: {
99 type: 'area' as const,
100 toolbar: {show: false},
101 zoom: {enabled: false},
102 },
103 xaxis: {
104 type: 'datetime',
105 labels: {format: 'MMM dd, yyyy'},
106 },
107 yaxis: {
108 min: 0,
109 labels: {
110 formatter: (val) => amountFormatter.format(val),
111 },
112 },
113 dataLabels: {enabled: false},
114 stroke: {
115 curve: 'smooth',
116 width: 2,
117 colors: ['#60a1e2'],
118 },
119 fill: {
120 type: 'gradient',
121 gradient: {
122 shadeIntensity: 1,
123 opacityFrom: 0.3,
124 opacityTo: 0,
125 stops: [0, 100],
126 },
127 },
128 tooltip: {
129 x: {
130 format: 'MMM dd, yyyy',
131 },
132 },
133 };
134
135 return <Chart options={options} series={series} type="area" height="250" />;
136 }
137