0xSakura commited on
Commit
c8a3dc1
·
1 Parent(s): 3f8b2d3

Add files via upload

Browse files
components/AnalysisResult.tsx CHANGED
@@ -1,7 +1,7 @@
1
 
2
  import React from 'react';
3
  import { AnalysisData } from '../types';
4
- import { ScrollText, Briefcase, Coins, Heart, Activity, Users, Star, Info } from 'lucide-react';
5
 
6
  interface AnalysisResultProps {
7
  analysis: AnalysisData;
@@ -31,8 +31,8 @@ const ScoreBar = ({ score }: { score: number }) => {
31
  );
32
  };
33
 
34
- const Card = ({ title, icon: Icon, content, score, colorClass }: any) => (
35
- <div className="bg-white p-6 rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow flex flex-col h-full">
36
  <div className={`flex items-center justify-between mb-3 ${colorClass}`}>
37
  <div className="flex items-center gap-2">
38
  <Icon className="w-5 h-5" />
@@ -40,6 +40,14 @@ const Card = ({ title, icon: Icon, content, score, colorClass }: any) => (
40
  </div>
41
  <Star className="w-4 h-4 opacity-50" />
42
  </div>
 
 
 
 
 
 
 
 
43
  <div className="text-gray-600 text-sm leading-relaxed whitespace-pre-wrap flex-grow">
44
  {content}
45
  </div>
@@ -84,6 +92,33 @@ const AnalysisResult: React.FC<AnalysisResultProps> = ({ analysis }) => {
84
 
85
  {/* Grid for categorical analysis with Scores */}
86
  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  <Card
88
  title="事业行业"
89
  icon={Briefcase}
@@ -91,6 +126,16 @@ const AnalysisResult: React.FC<AnalysisResultProps> = ({ analysis }) => {
91
  score={analysis.industryScore}
92
  colorClass="text-blue-600"
93
  />
 
 
 
 
 
 
 
 
 
 
94
  <Card
95
  title="财富层级"
96
  icon={Coins}
@@ -150,7 +195,7 @@ const AnalysisResult: React.FC<AnalysisResultProps> = ({ analysis }) => {
150
  </li>
151
  </ul>
152
  <p className="text-xs text-black leading-relaxed border-t border-gray-100 pt-2 text-justify">
153
- 注:命运还受环境和个人选择影响八字趋势不能完全代表真实人生,命理学不是玄学而是帮助我们在人生列车上做出更好选择哲学工具一命二运三风水 四积阴德五读书 六名七相八敬神 九遇贵人十养生。
154
  </p>
155
  </div>
156
  }
 
1
 
2
  import React from 'react';
3
  import { AnalysisData } from '../types';
4
+ import { ScrollText, Briefcase, Coins, Heart, Activity, Users, Star, Info, Brain, Bitcoin, Compass } from 'lucide-react';
5
 
6
  interface AnalysisResultProps {
7
  analysis: AnalysisData;
 
31
  );
32
  };
33
 
34
+ const Card = ({ title, icon: Icon, content, score, colorClass, extraBadges }: any) => (
35
+ <div className="bg-white p-6 rounded-xl shadow-sm border border-gray-100 hover:shadow-md transition-shadow flex flex-col h-full relative overflow-hidden">
36
  <div className={`flex items-center justify-between mb-3 ${colorClass}`}>
37
  <div className="flex items-center gap-2">
38
  <Icon className="w-5 h-5" />
 
40
  </div>
41
  <Star className="w-4 h-4 opacity-50" />
42
  </div>
43
+
44
+ {/* Extra Badges for Crypto */}
45
+ {extraBadges && (
46
+ <div className="flex flex-wrap gap-2 mb-3">
47
+ {extraBadges}
48
+ </div>
49
+ )}
50
+
51
  <div className="text-gray-600 text-sm leading-relaxed whitespace-pre-wrap flex-grow">
52
  {content}
53
  </div>
 
92
 
93
  {/* Grid for categorical analysis with Scores */}
94
  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
95
+
96
+ {/* Crypto Analysis */}
97
+ <Card
98
+ title="币圈交易运势"
99
+ icon={Bitcoin}
100
+ content={analysis.crypto}
101
+ score={analysis.cryptoScore}
102
+ colorClass="text-amber-600"
103
+ extraBadges={
104
+ <>
105
+ <span className="px-2 py-1 bg-amber-50 text-amber-700 text-xs font-bold rounded border border-amber-200">
106
+ 🔥 暴富流年: {analysis.cryptoYear}
107
+ </span>
108
+ <span className="px-2 py-1 bg-indigo-50 text-indigo-700 text-xs font-bold rounded border border-indigo-200">
109
+ 🎯 推荐: {analysis.cryptoStyle}
110
+ </span>
111
+ </>
112
+ }
113
+ />
114
+
115
+ <Card
116
+ title="性格分析"
117
+ icon={Brain}
118
+ content={analysis.personality}
119
+ score={analysis.personalityScore}
120
+ colorClass="text-teal-600"
121
+ />
122
  <Card
123
  title="事业行业"
124
  icon={Briefcase}
 
126
  score={analysis.industryScore}
127
  colorClass="text-blue-600"
128
  />
129
+
130
+ {/* Feng Shui Analysis - New Added */}
131
+ <Card
132
+ title="发展风水"
133
+ icon={Compass}
134
+ content={analysis.fengShui}
135
+ score={analysis.fengShuiScore}
136
+ colorClass="text-cyan-700"
137
+ />
138
+
139
  <Card
140
  title="财富层级"
141
  icon={Coins}
 
195
  </li>
196
  </ul>
197
  <p className="text-xs text-black leading-relaxed border-t border-gray-100 pt-2 text-justify">
198
+ 注:币圈交易风险极高,命理分析仅供娱乐与性格参考不构成任何投资建议。请对自己资金负责
199
  </p>
200
  </div>
201
  }
components/LifeKLineChart.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import React from 'react';
2
  import {
3
  ComposedChart,
@@ -8,7 +9,8 @@ import {
8
  Tooltip,
9
  ResponsiveContainer,
10
  ReferenceLine,
11
- Label
 
12
  } from 'recharts';
13
  import { KLinePoint } from '../types';
14
 
@@ -73,7 +75,7 @@ const CandleShape = (props: any) => {
73
 
74
  const isUp = payload.close >= payload.open;
75
  const color = isUp ? '#22c55e' : '#ef4444'; // Green Up, Red Down
76
- const strokeColor = isUp ? '#16a34a' : '#dc2626'; // Slightly darker for stroke
77
 
78
  let highY = y;
79
  let lowY = y + height;
@@ -91,11 +93,13 @@ const CandleShape = (props: any) => {
91
  const center = x + width / 2;
92
 
93
  // Enforce minimum body height so flat doji candles are visible
94
- const renderHeight = height < 1 ? 1 : height;
95
 
96
  return (
97
  <g>
98
- <line x1={center} y1={highY} x2={center} y2={lowY} stroke={strokeColor} strokeWidth={1.5} />
 
 
99
  <rect
100
  x={x}
101
  y={y}
@@ -103,8 +107,41 @@ const CandleShape = (props: any) => {
103
  height={renderHeight}
104
  fill={color}
105
  stroke={strokeColor}
106
- strokeWidth={0.5}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  />
 
 
 
 
 
 
 
 
 
 
 
108
  </g>
109
  );
110
  };
@@ -113,6 +150,8 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
113
  const transformedData = data.map(d => ({
114
  ...d,
115
  bodyRange: [Math.min(d.open, d.close), Math.max(d.open, d.close)],
 
 
116
  }));
117
 
118
  // Identify Da Yun change points to draw reference lines
@@ -121,6 +160,9 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
121
  return d.daYun !== data[i-1].daYun;
122
  });
123
 
 
 
 
124
  if (!data || data.length === 0) {
125
  return <div className="h-[500px] flex items-center justify-center text-gray-400">无数据</div>;
126
  }
@@ -136,7 +178,7 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
136
  </div>
137
 
138
  <ResponsiveContainer width="100%" height="90%">
139
- <ComposedChart data={transformedData} margin={{ top: 20, right: 10, left: 0, bottom: 20 }}>
140
  <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f3f4f6" />
141
 
142
  <XAxis
@@ -149,7 +191,7 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
149
  />
150
 
151
  <YAxis
152
- domain={[0, 100]}
153
  tick={{fontSize: 10, fill: '#6b7280'}}
154
  axisLine={false}
155
  tickLine={false}
@@ -183,7 +225,17 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
183
  shape={<CandleShape />}
184
  isAnimationActive={true}
185
  animationDuration={1500}
186
- />
 
 
 
 
 
 
 
 
 
 
187
 
188
  </ComposedChart>
189
  </ResponsiveContainer>
@@ -191,4 +243,4 @@ const LifeKLineChart: React.FC<LifeKLineChartProps> = ({ data }) => {
191
  );
192
  };
193
 
194
- export default LifeKLineChart;
 
1
+
2
  import React from 'react';
3
  import {
4
  ComposedChart,
 
9
  Tooltip,
10
  ResponsiveContainer,
11
  ReferenceLine,
12
+ Label,
13
+ LabelList
14
  } from 'recharts';
15
  import { KLinePoint } from '../types';
16
 
 
75
 
76
  const isUp = payload.close >= payload.open;
77
  const color = isUp ? '#22c55e' : '#ef4444'; // Green Up, Red Down
78
+ const strokeColor = isUp ? '#15803d' : '#b91c1c'; // Darker stroke for better visibility
79
 
80
  let highY = y;
81
  let lowY = y + height;
 
93
  const center = x + width / 2;
94
 
95
  // Enforce minimum body height so flat doji candles are visible
96
+ const renderHeight = height < 2 ? 2 : height;
97
 
98
  return (
99
  <g>
100
+ {/* Wick - made slightly thicker for visibility */}
101
+ <line x1={center} y1={highY} x2={center} y2={lowY} stroke={strokeColor} strokeWidth={2} />
102
+ {/* Body */}
103
  <rect
104
  x={x}
105
  y={y}
 
107
  height={renderHeight}
108
  fill={color}
109
  stroke={strokeColor}
110
+ strokeWidth={1}
111
+ rx={1} // Slight border radius
112
+ />
113
+ </g>
114
+ );
115
+ };
116
+
117
+ // Custom Label Component for the Peak Star
118
+ const PeakLabel = (props: any) => {
119
+ const { x, y, width, value, maxHigh } = props;
120
+
121
+ // Only render if this value equals the global max high
122
+ if (value !== maxHigh) return null;
123
+
124
+ return (
125
+ <g>
126
+ {/* Red Star Icon */}
127
+ <path
128
+ d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
129
+ transform={`translate(${x + width / 2 - 6}, ${y - 24}) scale(0.5)`}
130
+ fill="#ef4444" // Red-500
131
+ stroke="#b91c1c" // Red-700
132
+ strokeWidth="1"
133
  />
134
+ {/* Score Text */}
135
+ <text
136
+ x={x + width / 2}
137
+ y={y - 28}
138
+ fill="#b91c1c"
139
+ fontSize={10}
140
+ fontWeight="bold"
141
+ textAnchor="middle"
142
+ >
143
+ {value}
144
+ </text>
145
  </g>
146
  );
147
  };
 
150
  const transformedData = data.map(d => ({
151
  ...d,
152
  bodyRange: [Math.min(d.open, d.close), Math.max(d.open, d.close)],
153
+ // Helper for labelling: we label the 'high' point
154
+ labelPoint: d.high
155
  }));
156
 
157
  // Identify Da Yun change points to draw reference lines
 
160
  return d.daYun !== data[i-1].daYun;
161
  });
