1+ import reflex as rx
2+ from typing import List
3+ from stock_market_dashboard .states .trading_state import TradingState , StockInfo
4+ from stock_market_dashboard .components .tooltip_props import TOOLTIP_PROPS
5+
6+
7+ def stock_info_header (stock : StockInfo ) -> rx .Component :
8+ return rx .el .div (
9+ rx .el .div (
10+ rx .el .h2 (
11+ stock ["symbol" ],
12+ class_name = "text-xl font-bold text-white" ,
13+ ),
14+ rx .el .span (
15+ stock ["price" ].to_string (),
16+ class_name = "text-xl font-semibold text-white mr-2" ,
17+ ),
18+ rx .el .span (
19+ stock ["change" ].to_string (),
20+ class_name = rx .cond (
21+ stock ["change" ] >= 0 ,
22+ "text-green-400" ,
23+ "text-red-400" ,
24+ ),
25+ ),
26+ rx .el .span (
27+ stock ["change_percent" ].to_string (),
28+ class_name = rx .cond (
29+ stock ["change" ] >= 0 ,
30+ "text-green-400 text-sm ml-1" ,
31+ "text-red-400 text-sm ml-1" ,
32+ ),
33+ ),
34+ class_name = "flex items-baseline gap-2" ,
35+ ),
36+ rx .el .div (
37+ rx .el .button (
38+ "Buy" ,
39+ class_name = "bg-green-500 hover:bg-green-600 text-white text-xs font-bold py-1 px-4 rounded mr-2" ,
40+ ),
41+ rx .el .button (
42+ "Sell" ,
43+ class_name = "bg-red-500 hover:bg-red-600 text-white text-xs font-bold py-1 px-4 rounded" ,
44+ ),
45+ rx .el .span (
46+ stock ["open" ].to_string (),
47+ class_name = "text-xs text-gray-400 ml-4" ,
48+ ),
49+ rx .el .span (
50+ stock ["high" ].to_string (),
51+ class_name = "text-xs text-gray-400 ml-2" ,
52+ ),
53+ rx .el .span (
54+ stock ["low" ].to_string (),
55+ class_name = "text-xs text-gray-400 ml-2" ,
56+ ),
57+ rx .el .span (
58+ stock ["close" ].to_string (),
59+ class_name = "text-xs text-gray-400 ml-2" ,
60+ ),
61+ rx .el .span (
62+ f"V { stock ['volume' ]} " ,
63+ class_name = "text-xs text-gray-400 ml-2" ,
64+ ),
65+ class_name = "flex items-center mt-1" ,
66+ ),
67+ class_name = "mb-3" ,
68+ )
69+
70+
71+ def chart_controls () -> rx .Component :
72+ return rx .el .div (
73+ rx .el .div (
74+ rx .foreach (
75+ ["1D" , "1W" , "1M" , "3M" , "1Y" , "5Y" , "All" ],
76+ lambda item : rx .el .button (
77+ item ,
78+ class_name = "text-xs text-gray-400 hover:text-white px-2 py-1 rounded hover:bg-gray-700" ,
79+ ),
80+ ),
81+ class_name = "flex space-x-1" ,
82+ ),
83+ rx .el .div (
84+ rx .el .span (
85+ "Interval: 1h" ,
86+ class_name = "text-xs text-gray-400 mr-3" ,
87+ ),
88+ rx .el .button (
89+ "Auto-scale" ,
90+ class_name = "text-xs text-gray-400 hover:text-white px-2 py-1 rounded hover:bg-gray-700" ,
91+ ),
92+ class_name = "flex items-center" ,
93+ ),
94+ class_name = "flex justify-between items-center mt-2 px-2" ,
95+ )
96+
97+
98+ def trading_line_chart () -> rx .Component :
99+ min_price = rx .Var .create (
100+ f"Math.min(...{ TradingState .chart_data .to_string ()} .map(p => p.price))"
101+ ).to (int )
102+ max_price = rx .Var .create (
103+ f"Math.max(...{ TradingState .chart_data .to_string ()} .map(p => p.price))"
104+ ).to (int )
105+ padding = (max_price - min_price ) * 0.1
106+ y_domain = rx .Var .create (
107+ f"[{ min_price } - { padding } , { max_price } + { padding } ]"
108+ )
109+ return rx .el .div (
110+ stock_info_header (TradingState .stock_info ),
111+ rx .recharts .line_chart (
112+ rx .recharts .cartesian_grid (
113+ stroke_dasharray = "3 3" ,
114+ stroke = "#4b5563" ,
115+ horizontal = True ,
116+ vertical = False ,
117+ ),
118+ rx .recharts .graphing_tooltip (** TOOLTIP_PROPS ),
119+ rx .recharts .line (
120+ data_key = "price" ,
121+ stroke = "#22c55e" ,
122+ dot = False ,
123+ type_ = "monotone" ,
124+ stroke_width = 2 ,
125+ is_animation_active = False ,
126+ ),
127+ rx .recharts .x_axis (
128+ data_key = "time" ,
129+ axis_line = False ,
130+ tick_line = False ,
131+ stroke = "#9ca3af" ,
132+ tick_size = 10 ,
133+ tick_count = 6 ,
134+ interval = "preserveStartEnd" ,
135+ padding = {"left" : 10 , "right" : 10 },
136+ custom_attrs = {"fontSize" : "10px" },
137+ ),
138+ rx .recharts .y_axis (
139+ domain = y_domain ,
140+ axis_line = False ,
141+ tick_line = False ,
142+ stroke = "#9ca3af" ,
143+ orientation = "right" ,
144+ tick_formatter = "function(value) { return `$${value.toFixed(2)}`; }" ,
145+ width = 55 ,
146+ allow_decimals = True ,
147+ custom_attrs = {"fontSize" : "10px" },
148+ ),
149+ data = TradingState .chart_data ,
150+ margin = {
151+ "top" : 5 ,
152+ "right" : 0 ,
153+ "left" : 0 ,
154+ "bottom" : 5 ,
155+ },
156+ height = 250 ,
157+ width = "100%" ,
158+ ),
159+ chart_controls (),
160+ class_name = "bg-gray-800 p-4 rounded-lg border border-gray-700 flex-grow" ,
161+ )
0 commit comments