PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.0.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.0.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / src / admin / components / common / PerformanceChart.js

PerformanceChart.js in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.0.0, at src/admin/components/common/PerformanceChart.js

192 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Performance Chart Component
3 *
4 * Professional Chart.js implementation for Core Web Vitals and performance metrics
5 *
6 * @package ThinkRank
7 * @since 1.0.0
8 */
9
10 import { Line } from 'react-chartjs-2';
11
12 // Chart.js is loaded separately via charts.js entry point
13 // Components are registered globally by the charts bundle
14
15 /**
16 * Performance Chart Component
17 */
18 const PerformanceChart = ({
19 title,
20 data,
21 unit = '',
22 thresholds = {},
23 height = 300,
24 showArea = true,
25 color = '#0073aa'
26 }) => {
27 // Prepare chart data
28 const chartData = {
29 labels: data.map((_, index) => {
30 const daysAgo = data.length - 1 - index;
31 const date = new Date();
32 date.setDate(date.getDate() - daysAgo);
33 return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
34 }),
35 datasets: [
36 {
37 label: title,
38 data: data.map(point => point.value),
39 borderColor: color,
40 backgroundColor: showArea ? `${color}20` : 'transparent',
41 borderWidth: 2,
42 fill: showArea,
43 tension: 0.4,
44 pointBackgroundColor: color,
45 pointBorderColor: '#ffffff',
46 pointBorderWidth: 2,
47 pointRadius: 4,
48 pointHoverRadius: 6,
49 pointHoverBackgroundColor: color,
50 pointHoverBorderColor: '#ffffff',
51 pointHoverBorderWidth: 2,
52 }
53 ]
54 };
55
56 // Chart options
57 const options = {
58 responsive: true,
59 maintainAspectRatio: false,
60 plugins: {
61 legend: {
62 display: false
63 },
64 title: {
65 display: true,
66 text: title,
67 font: {
68 size: 16,
69 weight: '600'
70 },
71 color: '#1e1e1e',
72 padding: {
73 bottom: 20
74 }
75 },
76 tooltip: {
77 backgroundColor: '#ffffff',
78 titleColor: '#1e1e1e',
79 bodyColor: '#1e1e1e',
80 borderColor: '#e0e0e0',
81 borderWidth: 1,
82 cornerRadius: 8,
83 displayColors: false,
84 callbacks: {
85 label: function(context) {
86 const value = context.parsed.y;
87 const formattedValue = unit === 's' ?
88 `${value.toFixed(2)}s` :
89 unit === 'ms' ?
90 `${Math.round(value)}ms` :
91 value.toFixed(3);
92
93 return `${title}: ${formattedValue}`;
94 }
95 }
96 }
97 },
98 scales: {
99 x: {
100 grid: {
101 color: '#f0f0f0',
102 borderColor: '#e0e0e0'
103 },
104 ticks: {
105 color: '#666666',
106 font: {
107 size: 12
108 }
109 }
110 },
111 y: {
112 beginAtZero: true,
113 grid: {
114 color: '#f0f0f0',
115 borderColor: '#e0e0e0'
116 },
117 ticks: {
118 color: '#666666',
119 font: {
120 size: 12
121 },
122 callback: function(value) {
123 if (unit === 's') {
124 return `${value.toFixed(1)}s`;
125 } else if (unit === 'ms') {
126 return `${Math.round(value)}ms`;
127 } else {
128 return value.toFixed(2);
129 }
130 }
131 }
132 }
133 },
134 interaction: {
135 intersect: false,
136 mode: 'index'
137 },
138 elements: {
139 point: {
140 hoverRadius: 8
141 }
142 }
143 };
144
145 // Add threshold lines if provided
146 if (thresholds.good || thresholds.needs_improvement) {
147 options.plugins.annotation = {
148 annotations: {}
149 };
150
151 if (thresholds.good) {
152 options.plugins.annotation.annotations.goodThreshold = {
153 type: 'line',
154 yMin: thresholds.good,
155 yMax: thresholds.good,
156 borderColor: '#34a853',
157 borderWidth: 2,
158 borderDash: [5, 5],
159 label: {
160 content: 'Good',
161 enabled: true,
162 position: 'end'
163 }
164 };
165 }
166
167 if (thresholds.needs_improvement) {
168 options.plugins.annotation.annotations.improvementThreshold = {
169 type: 'line',
170 yMin: thresholds.needs_improvement,
171 yMax: thresholds.needs_improvement,
172 borderColor: '#fbbc04',
173 borderWidth: 2,
174 borderDash: [5, 5],
175 label: {
176 content: 'Needs Improvement',
177 enabled: true,
178 position: 'end'
179 }
180 };
181 }
182 }
183
184 return (
185 <div style={{ height: `${height}px`, width: '100%' }}>
186 <Line data={chartData} options={options} />
187 </div>
188 );
189 };
190
191 export default PerformanceChart;
192