cari

Rumah  >  Soal Jawab  >  teks badan

Bagaimanakah cara saya menukar kandungan bekas yang berbeza dalam apl sengkang?

Saya mengalami kesukaran untuk melakukan perkara berikut. Saya mempunyai aplikasi dash yang diformatkan oleh css untuk dipaparkan dalam bekas yang berbeza. Bekas berlabel "hexgrid-1-container" ialah bekas terbesar, manakala bekas lain lebih kecil dan teratur di sekelilingnya. Saya ingin mengemas kini apl dash saya supaya setiap kali saya mengklik pada rajah/grafik dalam bekas lain, ia muncul dalam "hexgrid-1-container" manakala rajah sebelumnya dalam "hexgrid-1-container" Bekas akan muncul dalam bekas yang lebih kecil .

Saya mempunyai apl dash seperti ini:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import sqlite3
import locale
import numpy as np
import plotly.figure_factory as ff
import plotly.express as px

# Set the locale for formatting
locale.setlocale(locale.LC_ALL, '')
app = dash.Dash(__name__)
app.layout = html.Div(className= 'container glass', children=[
    html.Div(className='hexgrid-1-container', style={'border': '1px solid black'}, children=[
        dcc.Graph(id='hexgrid-1', style={"height": "75%", "width": "100%"}, className='hexgrid1')
    ]),

    html.Div(className='hexgrid-2-container', style={'border': '1px solid black'}, children=[
        dcc.Graph(id='hexgrid-2', style={"height": "100%", "width": "100%"}, className='hexgrid2')
    ]),

    html.Div(className='base-plot-container', style={'border': '1px solid black'}, children=[
        dcc.Graph(id='base-plot', style={"height": "100%", "width": "100%"})
    ]),

    html.Div(className='us-map-container', style={'border': '1px solid black'}, children=[
        dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"})
    ]),

    html.Div(className='fifth-container', style={'border': '1px solid black'}, children=[
        # dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"})
        #html.H2("5th Container")
    ]),

    html.Div(className='sixth-container', style={'border': '1px solid black'}, children=[
        # dcc.Graph(id='us-map-graph', style={"height": "100%", "width": "100%"})
        #html.H2("6th Container")
    ])
])


@app.callback(
    Output('hexgrid-1', 'figure'),
    Input('hexgrid-1', 'id')
)

def render_hexgrid_1(_):
    # Open a new database connection
    conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")
    
    # Fetching all columns in the transactions table
    query = '''
        PRAGMA table_info(transactions)
    '''
    
    # Fetch data
    data = pd.read_sql_query(query, conn)
    
    # Filtering out the relevant columns, this step can be skipped if you want all columns.
    relevant_columns = data[data['name'].isin(['TranType', 'MessageTypeIdentifier', 'MerchantType', 'IResponseCode'])]
    
    # Creating the hex grid with column names
    plot_data = go.Scatter(x=relevant_columns.index, y=relevant_columns['name'], text=relevant_columns['name'],
                           marker=dict(symbol='hexagon', size=30), mode='markers+text')
    layout = go.Layout(title="Select a Category")
    return go.Figure(data=[plot_data], layout=layout)
@app.callback(
    Output('hexgrid-2', 'figure'),
    Output('hexgrid-2', 'style'),
    Input('hexgrid-1', 'clickData')
)
def render_hexgrid_2(clickData):
    # Open a new database connection
    conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")
    
    if clickData is None:
        return go.Figure(), {"display": "none"}
    else:
        category = clickData['points'][0]['text']
        
        # Fetching all columns in the transactions table
        query = '''
            PRAGMA table_info(transactions)
        '''
        
        # Fetch data
        data = pd.read_sql_query(query, conn)
        
        # Filtering out the relevant numerical features columns
        relevant_columns = data[data['name'].isin(['TransactionAmount', 'OutstandingAmount', 'CurrentBalance', 'TotalOutStgAuthAmt'])]
        
        # Generating random points on the surface of a sphere
        phi = np.random.uniform(0, np.pi, len(relevant_columns))
        theta = np.random.uniform(0, 2*np.pi, len(relevant_columns))
        
        x = np.cos(theta) * np.sin(phi)
        y = np.sin(theta) * np.sin(phi)
        z = np.cos(phi)
        
        # Create a 3D scatter plot with sphere markers
        scatter = go.Scatter3d(
            x=x,
            y=y,
            z=z,
            mode='markers+text',
            marker=dict(
                size=12,
                color=np.arange(len(relevant_columns)),
                colorscale='Viridis',
                symbol='circle',
                opacity=0.8
            ),
            text=relevant_columns['name'],
            hoverinfo='text'
        )
        
        # Create a wireframe sphere using a mesh
        u = np.linspace(0, 2 * np.pi, 100)
        v = np.linspace(0, np.pi, 100)
        x_sphere = np.outer(np.cos(u), np.sin(v))
        y_sphere = np.outer(np.sin(u), np.sin(v))
        z_sphere = np.outer(np.ones(np.size(u)), np.cos(v))
        
        sphere = go.Mesh3d(x=x_sphere.ravel(),
                           y=y_sphere.ravel(),
                           z=z_sphere.ravel(),
                           opacity=0.1,
                           color='cyan')
        
        # Combine the scatter plot and wireframe into a single figure
        fig = go.Figure(data=[scatter, sphere])
        
        fig.update_layout(
            margin=dict(l=0, r=0, b=0, t=0),
            scene=dict(
                xaxis=dict(title=None, visible=False),
                yaxis=dict(title=None, visible=False),
                zaxis=dict(title=None, visible=False),
            ),
            template='plotly_dark'
        )
        
        return fig, {"height": "50vh", "width": "100%", "display": "inline-block"}
