import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import pandas as pd
import numpy as np
import altair as alt
import vega_datasets

alt.data_transformers.enable('default')
alt.data_transformers.disable_max_rows()
app = dash.Dash(__name__, assets_folder='assets', external_stylesheets=[dbc.themes.BOOTSTRAP])
# Boostrap CSS.
app.css.append_css({'external_url': 'https://codepen.io/amyoshino/pen/jzXypZ.css'})  # noqa: E501
server = app.server
app.title = 'Dash app with pure Altair HTML'

df = pd.read_csv('data/Police_Department_Incidents_-_Previous_Year__2016_.csv')

# df = pd.read_csv("https://raw.github.ubc.ca/MDS-2019-20/DSCI_531_lab4_anas017/master/data/Police_Department_Incidents_-_Previous_Year__2016_.csv?token=AAAHQ0dLxUd74i7Zhzh1SJ_UuOaFVI3_ks5d5dT3wA%3D%3D")
df['datetime'] = pd.to_datetime(df[["Date","Time"]].apply(lambda x: x[0].split()[0] +" "+x[1], axis=1), format="%m/%d/%Y %H:%M")
df['hour'] = df['datetime'].dt.hour     
df.dropna(inplace=True)
top_4_crimes = df['Category'].value_counts()[:6].index.to_list()
top_4_crimes
top_4_crimes.remove("NON-CRIMINAL")
top_4_crimes.remove("OTHER OFFENSES")
# top 4 crimes df subset
df_t4 = df[df["Category"].isin(top_4_crimes)].copy()

def make_plot_top(df_new=df_t4):
    
    # Create a plot of the Displacement and the Horsepower of the cars dataset
    # making the slider
    slider = alt.binding_range(min = 0, max = 23, step = 1)
    select_hour = alt.selection_single(name='select', fields = ['hour'],
                                    bind = slider, init={'hour': 0})

    #begin of my code
    # typeDict = {'ASSAULT':'quantitative',
    #             'VANDALISM':'quantitative',
    #             'LARCENY/THEFT':'quantitative',
    #             'VEHICLE THEFT':'quantitative'
    # }
    # end
    
    chart = alt.Chart(df_new).mark_bar(size=30).encode(
        x=alt.X('Category',type='nominal', title='Category'),
        y=alt.Y('count()', title = "Count" , scale = alt.Scale(domain = (0,3300))),
        tooltip='count()'
    ).properties(
        title = "Per hour crime occurrences for the top 4 crimes",
        width=500,
        height = 315
    ).add_selection(
        select_hour
    ).transform_filter(
        select_hour
    )
    return chart

def make_plot_bot(data=df_t4):
    chart_1 = alt.Chart(data).mark_circle(size=3, opacity = 0.8).encode(
        longitude='X:Q',
        latitude='Y:Q',
        color = alt.Color('PdDistrict:N', legend = alt.Legend(title = "District")),
        tooltip = 'PdDistrict'
    ).project(
        type='albersUsa'
    ).properties(
        width=450,
        height=350
    )

    chart_2 = alt.Chart(data).mark_bar().encode(
        x=alt.X('PdDistrict:N', axis=None, title="District"),
        y=alt.Y('count()', title="Count of reports"),
        color=alt.Color('PdDistrict:N', legend=alt.Legend(title="District")),
        tooltip=['PdDistrict', 'count()']
    ).properties(
        width=450,
        height=350
    )

    # A dropdown filter
    crimes_dropdown = alt.binding_select(options=list(data['Category'].unique()))
    crimes_select = alt.selection_single(fields=['Category'], bind=crimes_dropdown,
                                              name="Pick\ Crime")

    combine_chart = (chart_2 | chart_1)

    filter_crimes = combine_chart.add_selection(
        crimes_select
    ).transform_filter(
        crimes_select
    )

    return filter_crimes  

