@dhiraj0720/report1chart 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dhiraj0720/report1chart",
3
- "version": "1.0.1",
4
- "main": "src/index.js",
3
+ "version": "1.0.3",
4
+ "main": "src/index.jsx",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
package/src/index.jsx ADDED
@@ -0,0 +1,600 @@
1
+ import React, { useState } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ ActivityIndicator,
9
+ Dimensions,
10
+ } from 'react-native';
11
+
12
+ const ReportChart = ({
13
+ onReportSelect,
14
+ onClose,
15
+ reports = [],
16
+ onFetchReportData
17
+ }) => {
18
+ const [selectedReport, setSelectedReport] = useState(null);
19
+ const [reportData, setReportData] = useState(null);
20
+ const [loading, setLoading] = useState(false);
21
+ const [error, setError] = useState(null);
22
+
23
+ // Default reports if none provided
24
+ const defaultReports = [
25
+ {
26
+ id: 1,
27
+ name: 'Report 1',
28
+ title: 'Revenue Trend',
29
+ type: 'line',
30
+ description: 'Monthly revenue analysis'
31
+ },
32
+ {
33
+ id: 2,
34
+ name: 'Report 2',
35
+ title: 'Revenue by Mode',
36
+ type: 'bar',
37
+ description: 'Revenue distribution across modes'
38
+ },
39
+ {
40
+ id: 3,
41
+ name: 'Report 3',
42
+ title: 'Shipment by Direction',
43
+ type: 'pie',
44
+ description: 'Shipment direction analysis'
45
+ },
46
+ ];
47
+
48
+ const reportList = reports.length > 0 ? reports : defaultReports;
49
+
50
+ const handleReportClick = async (report) => {
51
+ setLoading(true);
52
+ setError(null);
53
+ setReportData(null);
54
+ setSelectedReport(report);
55
+
56
+ try {
57
+ // Call the parent function to fetch data
58
+ if (onFetchReportData) {
59
+ const data = await onFetchReportData(report);
60
+ if (data) {
61
+ setReportData({
62
+ ...data,
63
+ title: report.title || report.name,
64
+ type: report.type || 'bar',
65
+ });
66
+ }
67
+ }
68
+
69
+ // Callback to parent
70
+ if (onReportSelect) {
71
+ onReportSelect(report.name);
72
+ }
73
+ } catch (err) {
74
+ setError(err.message || 'Failed to fetch report data');
75
+ } finally {
76
+ setLoading(false);
77
+ }
78
+ };
79
+
80
+ const renderChart = () => {
81
+ if (!reportData || !reportData.data) {
82
+ return (
83
+ <View style={styles.noDataContainer}>
84
+ <Text style={styles.noDataText}>No data available</Text>
85
+ </View>
86
+ );
87
+ }
88
+
89
+ const { type, data } = reportData;
90
+
91
+ switch (type) {
92
+ case 'line':
93
+ return renderLineChart(data);
94
+ case 'bar':
95
+ return renderBarChart(data);
96
+ case 'pie':
97
+ return renderPieChart(data);
98
+ default:
99
+ return renderBarChart(data);
100
+ }
101
+ };
102
+
103
+ const renderLineChart = (data) => {
104
+ // Handle both formats: { labels, values } or array format
105
+ const values = data.values || data.map(d => d.value || d.revenue || d.shipments || 0);
106
+ const labels = data.labels || data.map(d => d.label || d.month || d.mode || d.direction || '');
107
+
108
+ const maxValue = Math.max(...values, 1);
109
+ const chartHeight = 200;
110
+ const chartWidth = Dimensions.get('window').width - 64;
111
+ const barWidth = (chartWidth / values.length) - 10;
112
+
113
+ return (
114
+ <View style={styles.chartContainer}>
115
+ <Text style={styles.chartTitle}>{reportData.title}</Text>
116
+ <ScrollView horizontal showsHorizontalScrollIndicator={false}>
117
+ <View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
118
+ {values.map((value, index) => {
119
+ const height = (value / maxValue) * chartHeight;
120
+ const label = labels[index] || `M${index + 1}`;
121
+
122
+ return (
123
+ <View key={index} style={styles.linePointWrapper}>
124
+ <View style={[styles.linePoint, {
125
+ height: Math.max(height, 2),
126
+ width: barWidth
127
+ }]} />
128
+ <View style={styles.lineConnector} />
129
+ <Text style={styles.lineLabel} numberOfLines={1}>{label}</Text>
130
+ <Text style={styles.valueText}>{formatNumber(value)}</Text>
131
+ </View>
132
+ );
133
+ })}
134
+ </View>
135
+ </ScrollView>
136
+ </View>
137
+ );
138
+ };
139
+
140
+ const renderBarChart = (data) => {
141
+ // Handle array format or object format
142
+ const isArray = Array.isArray(data);
143
+ const values = isArray ? data.map(d => d.revenue || d.value || d.shipments || 0) : data.values;
144
+ const labels = isArray ? data.map(d => d.mode || d.label || '') : data.labels;
145
+
146
+ const maxValue = Math.max(...values, 1);
147
+ const chartHeight = 200;
148
+ const chartWidth = Dimensions.get('window').width - 64;
149
+ const barWidth = Math.min(40, (chartWidth / values.length) - 10);
150
+
151
+ return (
152
+ <View style={styles.chartContainer}>
153
+ <Text style={styles.chartTitle}>{reportData.title}</Text>
154
+ <ScrollView horizontal showsHorizontalScrollIndicator={false}>
155
+ <View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
156
+ {values.map((value, index) => {
157
+ const height = (value / maxValue) * chartHeight;
158
+ const label = labels?.[index] || `Item ${index + 1}`;
159
+
160
+ return (
161
+ <View key={index} style={styles.barWrapper}>
162
+ <View style={[styles.bar, {
163
+ height,
164
+ width: barWidth,
165
+ backgroundColor: getColor(index)
166
+ }]} />
167
+ <Text style={styles.barLabel} numberOfLines={1}>{label}</Text>
168
+ <Text style={styles.valueText}>{formatNumber(value)}</Text>
169
+ </View>
170
+ );
171
+ })}
172
+ </View>
173
+ </ScrollView>
174
+ </View>
175
+ );
176
+ };
177
+
178
+ const renderPieChart = (data) => {
179
+ // Data should be array of objects with label and value
180
+ const total = data.reduce((sum, item) => sum + (item.shipments || item.revenue || item.value || 0), 0);
181
+
182
+ return (
183
+ <View style={styles.chartContainer}>
184
+ <Text style={styles.chartTitle}>{reportData.title}</Text>
185
+ <View style={styles.pieContainer}>
186
+ {data.map((item, index) => {
187
+ const value = item.shipments || item.revenue || item.value || 0;
188
+ const label = item.direction || item.mode || item.label || `Item ${index + 1}`;
189
+ const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : '0';
190
+
191
+ return (
192
+ <View key={index} style={styles.pieItem}>
193
+ <View style={[styles.pieColor, { backgroundColor: getColor(index) }]} />
194
+ <Text style={styles.pieLabel}>{label}:</Text>
195
+ <Text style={styles.pieValue}>
196
+ {formatNumber(value)} ({percentage}%)
197
+ </Text>
198
+ </View>
199
+ );
200
+ })}
201
+ </View>
202
+ {total > 0 && (
203
+ <Text style={styles.totalText}>Total: {formatNumber(total)}</Text>
204
+ )}
205
+ </View>
206
+ );
207
+ };
208
+
209
+ const formatNumber = (num) => {
210
+ return num.toLocaleString();
211
+ };
212
+
213
+ const getColor = (index) => {
214
+ const colors = ['#4CAF50', '#2196F3', '#FF9800', '#E91E63', '#9C27B0', '#00BCD4'];
215
+ return colors[index % colors.length];
216
+ };
217
+
218
+ const handleClose = () => {
219
+ setSelectedReport(null);
220
+ setReportData(null);
221
+ if (onClose) onClose();
222
+ };
223
+
224
+ if (selectedReport) {
225
+ return (
226
+ <View style={styles.container}>
227
+ <View style={styles.header}>
228
+ <TouchableOpacity
229
+ style={styles.backButton}
230
+ onPress={() => {
231
+ setSelectedReport(null);
232
+ setReportData(null);
233
+ }}
234
+ >
235
+ <Text style={styles.backText}>‹</Text>
236
+ <Text style={styles.backButtonText}>Back</Text>
237
+ </TouchableOpacity>
238
+ <Text style={styles.headerTitle} numberOfLines={1}>
239
+ {selectedReport.title || selectedReport.name}
240
+ </Text>
241
+ <TouchableOpacity onPress={handleClose} style={styles.closeButton}>
242
+ <Text style={styles.closeText}>×</Text>
243
+ </TouchableOpacity>
244
+ </View>
245
+
246
+ {loading ? (
247
+ <View style={styles.loadingContainer}>
248
+ <ActivityIndicator size="large" color="#4CAF50" />
249
+ <Text style={styles.loadingText}>Loading report data...</Text>
250
+ </View>
251
+ ) : error ? (
252
+ <View style={styles.errorContainer}>
253
+ <Text style={styles.errorText}>Error: {error}</Text>
254
+ <TouchableOpacity
255
+ style={styles.retryButton}
256
+ onPress={() => handleReportClick(selectedReport)}
257
+ >
258
+ <Text style={styles.retryText}>Retry</Text>
259
+ </TouchableOpacity>
260
+ </View>
261
+ ) : (
262
+ <ScrollView style={styles.chartView}>
263
+ {renderChart()}
264
+
265
+ {reportData && reportData.data && (
266
+ <View style={styles.dataInfo}>
267
+ <Text style={styles.infoTitle}>Report Information</Text>
268
+ <Text style={styles.infoText}>
269
+ {selectedReport.description || 'Detailed analysis report'}
270
+ </Text>
271
+ <Text style={styles.dataSource}>
272
+ Data points: {Array.isArray(reportData.data) ? reportData.data.length :
273
+ reportData.data.values?.length || reportData.data.labels?.length || 'N/A'}
274
+ </Text>
275
+ </View>
276
+ )}
277
+ </ScrollView>
278
+ )}
279
+ </View>
280
+ );
281
+ }
282
+
283
+ return (
284
+ <View style={styles.container}>
285
+ <View style={styles.header}>
286
+ <Text style={styles.headerTitle}>Reports Dashboard</Text>
287
+ <TouchableOpacity onPress={handleClose} style={styles.closeButton}>
288
+ <Text style={styles.closeText}>×</Text>
289
+ </TouchableOpacity>
290
+ </View>
291
+
292
+ <ScrollView style={styles.reportsList}>
293
+ {reportList.map((report) => (
294
+ <TouchableOpacity
295
+ key={report.id}
296
+ style={styles.reportCard}
297
+ onPress={() => handleReportClick(report)}
298
+ >
299
+ <View style={[styles.reportIcon, { backgroundColor: getColor(report.id) }]}>
300
+ <Text style={styles.reportIconText}>{report.id}</Text>
301
+ </View>
302
+ <View style={styles.reportInfo}>
303
+ <Text style={styles.reportName}>{report.name}</Text>
304
+ <Text style={styles.reportTitle}>{report.title}</Text>
305
+ <Text style={styles.reportDesc}>{report.description}</Text>
306
+ </View>
307
+ <Text style={styles.arrow}>›</Text>
308
+ </TouchableOpacity>
309
+ ))}
310
+ </ScrollView>
311
+ </View>
312
+ );
313
+ };
314
+
315
+ const styles = StyleSheet.create({
316
+ container: {
317
+ flex: 1,
318
+ backgroundColor: '#f8f9fa',
319
+ },
320
+ header: {
321
+ flexDirection: 'row',
322
+ alignItems: 'center',
323
+ justifyContent: 'space-between',
324
+ backgroundColor: '#fff',
325
+ paddingHorizontal: 16,
326
+ paddingVertical: 12,
327
+ borderBottomWidth: 1,
328
+ borderBottomColor: '#e0e0e0',
329
+ },
330
+ headerTitle: {
331
+ fontSize: 18,
332
+ fontWeight: '700',
333
+ color: '#000',
334
+ flex: 1,
335
+ textAlign: 'center',
336
+ },
337
+ backButton: {
338
+ flexDirection: 'row',
339
+ alignItems: 'center',
340
+ padding: 8,
341
+ },
342
+ backText: {
343
+ fontSize: 24,
344
+ color: '#4CAF50',
345
+ marginRight: 4,
346
+ },
347
+ backButtonText: {
348
+ fontSize: 16,
349
+ color: '#4CAF50',
350
+ fontWeight: '600',
351
+ },
352
+ closeButton: {
353
+ width: 32,
354
+ height: 32,
355
+ borderRadius: 16,
356
+ backgroundColor: '#f0f0f0',
357
+ justifyContent: 'center',
358
+ alignItems: 'center',
359
+ },
360
+ closeText: {
361
+ fontSize: 20,
362
+ color: '#666',
363
+ fontWeight: '300',
364
+ },
365
+ reportsList: {
366
+ flex: 1,
367
+ padding: 16,
368
+ },
369
+ reportCard: {
370
+ flexDirection: 'row',
371
+ alignItems: 'center',
372
+ backgroundColor: '#fff',
373
+ borderRadius: 12,
374
+ padding: 16,
375
+ marginBottom: 12,
376
+ borderWidth: 1,
377
+ borderColor: '#e8e8e8',
378
+ shadowColor: '#000',
379
+ shadowOffset: { width: 0, height: 1 },
380
+ shadowOpacity: 0.05,
381
+ shadowRadius: 2,
382
+ elevation: 2,
383
+ },
384
+ reportIcon: {
385
+ width: 44,
386
+ height: 44,
387
+ borderRadius: 22,
388
+ justifyContent: 'center',
389
+ alignItems: 'center',
390
+ marginRight: 12,
391
+ },
392
+ reportIconText: {
393
+ fontSize: 18,
394
+ fontWeight: '700',
395
+ color: '#fff',
396
+ },
397
+ reportInfo: {
398
+ flex: 1,
399
+ },
400
+ reportName: {
401
+ fontSize: 16,
402
+ fontWeight: '600',
403
+ color: '#000',
404
+ marginBottom: 2,
405
+ },
406
+ reportTitle: {
407
+ fontSize: 14,
408
+ fontWeight: '500',
409
+ color: '#4CAF50',
410
+ marginBottom: 4,
411
+ },
412
+ reportDesc: {
413
+ fontSize: 13,
414
+ color: '#666',
415
+ lineHeight: 18,
416
+ },
417
+ arrow: {
418
+ fontSize: 24,
419
+ color: '#ccc',
420
+ fontWeight: '300',
421
+ },
422
+ chartView: {
423
+ flex: 1,
424
+ padding: 16,
425
+ },
426
+ chartContainer: {
427
+ backgroundColor: '#fff',
428
+ borderRadius: 12,
429
+ padding: 16,
430
+ marginBottom: 16,
431
+ borderWidth: 1,
432
+ borderColor: '#e8e8e8',
433
+ shadowColor: '#000',
434
+ shadowOffset: { width: 0, height: 1 },
435
+ shadowOpacity: 0.05,
436
+ shadowRadius: 2,
437
+ elevation: 2,
438
+ },
439
+ chartTitle: {
440
+ fontSize: 18,
441
+ fontWeight: '700',
442
+ color: '#000',
443
+ marginBottom: 20,
444
+ textAlign: 'center',
445
+ },
446
+ chart: {
447
+ flexDirection: 'row',
448
+ alignItems: 'flex-end',
449
+ justifyContent: 'space-between',
450
+ paddingHorizontal: 8,
451
+ },
452
+ barWrapper: {
453
+ alignItems: 'center',
454
+ marginHorizontal: 4,
455
+ },
456
+ bar: {
457
+ borderRadius: 4,
458
+ },
459
+ barLabel: {
460
+ marginTop: 8,
461
+ fontSize: 11,
462
+ color: '#666',
463
+ textAlign: 'center',
464
+ width: 60,
465
+ },
466
+ linePointWrapper: {
467
+ alignItems: 'center',
468
+ marginHorizontal: 4,
469
+ },
470
+ linePoint: {
471
+ backgroundColor: '#2196F3',
472
+ borderRadius: 2,
473
+ },
474
+ lineConnector: {
475
+ width: 2,
476
+ backgroundColor: '#2196F3',
477
+ opacity: 0.3,
478
+ marginVertical: 2,
479
+ flex: 1,
480
+ },
481
+ lineLabel: {
482
+ marginTop: 8,
483
+ fontSize: 11,
484
+ color: '#666',
485
+ textAlign: 'center',
486
+ width: 60,
487
+ },
488
+ valueText: {
489
+ fontSize: 10,
490
+ color: '#999',
491
+ marginTop: 4,
492
+ fontWeight: '500',
493
+ },
494
+ pieContainer: {
495
+ padding: 10,
496
+ },
497
+ pieItem: {
498
+ flexDirection: 'row',
499
+ alignItems: 'center',
500
+ marginBottom: 12,
501
+ padding: 8,
502
+ backgroundColor: '#f9f9f9',
503
+ borderRadius: 8,
504
+ },
505
+ pieColor: {
506
+ width: 16,
507
+ height: 16,
508
+ borderRadius: 8,
509
+ marginRight: 12,
510
+ },
511
+ pieLabel: {
512
+ fontSize: 15,
513
+ fontWeight: '600',
514
+ color: '#000',
515
+ flex: 1,
516
+ },
517
+ pieValue: {
518
+ fontSize: 14,
519
+ color: '#666',
520
+ fontWeight: '500',
521
+ },
522
+ totalText: {
523
+ fontSize: 16,
524
+ fontWeight: '700',
525
+ color: '#4CAF50',
526
+ textAlign: 'center',
527
+ marginTop: 16,
528
+ paddingTop: 16,
529
+ borderTopWidth: 1,
530
+ borderTopColor: '#eee',
531
+ },
532
+ dataInfo: {
533
+ backgroundColor: '#e8f5e9',
534
+ borderRadius: 12,
535
+ padding: 16,
536
+ marginTop: 8,
537
+ },
538
+ infoTitle: {
539
+ fontSize: 16,
540
+ fontWeight: '700',
541
+ color: '#2e7d32',
542
+ marginBottom: 8,
543
+ },
544
+ infoText: {
545
+ fontSize: 14,
546
+ color: '#555',
547
+ lineHeight: 20,
548
+ marginBottom: 8,
549
+ },
550
+ dataSource: {
551
+ fontSize: 13,
552
+ color: '#777',
553
+ fontStyle: 'italic',
554
+ },
555
+ loadingContainer: {
556
+ flex: 1,
557
+ justifyContent: 'center',
558
+ alignItems: 'center',
559
+ padding: 40,
560
+ },
561
+ loadingText: {
562
+ marginTop: 16,
563
+ fontSize: 16,
564
+ color: '#666',
565
+ },
566
+ errorContainer: {
567
+ flex: 1,
568
+ justifyContent: 'center',
569
+ alignItems: 'center',
570
+ padding: 40,
571
+ },
572
+ errorText: {
573
+ fontSize: 16,
574
+ color: '#d32f2f',
575
+ textAlign: 'center',
576
+ marginBottom: 20,
577
+ },
578
+ retryButton: {
579
+ backgroundColor: '#4CAF50',
580
+ paddingHorizontal: 24,
581
+ paddingVertical: 12,
582
+ borderRadius: 8,
583
+ },
584
+ retryText: {
585
+ color: '#fff',
586
+ fontSize: 16,
587
+ fontWeight: '600',
588
+ },
589
+ noDataContainer: {
590
+ padding: 40,
591
+ alignItems: 'center',
592
+ },
593
+ noDataText: {
594
+ fontSize: 16,
595
+ color: '#999',
596
+ textAlign: 'center',
597
+ },
598
+ });
599
+
600
+ export default ReportChart;
package/src/index.js DELETED
@@ -1,43 +0,0 @@
1
- import React from 'react';
2
- import { View, Text, StyleSheet } from 'react-native';
3
-
4
- const BarChart = ({ data = [], height = 200 }) => {
5
- const maxValue = Math.max(...data.map(d => d.value), 1);
6
-
7
- return (
8
- <View style={[styles.container, { height }]}>
9
- {data.map((item, index) => {
10
- const barHeight = (item.value / maxValue) * height;
11
-
12
- return (
13
- <View key={index} style={styles.barWrapper}>
14
- <View style={[styles.bar, { height: barHeight }]} />
15
- <Text style={styles.label}>{item.name}</Text>
16
- </View>
17
- );
18
- })}
19
- </View>
20
- );
21
- };
22
-
23
- export default BarChart; // ✅ DEFAULT EXPORT
24
-
25
- const styles = StyleSheet.create({
26
- container: {
27
- flexDirection: 'row',
28
- alignItems: 'flex-end',
29
- },
30
- barWrapper: {
31
- flex: 1,
32
- alignItems: 'center',
33
- },
34
- bar: {
35
- width: 22,
36
- backgroundColor: '#4CAF50',
37
- borderRadius: 6,
38
- },
39
- label: {
40
- marginTop: 6,
41
- fontSize: 12,
42
- },
43
- });