如何在Dash应用中实现图表选区与ag-grid的数据映射联动
Dash图表区域选择联动过滤Ag-Grid表格
要实现图表区域选择后过滤表格数据的逻辑,核心是通过Dash回调监听图表的区域选择事件,提取选中的时间戳范围,再用该范围过滤原始DataFrame,最后更新Ag-Grid的行数据。以下是具体实现步骤:
1. 修正图表函数并启用区域选择
先修复原plot函数中的未定义变量问题,同时配置图表支持区域选择操作:
import plotly.graph_objects as go def plot(df, param, color="#1f77b4", height=400): group_by = 'timestamp' cum_sum = df.groupby(group_by)[param].sum().reset_index() fig = go.Figure() # 添加线条轨迹 fig.add_trace(go.Scatter( x=cum_sum[group_by], y=cum_sum[param], mode='lines', name=param, marker=dict(color=color) )) # 添加标记点轨迹 for _, row in cum_sum.iterrows(): fig.add_scatter( x=[row[group_by]], y=[row[param]], mode='markers', name='', showlegend=False, marker=dict(color=color) ) fig.update_layout( title='累计参数趋势', xaxis=dict(type='category'), height=height, # 启用区域选择的拖拽模式 dragmode='select' ) return fig
2. 调整应用布局
确保组件ID配置正确,同时为图表添加选择工具栏:
from dash import Dash, html, dcc, Input, Output, State import dash_ag_grid as dag import pandas as pd # 替换为你的实际DataFrame df = pd.DataFrame({ 'timestamp': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'], 'param': [10, 20, 15, 25], 'other_col': ['A', 'B', 'C', 'D'] }) app = Dash(__name__) # 生成初始表格 def create_grid(df): columnDefs = [{'headerName': col, 'field': col} for col in df.columns] ag_grid = dag.AgGrid( id="ag-grid", rowData=df.to_dict("records"), columnDefs=columnDefs, ) return ag_grid grid = create_grid(df) fig1 = plot(df, param='param') app.layout = html.Div([ html.Div([grid], style={'width': '80%', 'margin': '20px auto'}), dcc.Graph( id='scatter', figure=fig1, # 配置工具栏,确保区域选择按钮可见 config={'modeBarButtonsToAdd': ['select2d'], 'displayModeBar': True} ) ])
3. 编写回调实现联动逻辑
通过回调监听图表的区域选择事件,过滤数据后更新表格:
@app.callback( Output("ag-grid", "rowData"), Input("scatter", "relayoutData"), State("ag-grid", "rowData"), prevent_initial_call=True ) def update_grid(selected_range, original_data): # 解析选中的时间戳范围 if 'xaxis.range[0]' in selected_range and 'xaxis.range[1]' in selected_range: start_ts = selected_range['xaxis.range[0]'] end_ts = selected_range['xaxis.range[1]'] # 过滤原始DataFrame filtered_df = df[(df['timestamp'] >= start_ts) & (df['timestamp'] <= end_ts)] return filtered_df.to_dict("records") # 无选中区域时返回原始数据 return original_data
关键说明
relayoutData:用户在图表上进行区域选择时,该属性会返回包含选中范围的字典,xaxis.range[0]和xaxis.range[1]对应选中的起始/结束时间戳。prevent_initial_call=True:避免应用启动时触发不必要的回调。- 时间戳格式:如果你的
timestamp是datetime类型,直接使用范围比较即可;如果是字符串,需确保格式统一,保证比较逻辑有效。
内容的提问来源于stack exchange,提问作者Alesya
相关产品推荐
相关产品推荐

