ホームページ  >  に質問  >  本文

ダッシュ アプリ内のさまざまなコンテナーのコンテンツを交換するにはどうすればよいですか?

次のことを行うのに非常に苦労しています。さまざまなコンテナーに表示するために CSS でフォ​​ーマットされたダッシュ アプリケーションがあります。 「hexgrid-1-container」というラベルの付いたコンテナーが最大のコンテナーであり、他のコンテナーはより小さく、その周りに編成されています。ダッシュ アプリを更新して、別のコンテナー内の図/グラフィックをクリックすると、前の図が「hexgrid-1-container」にあった場所にその図/グラフィックが「hexgrid-1-container」に表示されるようにしたいです。コンテナーはより小さいコンテナーに表示されます。 。

次のようなダッシュ アプリケーションがあります:

インポートダッシュ
ダッシュ_コア_コンポーネントを dcc としてインポートします
ダッシュ_html_componentsをHTMLとしてインポート
from dump.dependency import 入力、出力、状態
jupyter_dash から JupyterDash をインポート
pxとしてplotly.expressをインポートします
そのままplotly.graph_objectsをインポートします
パンダをPDとしてインポートする
sqlite3をインポートする
ロケールをインポートする
numpyをnpとしてインポート
インポートplotly.figure_factoryをffとして
pxとしてplotly.expressをインポートします

# 書式設定のロケールを設定する
locale.setlocale(locale.LC_ALL, '')
app = ダッシュ.ダッシュ(__name__)
app.layout = html.Div(className= 'コンテナ ガラス', Children=[
    html.Div(className='hexgrid-1-container', style={'border': '1px ソリッドブラック'}, Children=[
        dcc.Graph(id='hexgrid-1', style={"height": "75%", "width": "100%"}, className='hexgrid1')
    ])、

    html.Div(className='hexgrid-2-container', style={'border': '1px ソリッド ブラック'}, Children=[
        dcc.Graph(id='hexgrid-2', style={"height": "100%", "width": "100%"}, className='hexgrid2')
    ])、

    html.Div(className='base-plot-container', style={'border': '1px ソリッドブラック'}, Children=[
        dcc.Graph(id='base-plot', style={"高さ": "100%", "幅": "100%"})
    ])、

    html.Div(className='us-map-container', style={'border': '1px ソリッドブラック'}, Children=[
        dcc.Graph(id='us-map-graph', style={"高さ": "100%", "幅": "100%"})
    ])、

    html.Div(className='fifth-container', style={'border': '1px ソリッドブラック'}, Children=[
        # dcc.Graph(id='us-map-graph', style={"高さ": "100%", "幅": "100%"})
        #html.H2("5 番目のコンテナ")
    ])、

    html.Div(className='sixth-container', style={'border': '1px ソリッドブラック'}, Children=[
        # dcc.Graph(id='us-map-graph', style={"高さ": "100%", "幅": "100%"})
        #html.H2("6 番目のコンテナ")
    ])
])


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

def render_hexgrid_1(_):
    # 新しいデータベース接続を開く
    conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")
    
    # トランザクションテーブルのすべての列を取得します
    クエリ = ''
        PRAGMA table_info(トランザクション)
    「」
    
    # データを取得する
    データ = pd.read_sql_query(クエリ, conn)
    
    # 関連する列をフィルタリングして除外します。すべての列が必要な場合は、この手順をスキップできます。
    関連列 = データ[データ['名前'].isin(['TranType', 'MessageTypeIdentifier', 'MerchantType', 'IResponseCode'])]
    
    # 列名を使用した 16 進グリッドの作成
    Lot_data = go.Scatter(x=relevant_columns.index, y=relevant_columns['name'], text=relevant_columns['name'],
                           マーカー=dict(シンボル='六角形', サイズ=30), モード='マーカーテキスト')
    layout = go.Layout(title="カテゴリを選択")
    return go.Figure(data=[プロットデータ], レイアウト=レイアウト)
