ui修改
This commit is contained in:
parent
e2ad47a13c
commit
8a4aa2c0c0
12926
cache/fixed.csv
vendored
12926
cache/fixed.csv
vendored
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
from dash import dcc, html
|
from dash import dcc, html
|
||||||
from pkg.config import interval_options,days_options,render_data
|
from pkg.config import interval_options, days_options, render_data
|
||||||
|
|
||||||
|
|
||||||
def layout_config(app):
|
def layout_config(app):
|
||||||
# Dash app layout (unchanged except default days value)
|
# Dash app layout (unchanged except default days value)
|
||||||
@ -61,6 +62,21 @@ def layout_config(app):
|
|||||||
'display': 'none',
|
'display': 'none',
|
||||||
'whiteSpace': 'nowrap'
|
'whiteSpace': 'nowrap'
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
html.A(
|
||||||
|
href='https://x.com/elonmusk',
|
||||||
|
children=[
|
||||||
|
html.Img(
|
||||||
|
src='https://pbs.twimg.com/profile_images/1893803697185910784/Na5lOWi5_400x400.jpg',
|
||||||
|
style={
|
||||||
|
'height': '24px', # Matches fontSize of other buttons
|
||||||
|
'width': '24px',
|
||||||
|
'cursor': 'pointer',
|
||||||
|
'padding': '5px',
|
||||||
|
'marginTop': '10px'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
style={
|
style={
|
||||||
@ -113,7 +129,7 @@ def layout_config(app):
|
|||||||
dcc.Tabs(id='tabs', value='line', children=[
|
dcc.Tabs(id='tabs', value='line', children=[
|
||||||
dcc.Tab(label='Line', value='line'),
|
dcc.Tab(label='Line', value='line'),
|
||||||
dcc.Tab(label='Heatmap', value='heatmap'),
|
dcc.Tab(label='Heatmap', value='heatmap'),
|
||||||
dcc.Tab(label='1-dayHeatmap', value='one_day_heatmap'),
|
dcc.Tab(label='Heatmap(1-day)', value='one_day_heatmap'),
|
||||||
]),
|
]),
|
||||||
html.Div(id='tabs-content'),
|
html.Div(id='tabs-content'),
|
||||||
], style={'marginLeft': '50px'}),
|
], style={'marginLeft': '50px'}),
|
||||||
|
@ -4,7 +4,6 @@ from .javascript import setting_callback
|
|||||||
import os
|
import os
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
# Initialize Dash app (unchanged)
|
|
||||||
external_stylesheets = ['assets/bWLwgP.css']
|
external_stylesheets = ['assets/bWLwgP.css']
|
||||||
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
|
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
|
||||||
app = layout_config(app)
|
app = layout_config(app)
|
||||||
|
@ -24,7 +24,6 @@ def update_clocks(n):
|
|||||||
'textAlign': 'left',
|
'textAlign': 'left',
|
||||||
'borderCollapse': 'collapse'
|
'borderCollapse': 'collapse'
|
||||||
})
|
})
|
||||||
|
|
||||||
return [table]
|
return [table]
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,19 +21,26 @@ import pandas as pd
|
|||||||
def render_tab_content(tab, selected_dates, interval, time_zones, days_to_display):
|
def render_tab_content(tab, selected_dates, interval, time_zones, days_to_display):
|
||||||
warning = ""
|
warning = ""
|
||||||
if tab == 'line':
|
if tab == 'line':
|
||||||
|
if not selected_dates: # Handle None or empty list
|
||||||
|
selected_dates = [datetime.now().date()] # Default to today
|
||||||
|
warning = "No dates selected. Showing today’s data."
|
||||||
if len(selected_dates) > 10:
|
if len(selected_dates) > 10:
|
||||||
selected_dates = selected_dates[:10]
|
selected_dates = selected_dates[:10]
|
||||||
warning = "Maximum of 10 days can be selected. Showing first 10 selected days."
|
warning = "Maximum of 10 days can be selected. Showing first 10 selected days."
|
||||||
selected_dates = [datetime.strptime(date, '%Y-%m-%d').date() for date in selected_dates]
|
selected_dates = [datetime.strptime(date, '%Y-%m-%d').date() for date in selected_dates]
|
||||||
else:
|
else:
|
||||||
selected_dates = sorted(render_data.global_agg_df['date'].unique(), reverse=True)[:days_to_display]
|
available_dates = sorted(render_data.global_agg_df['date'].unique(), reverse=True)
|
||||||
|
selected_dates = available_dates[:days_to_display] if available_dates else [datetime.now().date()]
|
||||||
|
if not available_dates:
|
||||||
|
warning = "No data available. Showing today’s date with zero tweets."
|
||||||
|
|
||||||
multi_data_agg = render_data.global_agg_df[render_data.global_agg_df['date'].isin(selected_dates)].copy()
|
multi_data_agg = render_data.global_agg_df[render_data.global_agg_df['date'].isin(selected_dates)].copy()
|
||||||
if multi_data_agg.empty:
|
if multi_data_agg.empty:
|
||||||
multi_data_agg = pd.DataFrame({'date': selected_dates, 'minute_of_day': [0] * len(selected_dates)})
|
multi_data_agg = pd.DataFrame({
|
||||||
tweet_count_total = 0
|
'date': selected_dates,
|
||||||
else:
|
'minute_of_day': [0] * len(selected_dates),
|
||||||
tweet_count_total = multi_data_agg['tweet_count'].sum()
|
})
|
||||||
|
tweet_count_total = multi_data_agg.get('tweet_count', pd.Series([0] * len(multi_data_agg))).sum()
|
||||||
|
|
||||||
multi_data_raw = render_data.global_df[render_data.global_df['date'].isin(selected_dates)].copy()
|
multi_data_raw = render_data.global_df[render_data.global_df['date'].isin(selected_dates)].copy()
|
||||||
if multi_data_raw.empty:
|
if multi_data_raw.empty:
|
||||||
|
16
pkg/tool.py
16
pkg/tool.py
@ -1,9 +1,16 @@
|
|||||||
|
from datetime import datetime
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
# Auxiliary functions (unchanged)
|
|
||||||
def aggregate_data(data, interval):
|
def aggregate_data(data, interval):
|
||||||
all_minutes = pd.DataFrame({'interval_group': range(0, 1440, interval)})
|
all_minutes = pd.DataFrame({'interval_group': range(0, 1440, interval)})
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
|
if data.empty or 'date' not in data.columns:
|
||||||
|
complete_data = all_minutes.copy()
|
||||||
|
complete_data['tweet_count'] = 0
|
||||||
|
complete_data['date'] = datetime.now().date()
|
||||||
|
return complete_data
|
||||||
|
|
||||||
for date in data['date'].unique():
|
for date in data['date'].unique():
|
||||||
day_data = data[data['date'] == date].copy()
|
day_data = data[data['date'] == date].copy()
|
||||||
day_data['interval_group'] = (day_data['minute_of_day'] // interval) * interval
|
day_data['interval_group'] = (day_data['minute_of_day'] // interval) * interval
|
||||||
@ -11,6 +18,13 @@ def aggregate_data(data, interval):
|
|||||||
complete_data = all_minutes.merge(agg, on='interval_group', how='left').fillna({'tweet_count': 0})
|
complete_data = all_minutes.merge(agg, on='interval_group', how='left').fillna({'tweet_count': 0})
|
||||||
complete_data['date'] = date
|
complete_data['date'] = date
|
||||||
result.append(complete_data)
|
result.append(complete_data)
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
complete_data = all_minutes.copy()
|
||||||
|
complete_data['tweet_count'] = 0
|
||||||
|
complete_data['date'] = data['date'].iloc[0] if not data.empty else datetime.now().date()
|
||||||
|
return complete_data
|
||||||
|
|
||||||
return pd.concat(result, ignore_index=True)
|
return pd.concat(result, ignore_index=True)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user