238 lines
9.0 KiB
Python
238 lines
9.0 KiB
Python
from dash import dcc, html
|
||
from pkg.config import interval_options, days_options, render_data
|
||
|
||
|
||
def layout_config(app):
|
||
app.layout = html.Div([
|
||
html.Div(
|
||
id='clock-container',
|
||
children=[
|
||
html.Div(
|
||
id='clock-button',
|
||
children='🕒',
|
||
style={
|
||
'fontSize': '24px',
|
||
'cursor': 'pointer',
|
||
'padding': '5px',
|
||
}
|
||
),
|
||
html.Div(
|
||
id='clock-tooltip',
|
||
children=[
|
||
html.Div(id='pst-clock')
|
||
],
|
||
style={
|
||
'position': 'absolute',
|
||
'left': '35px',
|
||
'top': '0px',
|
||
'backgroundColor': 'rgba(0, 0, 0, 0.8)',
|
||
'color': 'white',
|
||
'padding': '10px',
|
||
'borderRadius': '5px',
|
||
'fontSize': '14px',
|
||
'display': 'none',
|
||
'whiteSpace': 'nowrap'
|
||
}
|
||
),
|
||
html.Div(
|
||
id='play-button',
|
||
children='▶️',
|
||
n_clicks=0,
|
||
style={
|
||
'fontSize': '24px',
|
||
'cursor': 'pointer',
|
||
'padding': '5px',
|
||
'marginTop': '10px'
|
||
}
|
||
),
|
||
html.Div(
|
||
id='play-tooltip',
|
||
children=[],
|
||
style={
|
||
'position': 'absolute',
|
||
'left': '35px',
|
||
'top': '40px',
|
||
'backgroundColor': 'rgba(0, 0, 0, 0.8)',
|
||
'color': 'white',
|
||
'padding': '10px',
|
||
'borderRadius': '5px',
|
||
'fontSize': '14px',
|
||
'display': 'none',
|
||
'whiteSpace': 'nowrap'
|
||
}
|
||
),
|
||
html.Div(
|
||
id='info-button',
|
||
children='ℹ️',
|
||
style={
|
||
'fontSize': '24px',
|
||
'cursor': 'pointer',
|
||
'padding': '5px',
|
||
'marginTop': '10px'
|
||
}
|
||
),
|
||
html.Div(
|
||
id='info-tooltip',
|
||
children='这是一个信息按钮示例',
|
||
style={
|
||
'position': 'absolute',
|
||
'left': '35px',
|
||
'top': '80px',
|
||
'backgroundColor': 'rgba(0, 0, 0, 0.8)',
|
||
'color': 'white',
|
||
'padding': '10px',
|
||
'borderRadius': '5px',
|
||
'fontSize': '14px',
|
||
'display': 'none',
|
||
'whiteSpace': 'nowrap'
|
||
}
|
||
),
|
||
html.A(
|
||
href='https://x.com/elonmusk/with_replies',
|
||
target='_blank',
|
||
children=[
|
||
html.Img(
|
||
src='https://pbs.twimg.com/profile_images/1893803697185910784/Na5lOWi5_400x400.jpg',
|
||
style={
|
||
'height': '24px',
|
||
'width': '24px',
|
||
'cursor': 'pointer',
|
||
'padding': '5px',
|
||
'marginTop': '10px'
|
||
}
|
||
)
|
||
]
|
||
)
|
||
],
|
||
style={
|
||
'position': 'fixed',
|
||
'left': '10px',
|
||
'top': '50%',
|
||
'transform': 'translateY(-50%)',
|
||
'zIndex': 1000
|
||
}
|
||
),
|
||
# Main content
|
||
html.Div([
|
||
html.H1("Elon Musk Tweet Time Analysis (EST)"),
|
||
html.Div(id='date-picker-container', children=[
|
||
dcc.Dropdown(
|
||
id='multi-date-picker',
|
||
options=[{'label': str(date), 'value': str(date)} for date in render_data.all_dates],
|
||
value=render_data.default_date,
|
||
multi=True,
|
||
searchable=True,
|
||
placeholder="Search and select dates (YYYY-MM-DD)",
|
||
style={'width': '100%'}
|
||
)
|
||
]),
|
||
dcc.Dropdown(
|
||
id='multi-interval-picker',
|
||
options=interval_options,
|
||
value=10,
|
||
style={'width': '50%', 'marginTop': '10px'}
|
||
),
|
||
html.Div(id='days-display-container', style={'display': 'none'}, children=[
|
||
dcc.Dropdown(
|
||
id='days-display-picker',
|
||
options=days_options,
|
||
value=30,
|
||
style={'width': '50%', 'marginTop': '10px'}
|
||
)
|
||
]),
|
||
html.Div(id='multi-day-warning', style={'color': 'red', 'margin': '10px'}),
|
||
dcc.Checklist(
|
||
id='time-zone-checklist',
|
||
options=[
|
||
{'label': 'California Time (PST)', 'value': 'PST'},
|
||
{'label': 'Texas Time (CST)', 'value': 'CST'}
|
||
],
|
||
value=['PST'],
|
||
style={'margin': '10px'}
|
||
),
|
||
html.Div(id='multi-tweet-summary', style={'fontSize': '20px', 'margin': '10px'}),
|
||
dcc.Tabs(id='tabs', value='line', children=[
|
||
dcc.Tab(label='Line', value='line'),
|
||
dcc.Tab(label='Heatmap', value='heatmap'),
|
||
dcc.Tab(label='Heatmap(1-day)', value='one_day_heatmap'),
|
||
]),
|
||
html.Div(id='tabs-content'),
|
||
html.Table([
|
||
html.Tr([
|
||
html.Td("Target:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
dcc.Input(
|
||
id='target-input',
|
||
type='number',
|
||
placeholder='输入 Target 值',
|
||
value=None,
|
||
style={'width': '100%'}
|
||
)
|
||
)
|
||
]),
|
||
html.Tr([
|
||
html.Td("Predict Tweets:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
dcc.Input(
|
||
id='predict-tweets-input',
|
||
type='number',
|
||
placeholder='输入 Predict Tweets 值',
|
||
value=None,
|
||
style={'width': '100%'}
|
||
)
|
||
)
|
||
]),
|
||
html.Tr([
|
||
html.Td("Hour:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
dcc.Input(
|
||
id='hour-input',
|
||
type='number',
|
||
placeholder='输入 Hour 值',
|
||
value=None,
|
||
style={'width': '100%'}
|
||
)
|
||
)
|
||
]),
|
||
html.Tr([
|
||
html.Td("Predict Tweets Start:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
dcc.Input(
|
||
id='prob-start-input',
|
||
type='number',
|
||
placeholder='输入 Probability Start 值',
|
||
value=525,
|
||
style={'width': '100%'}
|
||
)
|
||
)
|
||
]),
|
||
html.Tr([
|
||
html.Td("Predict Tweets End:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
dcc.Input(
|
||
id='prob-end-input',
|
||
type='number',
|
||
placeholder='输入 Probability End 值',
|
||
value=549,
|
||
style={'width': '100%'}
|
||
)
|
||
)
|
||
]),
|
||
html.Tr([
|
||
html.Td("Calculate Probability:", style={'paddingRight': '10px'}),
|
||
html.Td(
|
||
html.Button('Calculate', id='update-button', n_clicks=0)
|
||
)
|
||
]),
|
||
html.Tr(id='manual-info-tooltip', style={'margin': '10px'})
|
||
], style={
|
||
'width': '50%',
|
||
'marginTop': '10px',
|
||
'borderCollapse': 'collapse'
|
||
})
|
||
], style={'marginLeft': '50px'}),
|
||
|
||
dcc.Interval(id='clock-interval', interval=1000, n_intervals=0)
|
||
])
|
||
return app
|