@app.callback(
    Output('hexgrid-2', 'figure'),
    出力('hexgrid-2', 'スタイル'),
    入力('hexgrid-1', 'clickData')
)
def render_hexgrid_2(clickData):
    # 新しいデータベース接続を開く
    conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")
    
    clickData が None の場合:
        return go.Figure(), {"表示": "なし"}それ以外:
        カテゴリ = clickData['ポイント'][0]['テキスト']
        
        # トランザクションテーブルのすべての列を取得します
        クエリ = ''
            PRAGMA table_info(トランザクション)
        「」
        
        # データを取得する
        データ = pd.read_sql_query(クエリ, conn)
        
        # 関連する数値特徴列をフィルタリングして除外する
        関連列 = データ[データ['名前'].isin(['取引額', '未払い額', '現在の残高', 'TotalOutStgAuthAmt'])]
        
        # 球の表面にランダムな点を生成する
        phi = np.random.uniform(0, np.pi, len(relevant_columns))
        theta = np.random.uniform(0, 2*np.pi, len(relevant_columns))
        
        x = np.cos(シータ) * np.sin(ファイ)
        y = np.sin(θ) * np.sin(ファイ)
        z = np.cos(ファイ)
        
        # 球マーカーを使用して 3D 散布図を作成する
        散布 = go.Scatter3d(
            x=x、
            y=y、
            z=z、
            mode='マーカーテキスト',
            マーカー=dict(
                サイズ=12、
                color=np.arange(len(関連列)),
                colorscale='ウィリディス',
                シンボル='円'、
                不透明度=0.8
            )、
            text=relevant_columns['名前']、
            hoverinfo='テキスト'
        )
        
        # メッシュを使用してワイヤーフレーム球を作成する
        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()、
                           不透明度=0.1、
                           color='シアン')
        
        # 散布図とワイヤーフレームを 1 つの図に結合します
        fig = go.Figure(data=[散乱, 球])
        
        fig.update_layout(
            margin=dict(l=0, r=0, b=0, t=0),
            シーン=dict(
                xaxis=dict(title=None、visible=False)、
                yaxis=dict(title=None、visible=False)、
                zaxis=dict(title=None、visible=False)、
            )、
            template='plotly_dark'
        )
        
        return fig、{"高さ": "50vh"、"幅": "100%"、"表示": "インラインブロック"}