body = dbc.Container(
    [
        dbc.Row(
            [
                dbc.Col(
                    [
                        html.H2("San Francisco Crime"),
                        html.P(
                            """\
                            When looking for a place to live or visit, one important factor that people will consider
                            is the safety of the neighborhood. Searching that information district
                            by district could be time consuming and exhausting. It is even more difficult to
                            compare specific crime statistics across districts such as the crime rate
                            at a certain time of day. It would be useful if people can look up crime
                            related information across district on one application. Our app
                            aims to help people make decisions when considering their next trip or move to San Francisco, California
                            via visually exploring a dataset of crime statistics. The app provides an overview of the crime rate across
                            neighborhoods and allows users to focus on more specific information through
                            filtering of geological location, crime rate, crime type or time of the
                            crime.

                            Use the box below to choose crimes of interest.
                            """
                        ),
                        dcc.Dropdown(
                                    id = 'drop_selection_crime',
                                    options=[{'label': i, 'value': i} for i in df_t4['Category'].unique()
                                    ],
                                    style={'height': '20px',
                                        'width': '400px'},
                                    value=df_t4['Category'].unique(),
                                    multi=True)
                    ],
                    md=5,
                ),
                dbc.Col(
                    [
                        dbc.Row(
                            [
                                html.Iframe(
                                    sandbox = "allow-scripts",
                                    id = "plot_top",
                                    height = "500",
                                    width = "650",
                                    style = {"border-width": "0px"},
                                    srcDoc = make_plot_top().to_html()
                                    )
                            ]
                        )
                    ]
                ),
            ]
        ),
        dbc.Row(
            html.Iframe(
                sandbox='allow-scripts',
                id='plot_bot',
                height='500',
                width='1200',
                style={'border-width': '0px'},
                srcDoc= make_plot_bot().to_html()
                )
        )
    ],
    className="mt-4",
)

app.layout = html.Div(body)

@app.callback([dash.dependencies.Output('plot_top', 'srcDoc'),
    dash.dependencies.Output('plot_bot', 'srcDoc')],
    [dash.dependencies.Input('drop_selection_crime', 'value')]
    )
def update_df(chosen):
    new_df = df_t4[(df_t4["Category"].isin(chosen))]
    updated_plot_top = make_plot_top(new_df).to_html()
    updated_plot_bottom = make_plot_bot(new_df).to_html()

    return updated_plot_top, updated_plot_bottom

if __name__ == '__main__':
    app.run_server(debug=False)