162
 
163
+ // Calculate Global Max High for the peak label
164
+ const maxHigh = data.length > 0 ? Math.max(...data.map(d => d.high)) : 100;
165
+
166
  if (!data || data.length === 0) {
167
  return <div className="h-[500px] flex items-center justify-center text-gray-400">无数据</div>;
168
  }
 
178
  </div>
179
 
180
  <ResponsiveContainer width="100%" height="90%">
181
+ <ComposedChart data={transformedData} margin={{ top: 30, right: 10, left: 0, bottom: 20 }}>
182
  <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#f3f4f6" />
183
 
184
  <XAxis
 
191
  />
192
 
193
  <YAxis
194
+ domain={[0, 'auto']}
195
  tick={{fontSize: 10, fill: '#6b7280'}}
196
  axisLine={false}
197
  tickLine={false}
 
225
  shape={<CandleShape />}
226
  isAnimationActive={true}
227
  animationDuration={1500}
228
+ >
229
+ {/*
230
+ Only show label for the global Peak
231
+ We pass the computed maxHigh to the custom label component
232
+ */}
233
+ <LabelList
234
+ dataKey="high"
235
+ position="top"
236
+ content={<PeakLabel maxHigh={maxHigh} />}
237
+ />
238
+ </Bar>
239
 
240
  </ComposedChart>
241
  </ResponsiveContainer>
 
243
  );
244
  };
245
 
246
+ export default LifeKLineChart;