# プロットを更新し、球を強調表示し、ドリルダウンを有効にするコールバック関数を定義します。
@app.callback(
    Output('ベースプロット', '図'),
    入力('hexgrid-2', 'clickData'),
    State('hexgrid-1', 'clickData')
)
def update_base_plot(clickData_hexgrid_2, clickData_hexgrid_1):
    試す:
        # 新しいデータベース接続を開く
        conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db")

        カテゴリ = clickData_hexgrid_1['ポイント'][0]['テキスト']
        Numerical_feature = clickData_hexgrid_2['ポイント'][0]['テキスト']

        # 選択したカテゴリと数値特徴に基づいて集計データを取得する SQL クエリ
        クエリ = f'''
            SELECT {category}、WeekOfMonth、SUM({numerical_feature}) AS TotalAmount
            FROMトランザクション
            {カテゴリ}ごとにグループ化、月の週
            合計金額 DESC で注文
        「」

        # データベースからデータを取得します
        df_base = pd.read_sql(クエリ, conn)

        # データベース接続を閉じる
        conn.close()

        # 合計列の書式設定
        df_base['TotalAmount'] = df_base['TotalAmount'].apply(lambda x: locale.currency(x, grouping=True))

        # 球マーカーを使用した 3D 散布図の作成
        fig = go.Figure()

        # WeekOfMonth 値のカラースケールを定義する
        カラースケール = [
            [0, '青'], # 第 1 週: 青
            [0.25, 'purple']、# 第 2 週: 紫
            [0.5, 'darkorange']、# 第 3 週: ダークオレンジ
            [0.75、'黄色']、# 第 4 週: 黄色
            [1、「ピンク」] # 第 5 週: ピンク
        ]

        # 散布図トレースを追加します
        fig.add_trace(
            go.Scatter3d(
                x=df_base[カテゴリ]、
                y=df_base['WeekOfMonth'].astype(int),
                z=df_base['合計金額'],
                mode='マーカーテキスト',
                マーカー=dict(
                    size=5, # マーカーのサイズを調整して小さくします
                    symbol='circle', # 球には「circle」シンボルを使用します
                    color=df_base['月の週']、
                    カラースケール=カラースケール、
                )、
                textposition='上部中央',
                hovertemplate=(
                    f"<b>{カテゴリ}</b>: %{{x}}<br>"
                    "合計金額: %{z}
" "月の週: %{y}
" ) ) ) # y 軸範囲を動的に設定する y_max = df_base['WeekOfMonth'].max() fig.update_layout( シーン=dict( xaxis=dict( タイトル=カテゴリー、 title_font=dict(size=14, color='darkorange'), visible=False # X 軸を非表示にする )、 yaxis=dict( title='月の週', title_font=dict(size=14, color='purple'), ティックモード='配列', tinyvals=[0.5, 1.5, 2.5, 3.5, 4.5, 5.5], tictext=['1', '2', '3', '4', '5'], # 目盛りラベルを 1, 2, 3, 4, 5 として表示します], visible=False # y 軸を非表示にする )、 zaxis=dict( title=f'合計 {数値機能} ($)', title_font=dict(size=14, color=' yellow'), autorange='反転', visible=False # Z 軸を非表示にする )、 )、 xaxis=dict( type='カテゴリ', ティックモード='リニア'、 目盛り=45、 automargin=True、 visible=False # X 軸のラベルを非表示にする )、 margin=dict(l=10, r=10, t=10, b=10), # b の値を増やして表示ウィンドウを拡大します template='plotly_dark', ) イチジクを返す e としての例外を除く: print(f"エラー: {e}") go.Figure() を返す @app.callback( Output('us-map-graph', 'figure'), Output('us-map-graph', 'style'), 入力('ベースプロット', 'クリックデータ'), State('hexgrid-1', 'clickData'), State('hexgrid-2', 'clickData') ) def display_transaction_amount(base_plot_click_data, hexgrid_1_clickData, hexgrid_2_clickData): 試す: # hexgrid-1 と hexgrid-2 からのデータが利用可能かどうかを確認します hexgrid_1_clickData が None または hexgrid_2_clickData が None の場合: # 空の図を返し、マップを非表示にします return go.Figure(), {"表示": "なし"} # hexgrid-1 から選択したカテゴリを取得し、hexgrid-2 から数値特徴を取得します selected_category = hexgrid_1_clickData['ポイント'][0]['テキスト'] Numerical_feature = hexgrid_2_clickData['ポイント'][0]['テキスト'] # 選択したサブカテゴリをbase_plot_click_dataから取得します selected_subcategory = なし Base_plot_click_data が None でない場合: selected_subcategory = Base_plot_click_data['points'][0]['x'] # 新しいデータベース接続を開く conn = sqlite3.connect(r"C:\Users\HituJani\Downloads\txns.db") # 選択したカテゴリ、サブカテゴリ、および数値特徴の状態別にトランザクション データを取得する SQL クエリ クエリ = f''' SELECT StateCode, {selected_category}, SUM({numerical_feature}) AS TotalTransactionAmount FROMトランザクション WHERE {選択されたカテゴリ} = ? GROUP BY StateCode、{selected_category} 「」 # クエリを実行し、結果を DataFrame にフェッチします state_data = pd.read_sql(query, conn, params=(selected_subcategory,)) # データベース接続を閉じる conn.close() # フィルタリングされたデータを使用してコロプレス マップを作成する fig = px.コロプレス( データフレーム=状態データ、 locationmode='米国の州', 場所='州コード', スコープ='米国'、 color='合計取引金額', hover_data={'StateCode': True, 'TotalTransactionAmount': ':$,f'}, color_continuous_scale='レッド', ラベル={'TotalTransactionAmount': '合計トランザクション金額'}, 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'カテゴリ: {selected_category}、サブカテゴリ: {selected_subcategory}' の州別合計取引額', title_xanchor='センター', title_font=dict(size=12), title_x=0.5、 geo=dict(scope='usa'), ) # Figureを返し、表示スタイルをブロック(可視)に設定します return fig、{"表示": "ブロック"} e としての例外を除く: print(f"エラー: {e}") return go.Figure(), {"表示": "なし"} __name__ == '__main__'の場合: app.run_server(debug=True、use_reloader=False)

