# server.py import matplotlib.pyplot as plt from shiny import render, ui, reactive import faicons as fa #from fontawesomefree import icons import numpy as np from utils import conlogo, vendorlogo from utils import create_pie_chart, create_bar_chart, create_bar_chart, create_stacked_bar_chart import plotly.express as px from utils import load_data, filter_trips from shinywidgets import output_widget, render_widget import plotly.graph_objects as go # Load the data zones, trips = load_data() def create_server(app_dir): def server(input, output, session): @render.image def rsglogo(): return conlogo() @render.image def clientlogo(): return vendorlogo() @render.plot def bar_chart(): # Sample data for bar chart categories = ["Category A", "Category B", "Category C"] values = [10, 20, 30] return create_bar_chart(categories, values, plottitle = "Bar Chart Example") @render.plot def pie_chart(): # Data for pie chart labels = ["Home-Based Work", "Home-Based Other", "Non-Home-Based"] #labels = [f"{icons['fa-car']} Cars", f"{icons['fa-bicycle']} Bikes", f"{icons['fa-bus']} Buses"] #labels = [f"{fa.icon_svg("briefcase")} Cars", f"{fa.icon_svg("briefcase")} Bikes", f"{fa.icon_svg("briefcase")} Buses"] sizes = [22, 41, 37] colors = ["#00b3b3", "#70d281", "#ff7f0e"] explode = (0.1, 0, 0) # Explode the first slice for emphasis return create_pie_chart(labels, sizes, plottitle ="What Types of Trips are Occuring within Napa County on a Weekday?") @render.plot def stacked_bar_chart(): # Data for the stacked bar chart categories = ["Early AM", "AM Peak", "Mid-Day", "PM Peak", "Evening"] intra_napa = [2000, 16000, 14000, 12000, 5000] into_napa = [1000, 8000, 2000, 3000, 2000] out_napa = [2000, 4000, 2000, 5000, 1000] return create_stacked_bar_chart(categories, intra_napa, into_napa, out_napa) # Reactive values to track selections selected_origin = reactive.Value(None) selected_destination = reactive.Value(None) @reactive.Effect #@reactive.event(input) @reactive.event(input.origin_map_click, input.destination_map_click) def update_selections(): """Update selections when a map is clicked.""" selected_origin.set(input.origin_map_click.get("customdata")) selected_destination.set(input.destination_map_click.get("customdata")) @reactive.Calc def filtered_data(): """Filter trips based on selected origin or destination.""" return filter_trips(trips, zones, selected_origin.get(), selected_destination.get()) @output #@render.plot #@render.ui @render_widget def origin_map(): filtered_origins, _ = filtered_data() fig = px.choropleth( filtered_origins, geojson=filtered_origins.geometry, locations=filtered_origins.index, color="trip_count", title="Trip Origins", custom_data=["FPID"], #mapbox_style="open-street-map", #zoom=7.5, #center={"lat": filtered_origins.geometry.centroid.y.mean(), "lon": filtered_origins.geometry.centroid.x.mean()}, #opacity=0.7, # color_continuous_scale="amp", # labels={ # "Zone ID": "FPID", # "Trips": "trip_count" # } ) fig.update_geos(fitbounds="locations", visible=False) #fig.update_layout(coloraxis_colorbar=dict(title="Trip Count")) # Add legend return fig #return ui.HTML(fig.to_html()) #return ui.HTML(fig.to_html(full_html=False, include_plotlyjs="cdn")) @output #@render.plot #@render.ui @render_widget def destination_map(): _, filtered_destinations = filtered_data() fig = px.choropleth( filtered_destinations, geojson=filtered_destinations.geometry, locations=filtered_destinations.index, color="trip_count", title="Trip Destinations", custom_data=["FPID"] ) fig.update_geos(fitbounds="locations", visible=False) #fig.update_layout(coloraxis_colorbar=dict(title="Trip Count")) # Add legend return fig #return ui.HTML(fig.to_html()) #return ui.HTML(fig.to_html(full_html=False, include_plotlyjs="cdn")) return server