@dhiraj0720/report1chart 2.2.8 → 2.2.9

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhiraj0720/report1chart",
3
- "version": "2.2.8",
3
+ "version": "2.2.9",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -1,84 +1,77 @@
1
1
  import React from 'react';
2
- import { View, Text } from 'react-native';
3
- import Svg, { Rect, Polyline, Circle, Text as SvgText } from 'react-native-svg';
2
+ import { View, Text, ScrollView } from 'react-native';
3
+ import Svg, { Rect, Circle, Text as SvgText } from 'react-native-svg';
4
4
 
5
5
  const SvgBarLineChart = ({ data }) => {
6
- if (!data?.series?.length) return null;
6
+ if (!data?.series) return null;
7
7
 
8
- const width = 360;
9
- const height = 190;
10
- const padding = 30;
11
- const barWidth = 12;
8
+ const width = Math.max(360, data.labels.length * 90);
9
+ const height = 240;
10
+ const padding = 40;
12
11
 
13
12
  const max = Math.max(...data.series.flatMap(s => s.data));
14
-
15
- const scaleX = i =>
16
- padding + i * ((width - padding * 2) / data.labels.length);
17
-
18
- const scaleY = v =>
19
- height - padding - (v / max) * (height - padding * 2);
13
+ const barWidth = 14;
20
14
 
21
15
  return (
22
- <View style={{ backgroundColor: '#fff', padding: 12, borderRadius: 12 }}>
23
- <Text style={{ fontWeight: '700', textAlign: 'center', marginBottom: 8 }}>
16
+ <View style={{ marginVertical: 16 }}>
17
+ <Text style={{ fontWeight: '700', marginBottom: 8 }}>
24
18
  {data.title}
25
19
  </Text>
26
20
 
27
- <Svg width={width} height={height}>
28
- {/* Bars */}
29
- {data.labels.map((_, i) =>
30
- data.series.slice(0, 2).map((s, idx) => (
31
- <Rect
32
- key={`${i}-${idx}`}
33
- x={scaleX(i) + idx * (barWidth + 4)}
34
- y={scaleY(s.data[i])}
35
- width={barWidth}
36
- height={height - padding - scaleY(s.data[i])}
37
- fill={idx === 0 ? '#FB8C00' : '#1E88E5'}
38
- rx="2"
39
- />
40
- ))
41
- )}
21
+ <ScrollView horizontal>
22
+ <Svg width={width} height={height}>
23
+ {data.labels.map((label, i) => {
24
+ const x = padding + i * 70;
25
+
26
+ return (
27
+ <React.Fragment key={i}>
28
+ {/* 2024 bar */}
29
+ <Rect
30
+ x={x}
31
+ y={height - (data.series[0].data[i] / max) * 150}
32
+ width={barWidth}
33
+ height={(data.series[0].data[i] / max) * 150}
34
+ fill="#E07A3F"
35
+ />
36
+
37
+ {/* 2025 bar */}
38
+ <Rect
39
+ x={x + barWidth + 4}
40
+ y={height - (data.series[1].data[i] / max) * 150}
41
+ width={barWidth}
42
+ height={(data.series[1].data[i] / max) * 150}
43
+ fill="#4E79A7"
44
+ />
42
45
 
43
- {/* Budget dotted line */}
44
- {data.series[2] && (
45
- <>
46
- <Polyline
47
- points={data.series[2].data
48
- .map((v, i) => `${scaleX(i) + barWidth},${scaleY(v)}`)
49
- .join(' ')}
50
- fill="none"
51
- stroke="#90CAF9"
52
- strokeWidth="2"
53
- strokeDasharray="4,4"
54
- />
46
+ {/* Budget dot */}
47
+ <Circle
48
+ cx={x + barWidth}
49
+ cy={height - (data.series[2].data[i] / max) * 150}
50
+ r={4}
51
+ fill="#8AB6E8"
52
+ />
55
53
 
56
- {data.series[2].data.map((v, i) => (
57
- <Circle
58
- key={i}
59
- cx={scaleX(i) + barWidth}
60
- cy={scaleY(v)}
61
- r="4"
62
- fill="#90CAF9"
63
- />
64
- ))}
65
- </>
66
- )}
54
+ <SvgText
55
+ x={x + barWidth}
56
+ y={height - 6}
57
+ fontSize="10"
58
+ textAnchor="middle"
59
+ >
60
+ {label}
61
+ </SvgText>
62
+ </React.Fragment>
63
+ );
64
+ })}
65
+ </Svg>
66
+ </ScrollView>
67
67
 
68
- {/* Value labels */}
69
- {data.series[2]?.data.map((v, i) => (
70
- <SvgText
71
- key={i}
72
- x={scaleX(i) + barWidth}
73
- y={scaleY(v) - 8}
74
- fontSize="9"
75
- fill="#333"
76
- textAnchor="middle"
77
- >
78
- {(v / 1_000_000).toFixed(0)}M
79
- </SvgText>
68
+ <View style={{ flexDirection: 'row', marginTop: 8 }}>
69
+ {data.series.map((s, i) => (
70
+ <Text key={i} style={{ marginRight: 16 }}>
71
+ {s.name}
72
+ </Text>
80
73
  ))}
81
- </Svg>
74
+ </View>
82
75
  </View>
83
76
  );
84
77
  };
@@ -1,84 +1,88 @@
1
1
  import React from 'react';
2
- import { View, Text } from 'react-native';
3
- import Svg, { Polyline, Circle, Line, Text as SvgText } from 'react-native-svg';
2
+ import { View, Text, ScrollView } from 'react-native';
3
+ import Svg, { Line, Circle, Text as SvgText } from 'react-native-svg';
4
4
 
5
5
  const SvgLineChart = ({ data }) => {
6
- if (!data?.series?.length) return null;
6
+ if (!data?.series) return null;
7
7
 
8
- const width = 340;
9
- const height = 180;
10
- const padding = 30;
8
+ const width = Math.max(360, data.labels.length * 80);
9
+ const height = 220;
10
+ const padding = 40;
11
11
 
12
- const allValues = data.series.flatMap(s => s.data);
13
- const max = Math.max(...allValues);
14
- const min = Math.min(...allValues);
12
+ const values = data.series.flatMap(s => s.data);
13
+ const max = Math.max(...values);
14
+ const min = Math.min(...values);
15
15
 
16
- const scaleX = i =>
17
- padding + (i * (width - padding * 2)) / (data.labels.length - 1);
16
+ const y = v =>
17
+ height - padding -
18
+ ((v - min) / (max - min || 1)) * (height - padding * 2);
18
19
 
19
- const scaleY = v =>
20
- height - padding - ((v - min) / (max - min)) * (height - padding * 2);
20
+ const xStep = (width - padding * 2) / (data.labels.length - 1 || 1);
21
+ const colors = ['#E07A3F', '#4E79A7'];
21
22
 
22
23
  return (
23
- <View style={{ backgroundColor: '#fff', padding: 12, borderRadius: 12 }}>
24
- <Text style={{ fontWeight: '700', textAlign: 'center', marginBottom: 8 }}>
24
+ <View style={{ marginVertical: 16 }}>
25
+ <Text style={{ fontWeight: '700', marginBottom: 8 }}>
25
26
  {data.title}
26
27
  </Text>
27
28
 
28
- <Svg width={width} height={height}>
29
- {/* Grid */}
30
- {[0.25, 0.5, 0.75].map(p => (
31
- <Line
32
- key={p}
33
- x1={padding}
34
- x2={width - padding}
35
- y1={padding + p * (height - padding * 2)}
36
- y2={padding + p * (height - padding * 2)}
37
- stroke="#e0e0e0"
38
- strokeDasharray="4,4"
39
- />
40
- ))}
29
+ <ScrollView horizontal>
30
+ <Svg width={width} height={height}>
31
+ {/* Grid */}
32
+ {[0.25, 0.5, 0.75].map((p, i) => (
33
+ <Line
34
+ key={i}
35
+ x1={padding}
36
+ x2={width - padding}
37
+ y1={padding + (height - padding * 2) * p}
38
+ y2={padding + (height - padding * 2) * p}
39
+ stroke="#ccc"
40
+ strokeDasharray="4"
41
+ />
42
+ ))}
41
43
 
42
- {/* Lines */}
43
- {data.series.map((s, idx) => {
44
- const points = s.data
45
- .map((v, i) => `${scaleX(i)},${scaleY(v)}`)
46
- .join(' ');
44
+ {data.series.map((s, si) =>
45
+ s.data.map((v, i) => {
46
+ const x = padding + i * xStep;
47
+ const yVal = y(v);
47
48
 
48
- return (
49
- <Polyline
50
- key={s.name}
51
- points={points}
52
- fill="none"
53
- stroke={idx === 0 ? '#FB8C00' : '#1E88E5'}
54
- strokeWidth="2"
55
- />
56
- );
57
- })}
49
+ if (i === s.data.length - 1) return null;
58
50
 
59
- {/* Points + Labels */}
60
- {data.series.map((s, idx) =>
61
- s.data.map((v, i) => (
62
- <React.Fragment key={`${idx}-${i}`}>
63
- <Circle
64
- cx={scaleX(i)}
65
- cy={scaleY(v)}
66
- r="4"
67
- fill={idx === 0 ? '#FB8C00' : '#1E88E5'}
68
- />
69
- <SvgText
70
- x={scaleX(i)}
71
- y={scaleY(v) - 8}
72
- fontSize="9"
73
- fill="#333"
74
- textAnchor="middle"
75
- >
76
- {v}
77
- </SvgText>
78
- </React.Fragment>
79
- ))
80
- )}
81
- </Svg>
51
+ return (
52
+ <React.Fragment key={`${si}-${i}`}>
53
+ <Line
54
+ x1={x}
55
+ y1={yVal}
56
+ x2={x + xStep}
57
+ y2={y(s.data[i + 1])}
58
+ stroke={colors[si]}
59
+ strokeWidth={2}
60
+ strokeDasharray={si === 0 ? '4' : '0'}
61
+ />
62
+ <Circle cx={x} cy={yVal} r={4} fill={colors[si]} />
63
+ <SvgText
64
+ x={x}
65
+ y={yVal - 8}
66
+ fontSize="10"
67
+ textAnchor="middle"
68
+ >
69
+ {v.toLocaleString()}
70
+ </SvgText>
71
+ </React.Fragment>
72
+ );
73
+ })
74
+ )}
75
+ </Svg>
76
+ </ScrollView>
77
+
78
+ {/* Legend */}
79
+ <View style={{ flexDirection: 'row', marginTop: 8 }}>
80
+ {data.series.map((s, i) => (
81
+ <Text key={i} style={{ marginRight: 16, color: colors[i] }}>
82
+ ● {s.name}
83
+ </Text>
84
+ ))}
85
+ </View>
82
86
  </View>
83
87
  );
84
88
  };
package/src/index.jsx CHANGED
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, ActivityIndicator } from 'react-native';
2
3
 
3
4
  import ReportListScreen from './screens/ReportListScreen';
4
5
  import Report1Screen from './screens/Report1Screen';
@@ -7,11 +8,38 @@ import Report3Screen from './screens/Report3Screen';
7
8
 
8
9
  const AnalyticsReports = ({ config }) => {
9
10
  const [active, setActive] = useState(null);
11
+ const [loading, setLoading] = useState(true);
10
12
 
13
+ // SPLASH / LOADER (5 seconds)
14
+ useEffect(() => {
15
+ const timer = setTimeout(() => {
16
+ setLoading(false);
17
+ }, 5000);
18
+
19
+ return () => clearTimeout(timer);
20
+ }, []);
21
+
22
+ // 👉 SHOW LOADER FIRST (BEFORE REPORT LIST)
23
+ if (loading) {
24
+ return (
25
+ <View
26
+ style={{
27
+ flex: 1,
28
+ justifyContent: 'center',
29
+ alignItems: 'center',
30
+ }}
31
+ >
32
+ <ActivityIndicator size="large" />
33
+ </View>
34
+ );
35
+ }
36
+
37
+ // 👉 AFTER LOADER → SHOW REPORT LIST
11
38
  if (!active) {
12
39
  return <ReportListScreen onSelect={setActive} />;
13
40
  }
14
41
 
42
+ // 👉 REPORT 1
15
43
  if (active === 1) {
16
44
  return (
17
45
  <Report1Screen
@@ -22,6 +50,7 @@ const AnalyticsReports = ({ config }) => {
22
50
  );
23
51
  }
24
52
 
53
+ // 👉 REPORT 2
25
54
  if (active === 2) {
26
55
  return (
27
56
  <Report2Screen
@@ -32,6 +61,7 @@ const AnalyticsReports = ({ config }) => {
32
61
  );
33
62
  }
34
63
 
64
+ // 👉 REPORT 3
35
65
  if (active === 3) {
36
66
  return (
37
67
  <Report3Screen
@@ -39,11 +39,31 @@ const Report2Screen = ({ api, token, onBack }) => {
39
39
 
40
40
  if (!table || !line || !bar) return <ActivityIndicator />;
41
41
 
42
+ const filterChartByMonth = (chart, month) => {
43
+ if (month === 'ALL') return chart;
44
+ const index = chart.labels.indexOf(month);
45
+ if (index === -1) return chart;
46
+
47
+ return {
48
+ ...chart,
49
+ labels: [chart.labels[index]],
50
+ series: chart.series.map(s => ({
51
+ ...s,
52
+ data: [s.data[index]],
53
+ })),
54
+ };
55
+ };
56
+
57
+
42
58
  const rows =
43
59
  month === 'ALL'
44
60
  ? table.rows
45
61
  : table.rows.filter(r => r.monthLabel === month);
46
62
 
63
+ const filteredLine = filterChartByMonth(line, month);
64
+ const filteredBar = filterChartByMonth(bar, month);
65
+
66
+
47
67
  return (
48
68
  <ScrollView style={{ padding: 16 }}>
49
69
  <Text onPress={onBack}>‹ Back</Text>
@@ -58,16 +78,18 @@ const Report2Screen = ({ api, token, onBack }) => {
58
78
  onSelect={setMonth}
59
79
  />
60
80
 
61
- <FrozenTableReport2 rows={rows} />
62
-
63
- <SvgLineChart data={line} />
64
- <SvgBarLineChart data={bar} />
65
-
66
81
  <DivisionSelector
67
82
  divisions={divisions}
68
83
  selected={division}
69
84
  onSelect={setDivision}
70
85
  />
86
+
87
+ <FrozenTableReport2 rows={rows} />
88
+
89
+ <SvgLineChart data={filteredLine} />
90
+ <SvgBarLineChart data={filteredBar} />
91
+
92
+
71
93
  </ScrollView>
72
94
  );
73
95
  };
@@ -26,6 +26,21 @@ const Report3Screen = ({ api, token, onBack }) => {
26
26
 
27
27
  if (!table || !line || !bar) return <ActivityIndicator />;
28
28
 
29
+ const filterChartByMonth = (chart, month) => {
30
+ if (month === 'ALL') return chart;
31
+ const index = chart.labels.indexOf(month);
32
+ if (index === -1) return chart;
33
+
34
+ return {
35
+ ...chart,
36
+ labels: [chart.labels[index]],
37
+ series: chart.series.map(s => ({
38
+ ...s,
39
+ data: [s.data[index]],
40
+ })),
41
+ };
42
+ };
43
+
29
44
  const months = table.rows.filter(r => r.month !== 99).map(r => r.monthLabel);
30
45
 
31
46
  const rows =
@@ -33,6 +48,10 @@ const Report3Screen = ({ api, token, onBack }) => {
33
48
  ? table.rows
34
49
  : table.rows.filter(r => r.monthLabel === month);
35
50
 
51
+ const filteredLine = filterChartByMonth(line, month);
52
+ const filteredBar = filterChartByMonth(bar, month);
53
+
54
+
36
55
  return (
37
56
  <ScrollView style={{ padding: 16 }}>
38
57
  <Text onPress={onBack}>‹ Back</Text>
@@ -49,8 +68,8 @@ const Report3Screen = ({ api, token, onBack }) => {
49
68
 
50
69
  <FrozenTableReport3 rows={rows} />
51
70
 
52
- <SvgLineChart data={line} />
53
- <SvgBarLineChart data={bar} />
71
+ <SvgLineChart data={filteredLine} />
72
+ <SvgBarLineChart data={filteredBar} />
54
73
  </ScrollView>
55
74
  );
56
75
  };