さらに、私はこの格式化ネット页のcssファイルを持っています:

/* スタイル.css */

。容器 {
  表示: グリッド;
  グリッド テンプレート行: 1fr 1fr 1fr;
  グリッド テンプレート列: 1fr 1fr 1fr;
  グリッド列ギャップ: 15px;
  グリッド行ギャップ: 15px;
  背景画像: url("https://plainbackground.com/plain1024/383c3d.png");
  背景サイズ: 100%;
  背景位置: グリッド ce;
}

.hexgrid-1-container {
  /* グリッド領域: 1/1/3/3; */
  グリッド行: スパン 2;
  グリッド列: スパン 2;
  パディング: 2px 2px 2px 2px;
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsla(0, 7%, 11%, 0.9);
  位置: 相対的;
}

.hexgrid-2-container {
  グリッド領域: 1/3/2/4;
  パディング: 3レム 4レム 4レム;
  幅: 70%;
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsl(0, 7%, 11%, 0.9);
  位置: 相対的;
}

.base-plot-container {
  /* ここにベースプロットコンテナのカスタムスタイルを追加します */
  グリッド領域: 2/3/3/4;
  パディング: 3レム 4レム 4レム;
  幅: 70%;
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsl(0, 7%, 11%, 0.9);
  位置: 相対的;
}

.us-map-container {
  グリッド領域: 3/3/4/4;
  パディング: 3レム 4レム 4レム;
  幅: 70%;
  /* 位置: 固定; */
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsl(0, 7%, 11%, 0.9);
  位置: 相対的;
}

.fifth-container {
  グリッド領域: 3/2/4/3;
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsl(0, 7%, 11%, 0.9);
  位置: 相対的;
}

.sixth-container {
  グリッド領域: 3/1/4/2;
  ボーダー: 1px ソリッド hsl(176, 87%, 7%, 0.6);
  境界半径: 10px;
  ボックスシャドウ: rgba(250, 118, 3, 0.4) -5px 5px, rgba(250, 118, 3, 0.3) -10px 10px, rgba(250, 118, 3, 0.2) -15px 15px;
  バックグラウンド: hsl(0, 7%, 11%, 0.9);
  位置: 相対的;
}

私は関数の更新を試みていますが、それほど大きくはなく、かなりの困難を抱えています。この機能を実現するための最も直接的な方法は何でしょうか?

P粉378890106P粉378890106254日前547

全員に返信(1)返信します

  • P粉252423906

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

    コールバックを作成してクリック イベントをリッスンし、グラフィックの位置を交換し、グラフィックを更新された位置に戻すことができます。ユースケースに応じてクリックロジックを設定する必要があります。次のようなものを実装できます:

    @app.callback(
        Output('hexgrid-1-container', 'children'),
        Output('hexgrid-2-container', 'children'),
        入力('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 # hexgrid-2 がクリックされたと仮定すると、ユースケースに基づいてこのロジックを変更できます
    
        clicked_graph_id == 1 の場合:
            # hexgrid-1 と hexgrid-2 の間でグラフを交換します
            hexgrid_2_children、hexgrid_1_children を返す
    
        hexgrid_1_children、hexgrid_2_children
    を返す

    返事
    0
  • キャンセル返事