[((10, 0, 10, 39), 'altair.data_transformers.enable', 'alt.data_transformers.enable', ({(10, 29, 10, 38): '"""default"""'}, {}), "('default')", True, 'import altair as alt\n'), ((11, 0, 11, 40), 'altair.data_transformers.disable_max_rows', 'alt.data_transformers.disable_max_rows', ({}, {}), '()', True, 'import altair as alt\n'), ((12, 6, 12, 94), 'dash.Dash', 'dash.Dash', (), '', False, 'import dash\n'), ((18, 5, 18, 79), 'pandas.read_csv', 'pd.read_csv', ({(18, 17, 18, 78): '"""data/Police_Department_Incidents_-_Previous_Year__2016_.csv"""'}, {}), "('data/Police_Department_Incidents_-_Previous_Year__2016_.csv')", True, 'import pandas as pd\n'), ((167, 13, 167, 27), 'dash_html_components.Div', 'html.Div', ({(167, 22, 167, 26): 'body'}, {}), '(body)', True, 'import dash_html_components as html\n'), ((35, 13, 35, 59), 'altair.binding_range', 'alt.binding_range', (), '', True, 'import altair as alt\n'), ((36, 18, 37, 68), 'altair.selection_single', 'alt.selection_single', (), '', True, 'import altair as alt\n'), ((87, 20, 88, 65), 'altair.selection_single', 'alt.selection_single', (), '', True, 'import altair as alt\n'), ((169, 15, 169, 61), 'dash.dependencies.Output', 'dash.dependencies.Output', ({(169, 40, 169, 50): '"""plot_top"""', (169, 52, 169, 60): '"""srcDoc"""'}, {}), "('plot_top', 'srcDoc')", False, 'import dash\n'), ((170, 4, 170, 50), 'dash.dependencies.Output', 'dash.dependencies.Output', ({(170, 29, 170, 39): '"""plot_bot"""', (170, 41, 170, 49): '"""srcDoc"""'}, {}), "('plot_bot', 'srcDoc')", False, 'import dash\n'), ((171, 5, 171, 61), 'dash.dependencies.Input', 'dash.dependencies.Input', ({(171, 29, 171, 51): '"""drop_selection_crime"""', (171, 53, 171, 60): '"""value"""'}, {}), "('drop_selection_crime', 'value')", False, 'import dash\n'), ((76, 10, 76, 60), 'altair.X', 'alt.X', (), '', True, 'import altair as alt\n'), ((77, 10, 77, 52), 'altair.Y', 'alt.Y', (), '', True, 'import altair as alt\n'), ((106, 24, 106, 54), 'dash_html_components.H2', 'html.H2', ({(106, 32, 106, 53): '"""San Francisco Crime"""'}, {}), "('San Francisco Crime')", True, 'import dash_html_components as html\n'), ((107, 24, 123, 25), 'dash_html_components.P', 'html.P', ({(108, 28, 122, 31): '"""                            When looking for a place to live or visit, one important factor that people will consider\n                            is the safety of the neighborhood. Searching that information district\n                            by district could be time consuming and exhausting. It is even more difficult to\n                            compare specific crime statistics across districts such as the crime rate\n                            at a certain time of day. It would be useful if people can look up crime\n                            related information across district on one application. Our app\n                            aims to help people make decisions when considering their next trip or move to San Francisco, California\n                            via visually exploring a dataset of crime statistics. The app provides an overview of the crime rate across\n                            neighborhoods and allows users to focus on more specific information through\n                            filtering of geological location, crime rate, crime type or time of the\n                            crime.\n\n                            Use the box below to choose crimes of interest.\n                            """'}, {}), '(\n    """                            When looking for a place to live or visit, one important factor that people will consider\n                            is the safety of the neighborhood. Searching that information district\n                            by district could be time consuming and exhausting. It is even more difficult to\n                            compare specific crime statistics across districts such as the crime rate\n                            at a certain time of day. It would be useful if people can look up crime\n                            related information across district on one application. Our app\n                            aims to help people make decisions when considering their next trip or move to San Francisco, California\n                            via visually exploring a dataset of crime statistics. The app provides an overview of the crime rate across\n                            neighborhoods and allows users to focus on more specific information through\n                            filtering of geological location, crime rate, crime type or time of the\n                            crime.\n\n                            Use the box below to choose crimes of interest.\n                            """\n    )', True, 'import dash_html_components as html\n'), ((75, 14, 75, 29), 'altair.Chart', 'alt.Chart', ({(75, 24, 75, 28): 'data'}, {}), '(data)', True, 'import altair as alt\n'), ((78, 47, 78, 75), 'altair.Legend', 'alt.Legend', (), '', True, 'import altair as alt\n'), ((48, 10, 48, 60), 'altair.X', 'alt.X', (), '', True, 'import altair as alt\n'), ((63, 14, 63, 29), 'altair.Chart', 'alt.Chart', ({(63, 24, 63, 28): 'data'}, {}), '(data)', True, 'import altair as alt\n'), ((66, 51, 66, 81), 'altair.Legend', 'alt.Legend', (), '', True, 'import altair as alt\n'), ((47, 12, 47, 29), 'altair.Chart', 'alt.Chart', ({(47, 22, 47, 28): 'df_new'}, {}), '(df_new)', True, 'import altair as alt\n'), ((49, 53, 49, 81), 'altair.Scale', 'alt.Scale', (), '', True, 'import altair as alt\n')]