diff --git a/pkg/dash/app_html.py b/pkg/dash/app_html.py
index 79a06f6..a555414 100644
--- a/pkg/dash/app_html.py
+++ b/pkg/dash/app_html.py
@@ -113,7 +113,7 @@ def layout_config(app):
dcc.Tabs(id='tabs', value='line', children=[
dcc.Tab(label='Line Chart', value='line'),
dcc.Tab(label='Heatmap', value='heatmap'),
- dcc.Tab(label='Scatter Plot', value='scatter'),
+ dcc.Tab(label='One Day Heatmap Plot', value='one_day_heatmap'),
]),
html.Div(id='tabs-content'),
], style={'marginLeft': '50px'}),
diff --git a/pkg/dash/func/render.py b/pkg/dash/func/render.py
index 03a9a7d..f7b9c08 100644
--- a/pkg/dash/func/render.py
+++ b/pkg/dash/func/render.py
@@ -2,12 +2,12 @@ from datetime import datetime, timedelta
from dash.dependencies import Input, Output
from pkg.dash.app_init import app
from pkg.config import render_data
-from pkg.tool import aggregate_data,generate_xticks,minutes_to_time
+from pkg.tool import aggregate_data, generate_xticks, minutes_to_time
from dash import dcc
import plotly.graph_objs as go
import pandas as pd
-# Callback for updating tabs content (Modified to add Thursday-Friday lines)
+
@app.callback(
[Output('tabs-content', 'children'),
Output('multi-day-warning', 'children'),
@@ -20,7 +20,7 @@ import pandas as pd
)
def render_tab_content(tab, selected_dates, interval, time_zones, days_to_display):
warning = ""
- if tab != 'heatmap':
+ if tab == 'line':
if len(selected_dates) > 10:
selected_dates = selected_dates[:10]
warning = "Maximum of 10 days can be selected. Showing first 10 selected days."
@@ -81,52 +81,66 @@ def render_tab_content(tab, selected_dates, interval, time_zones, days_to_displa
xref="x",
yref="paper"
)
- fig.update_layout(
- title=f'Tweet Heatmap (Interval: {interval} minutes, EST, {len(selected_dates)} days)',
- xaxis_title='Time of Day (HH:MM EST)',
- yaxis_title='Date',
- height=max(400, len(selected_dates) * 20),
- yaxis=dict(autorange='reversed')
- )
+ fig.update_layout(
+ title=f'Tweet Heatmap (Interval: {interval} minutes, EST, {len(selected_dates)} days)',
+ xaxis_title='Time of Day (HH:MM EST)',
+ yaxis_title='Date',
+ height=max(400, len(selected_dates) * 20),
+ yaxis=dict(autorange='reversed')
+ )
- elif tab == 'scatter':
- fig = go.Figure()
- for date in selected_dates:
- day_data = multi_data_raw[multi_data_raw['date'] == date]
- if not day_data.empty:
- hover_times = [t.strftime('%Y-%m-%d %H:%M:%S EST') for t in day_data['datetime_est']]
- fig.add_trace(go.Scatter(
- x=day_data['minute_of_day'],
- y=[str(date)] * len(day_data),
- mode='markers',
- name=str(date),
- customdata=hover_times,
- hovertemplate='%{customdata}',
- marker=dict(size=8)
- ))
+ elif tab == 'one_day_heatmap':
+ one_day_data = agg_data.groupby('interval_group')['tweet_count'].sum().reset_index()
- if tab in ['line', 'scatter']:
+ hours = list(range(24))
+ intervals_per_hour = 60 // interval
+ z_values = [[0] * intervals_per_hour for _ in range(24)]
+
+ for _, row in one_day_data.iterrows():
+ minute = row['interval_group']
+ hour = int(minute // 60) # Convert to integer
+ interval_idx = int((minute % 60) // interval) # Convert to integer
+ if hour < 24:
+ z_values[hour][interval_idx] = row['tweet_count']
+
+ x_labels = [f"{i * interval:02d}" for i in range(intervals_per_hour)]
+
+ fig = go.Figure(data=go.Heatmap(
+ z=z_values,
+ x=x_labels,
+ y=[f"{h:02d}:00" for h in hours],
+ colorscale='Viridis',
+ hoverongaps=False,
+ hovertemplate='%{y} %{x} EST
Tweets: %{z}'
+ ))
+
+ # Add time zone annotations if selected
if 'PST' in time_zones:
- pacific_2am_est = (2 + 3) * 60
- pacific_7am_est = (7 + 3) * 60
+ pacific_2am_est = (2 + 3) * 60 // interval
+ pacific_7am_est = (7 + 3) * 60 // interval
fig.add_vline(x=pacific_2am_est, line_dash="dash", line_color="blue", annotation_text="CA 2AM PST")
fig.add_vline(x=pacific_7am_est, line_dash="dash", line_color="blue", annotation_text="CA 7AM PST")
if 'CST' in time_zones:
- central_2am_est = (2 + 1) * 60
- central_7am_est = (7 + 1) * 60
+ central_2am_est = (2 + 1) * 60 // interval
+ central_7am_est = (7 + 1) * 60 // interval
fig.add_vline(x=central_2am_est, line_dash="dash", line_color="green", annotation_text="TX 2AM CST")
fig.add_vline(x=central_7am_est, line_dash="dash", line_color="green", annotation_text="TX 7AM CST")
- if tab in ['line', 'scatter']:
+ if tab in ['line', 'one_day_heatmap']:
fig.update_layout(
- title=f'{"Line" if tab == "line" else "Scatter"} Tweet Frequency (Interval: {interval} minutes, EST)',
- xaxis_title='Eastern Time (HH:MM)',
- yaxis_title='Tweet Count' if tab == 'line' else 'Date',
- xaxis=dict(range=[0, 1440], tickvals=xticks, ticktext=xtick_labels, tickangle=45),
+ title=f'{"Line" if tab == "line" else "One-Day Heatmap"} Tweet Frequency (Interval: {interval} minutes, EST, {len(selected_dates)} days)',
+ xaxis_title='Minutes' if tab == 'one_day_heatmap' else 'Eastern Time (HH:MM)',
+ yaxis_title='Hour of Day' if tab == 'one_day_heatmap' else 'Tweet Count',
+ xaxis=dict(
+ range=[0, 1440] if tab == 'line' else None,
+ tickvals=xticks if tab == 'line' else None,
+ ticktext=xtick_labels if tab == 'line' else None,
+ tickangle=45 if tab == 'line' else 0
+ ),
height=600,
- showlegend=True,
- yaxis=dict(autorange='reversed') if tab == 'scatter' else None
+ showlegend=(tab == 'line'),
+ yaxis=dict(autorange='reversed') if tab == 'one_day_heatmap' else None
)
summary = f"Total tweets for selected dates: {int(tweet_count_total)}"
- return dcc.Graph(figure=fig), warning, summary
+ return dcc.Graph(figure=fig), warning, summary
\ No newline at end of file
diff --git a/pkg/dash/func/ui.py b/pkg/dash/func/ui.py
index c4b19cb..f447ff0 100644
--- a/pkg/dash/func/ui.py
+++ b/pkg/dash/func/ui.py
@@ -1,12 +1,14 @@
from pkg.dash.app_init import app
from dash.dependencies import Input, Output
+
@app.callback(
[Output('date-picker-container', 'style'),
- Output('days-display-container', 'style')],
+ Output('days-display-container', 'style'),
+ Output('time-zone-checklist', 'style')],
[Input('tabs', 'value')]
)
def toggle_controls_visibility(tab):
- if tab == 'heatmap':
- return {'display': 'none'}, {'display': 'block'}
- return {'display': 'block'}, {'display': 'none'}
\ No newline at end of file
+ if tab == 'heatmap' or tab == 'one_day_heatmap':
+ return {'display': 'none'}, {'display': 'block'}, {'display': 'none'}
+ return {'display': 'block'}, {'display': 'none'}, {'display': 'block'}