import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output, State
# Load data from a public URL
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
df = pd.read_csv(url)
# Filter the dataset for necessary columns and clean it
df = df[['Country Name', 'Year', 'Value']]
df.columns = ['Country', 'Year', 'GDP']
# Initialize the Dash app
app = dash.Dash(__name__)
# Layout of the app
app.layout = html.Div([
    html.H1("Global GDP Trends Dashboard"),
    
    # Dropdown for selecting countries
    html.Div([
        html.Label("Select Countries:"),
        dcc.Dropdown(
            id='country-dropdown',
            options=[{'label': country, 'value': country} for country in df['Country'].unique()],
            value=['United States', 'China'],
            multi=True
        )
    ]),
    
    # 2x2 Grid for Charts
    html.Div([
        html.Div([dcc.Graph(id='bubble-chart')], style={'width': '48%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='histogram')], style={'width': '48%', 'display': 'inline-block'}),
    ], style={'display': 'flex', 'justify-content': 'space-between'}),
    
    html.Div([
        html.Div([dcc.Graph(id='line-chart')], style={'width': '48%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='bar-chart')], style={'width': '48%', 'display': 'inline-block'}),
    ], style={'display': 'flex', 'justify-content': 'space-between'}),
    
    # Text description at the bottom
    html.Div([
        html.H3("Trends Description"),
        html.P(
            "The dashboard above visualizes global GDP trends across different countries. "
            "The bubble chart shows the relationship between GDP and population size over the years. "
            "The histogram represents the distribution of GDP among the selected countries. "
            "The line chart illustrates the trend of GDP over time for each selected country. "
            "Lastly, the bar chart highlights the top 10 countries by GDP in the most recent year available."
        )
    ])
])
# Function to update the layout of each chart
def update_chart_layout(fig):
    fig.update_layout(
        legend=dict(
            orientation='h',
            yanchor='bottom',
            y=1.02,
            xanchor='right',
            x=1
        ),
        margin=dict(l=0, r=0, t=0, b=0)
    )
    return fig
# Callback for updating the Bubble Chart
@app.callback(
    Output('bubble-chart', 'figure'),
    [Input('country-dropdown', 'value')]
)
def update_bubble_chart(selected_countries):
    filtered_df = df[df['Country'].isin(selected_countries)]
    fig = px.scatter(filtered_df, x='Year', y='GDP', size='GDP', color='Country',
                     hover_name='Country', size_max=60)
    fig.update_layout(clickmode='event+select', dragmode='select')
    return update_chart_layout(fig)
# Callback for updating the Histogram
@app.callback(
    Output('histogram', 'figure'),
    [Input('country-dropdown', 'value'),
     Input('bubble-chart', 'selectedData')]
)
def update_histogram(selected_countries, selectedData):
    filtered_df = df[df['Country'].isin(selected_countries)]
    if selectedData:
        selected_years = [point['x'] for point in selectedData['points']]
        filtered_df = filtered_df[filtered_df['Year'].isin(selected_years)]
    fig = px.histogram(filtered_df, x='GDP', color='Country', barmode='overlay')
    return update_chart_layout(fig)
# Callback for updating the Line Chart
@app.callback(
    Output('line-chart', 'figure'),
    [Input('country-dropdown', 'value'),
     Input('bubble-chart', 'selectedData')]
)
def update_line_chart(selected_countries, selectedData):
    filtered_df = df[df['Country'].isin(selected_countries)]
    if selectedData:
        selected_years = [point['x'] for point in selectedData['points']]
        filtered_df = filtered_df[filtered_df['Year'].isin(selected_years)]
    fig = px.line(filtered_df, x='Year', y='GDP', color='Country')
    return update_chart_layout(fig)
# Callback for updating the Bar Chart
@app.callback(
    Output('bar-chart', 'figure'),
    [Input('country-dropdown', 'value'),
     Input('bubble-chart', 'selectedData')]
)
def update_bar_chart(selected_countries, selectedData):
    latest_year = df['Year'].max()
    filtered_df = df[(df['Country'].isin(selected_countries)) & (df['Year'] == latest_year)]
    if selectedData:
        selected_years = [point['x'] for point in selectedData['points']]
        filtered_df = filtered_df[filtered_df['Year'].isin(selected_years)]
    fig = px.bar(filtered_df, x='Country', y='GDP', color='Country', title=f"Top 10 Countries by GDP in {latest_year}")
    return update_chart_layout(fig)
# Run the app
if __name__ == '__main__':
    app.run_server(debug=True)