# Define the callback function that will update the plot, highlight the sphere and enable drilling down
@app.callback(
    Output('base-plot', 'figure'),
    Input('hexgrid-2', 'clickData'),
    State('hexgrid-1', 'clickData')
)
def update_base_plot(clickData_hexgrid_2, clickData_hexgrid_1):
    try:
        # Open a new database connection
        conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")

        category = clickData_hexgrid_1['points'][0]['text']
        numerical_feature = clickData_hexgrid_2['points'][0]['text']

        # SQL query to retrieve aggregated data based on selected category and numerical feature
        query = f'''
            SELECT {category}, WeekOfMonth, SUM({numerical_feature}) AS TotalAmount
            FROM transactions
            GROUP BY {category}, WeekOfMonth
            ORDER BY TotalAmount DESC
        '''

        # Fetch the data from the database
        df_base = pd.read_sql(query, conn)

        # Close the database connection
        conn.close()

        # Formatting the Total column
        df_base['TotalAmount'] = df_base['TotalAmount'].apply(lambda x: locale.currency(x, grouping=True))

        # Creating 3D scatter plot with sphere markers
        fig = go.Figure()

        # Define colorscale for WeekOfMonth values
        colorscale = [
            [0, 'blue'],        # Week 1: Blue
            [0.25, 'purple'],   # Week 2: Purple
            [0.5, 'darkorange'],   # Week 3: Dark Orange
            [0.75, 'yellow'],   # Week 4: Yellow
            [1, 'pink']         # Week 5: Pink
        ]

        # Add the scatter plot trace
        fig.add_trace(
            go.Scatter3d(
                x=df_base[category],
                y=df_base['WeekOfMonth'].astype(int),
                z=df_base['TotalAmount'],
                mode='markers+text',
                marker=dict(
                    size=5,  # Adjust the size of markers to make them smaller
                    symbol='circle',  # Use 'circle' symbol for spheres
                    color=df_base['WeekOfMonth'],
                    colorscale=colorscale,
                ),
                textposition='top center',
                hovertemplate=(
                    f"<b>{category}</b>: %{{x}}<br>" +
                    "<b>Total Amount</b>: %{z}<br>" +
                    "<b>WeekOfMonth</b>: %{y}<br>"
                )
            )
        )

        # Dynamically set y-axis range
        y_max = df_base['WeekOfMonth'].max()

        fig.update_layout(
            scene=dict(
                xaxis=dict(
                    title=category,
                    title_font=dict(size=14, color='darkorange'),
                    visible=False  # Hide the x-axis
                ),
                yaxis=dict(
                    title='Week of Month',
                    title_font=dict(size=14, color='purple'),
                    tickmode='array',
                    tickvals=[0.5, 1.5, 2.5, 3.5, 4.5, 5.5],
                    ticktext=['1', '2', '3', '4', '5'],  # Display tick labels as 1, 2, 3, 4, 5],
                    visible=False  # Hide the y-axis
                ),
                zaxis=dict(
                    title=f'Total {numerical_feature} ($)',
                    title_font=dict(size=14, color='yellow'),
                    autorange='reversed',
                    visible=False  # Hide the z-axis
                ),
            ),
            xaxis=dict(
                type='category',
                tickmode='linear',
                tickangle=45,
                automargin=True,
                visible=False  # Hide the x-axis labels
            ),
            margin=dict(l=10, r=10, t=10, b=10),  # Increase the b value to enlarge the viewing window
            template='plotly_dark',
        )

        return fig

    except Exception as e:
        print(f"Error: {e}")
        return go.Figure()


@app.callback(
    Output('us-map-graph', 'figure'),
    Output('us-map-graph', 'style'),
    Input('base-plot', 'clickData'),
    State('hexgrid-1', 'clickData'),
    State('hexgrid-2', 'clickData')
)
def display_transaction_amount(base_plot_click_data, hexgrid_1_clickData, hexgrid_2_clickData):
    try:
        # Check if data from hexgrid-1 and hexgrid-2 is available
        if hexgrid_1_clickData is None or hexgrid_2_clickData is None:
            # Return an empty figure and hide the map
            return go.Figure(), {"display": "none"}

        # Get the selected category from hexgrid-1 and numerical feature from hexgrid-2
        selected_category = hexgrid_1_clickData['points'][0]['text']
        numerical_feature = hexgrid_2_clickData['points'][0]['text']

        # Get the selected subcategory from base_plot_click_data
        selected_subcategory = None
        if base_plot_click_data is not None:
            selected_subcategory = base_plot_click_data['points'][0]['x']

        # Open a new database connection
        conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")

        # SQL query to retrieve transaction data by state for the selected category, subcategory, and numerical feature
        query = f'''
            SELECT StateCode, {selected_category}, SUM({numerical_feature}) AS TotalTransactionAmount
            FROM transactions
            WHERE {selected_category} = ?
            GROUP BY StateCode, {selected_category}
        '''

        # Execute the query and fetch the results into a DataFrame
        state_data = pd.read_sql(query, conn, params=(selected_subcategory,))

        # Close the database connection
        conn.close()

        # Create a Choropleth map using the filtered data
        fig = px.choropleth(
            data_frame=state_data,
            locationmode='USA-states',
            locations='StateCode',
            scope='usa',
            color='TotalTransactionAmount',
            hover_data={'StateCode': True, 'TotalTransactionAmount': ':$,f'},
            color_continuous_scale='Reds',
            labels={'TotalTransactionAmount': 'Total Transaction Amount'},
            template='plotly_dark'
        )

        fig.update_traces(
            hovertemplate="<b>%{customdata[0]}</b><br>" +
                          "<b>TotalTransactionAmount</b>: $%{customdata[1]:,.2f}<br>",
            customdata=list(zip(state_data['StateCode'], state_data['TotalTransactionAmount']))
        )

        fig.update_layout(
            title_text=f'Total Transaction Amount by State for Category: {selected_category}, Subcategory: {selected_subcategory}',
            title_xanchor='center',
            title_font=dict(size=12),
            title_x=0.5,
            geo=dict(scope='usa'),
        )

        # Return the figure and set the display style to block (visible)
        return fig, {"display": "block"}

    except Exception as e:
        print(f"Error: {e}")
        return go.Figure(), {"display": "none"}
if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=False)

Selain itu, saya mempunyai fail css ini untuk memformat halaman web:

/* styles.css */

.container {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 15px;
  grid-row-gap: 15px;
  background-image: url("https://plainbackground.com/plain1024/383c3d.png");
  background-size: 100%;
  background-position: grid-ce;
}

.hexgrid-1-container {
  /* grid-area: 1/1/3/3; */
  grid-row: span 2;
  grid-column: span 2;
  padding: 2px 2px 2px 2px;
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsla(0, 7%, 11%, 0.9);
  position: relative;
}

.hexgrid-2-container {
  grid-area: 1/3/2/4;
  padding: 3rem 4rem 4rem;
  width: 70%;
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsl(0, 7%, 11%, 0.9);
  position: relative;
}

.base-plot-container {
  /* Add your custom styles for base-plot container here */
  grid-area: 2/3/3/4;
  padding: 3rem 4rem 4rem;
  width: 70%;
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsl(0, 7%, 11%, 0.9);
  position: relative;
}

.us-map-container {
  grid-area: 3/3/4/4;
  padding: 3rem 4rem 4rem;
  width: 70%;
  /* position: fixed; */
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsl(0, 7%, 11%, 0.9);
  position: relative;
}

.fifth-container {
  grid-area: 3/2/4/3;
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsl(0, 7%, 11%, 0.9);
  position: relative;
}

.sixth-container {
  grid-area: 3/1/4/2;
  border: 1px solid hsl(176, 87%, 7%, 0.6);
  border-radius: 10px;
  box-shadow: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  background: hsl(0, 7%, 11%, 0.9);
  position: relative;
}

Saya cuba mengemas kini fungsi panggil balik tetapi saya tidak membuat banyak kemajuan dan nampaknya saya melakukan banyak perkara yang salah. Apakah cara yang paling mudah untuk melaksanakan fungsi ini? Terima kasih terlebih dahulu.

P粉378890106P粉378890106272 hari yang lalu570

membalas semua(1)saya akan balas

  • P粉252423906

    P粉2524239062024-02-27 15:34:56

    Anda boleh membuat panggilan balik untuk mendengar acara klik, menukar kedudukan grafik dan kemudian mengembalikan grafik ke kedudukan yang dikemas kini. Anda perlu menetapkan logik klik mengikut kes penggunaan anda. Anda boleh melaksanakan sesuatu seperti ini:

    @app.callback(
        Output('hexgrid-1-container', 'children'),
        Output('hexgrid-2-container', 'children'),
        Input('hexgrid-2', 'clickData'),
        State('hexgrid-1-container', 'children'),
        State('hexgrid-2-container', 'children')
    )
    def swap_graphs(clickData, hexgrid_1_children, hexgrid_2_children):
        clicked_graph_id = 1  # Assuming hexgrid-2 was clicked, you can change this logic based on your use case
    
        if clicked_graph_id == 1:
            # Swap graph between hexgrid-1 and hexgrid-2
            return hexgrid_2_children, hexgrid_1_children
    
        return hexgrid_1_children, hexgrid_2_children

    balas
    0
  • Batalbalas