【问题标题】:Unselect active_cell in dash datatable (python)在破折号数据表(python)中取消选择active_cell
【发布时间】:2020-11-19 05:44:55
【问题描述】:

全部,

我正在尝试实现一个破折号数据表,通过直接单击它来选择行(没有单选按钮)。目前,我正在使用active_cell 执行此操作,并且效果很好: 无论用户单击行的哪个单元格,都会使用该行中的数据更新图表。如果他单击同一行中的另一个单元格,则未选择数据(通过 dcc.storage)

我的问题来了:如果用户再次单击同一个单元格,则不会触发active_cell 事件。因此,我的回调没有被触发,也没有任何反应。 我想在用户第二次单击该单元格时取消选择该单元格。我该如何实现?

谢谢!

【问题讨论】:

    标签: python datatable plotly-dash deselect


    【解决方案1】:

    所以...我解决了这个问题...它并不漂亮,但它有效 - 它包括一个我必须实现的循环断路器以避免循环依赖,但是是的 - 我绝对愿意接受更清洁的解决方案。

    在回调下方查找

        # takes user selected cell (active_cell) and the current state of a dcc.storage (tableclick) which stores the last saved row that was clicked
    # output: updated selected_rows for the datatable, styling for the selected row and update for dcc.storage
    # if no cell is selected, do nothing
    # if no cell is selected, but there is a row stored as selected, highlight that row (this is a consequence from the circular dependency)
    # if a cell is selected that is different from the previous cell, highlight that new row. Otherwise, deselect the row.
    @app.callback(
        [Output('performancedatatable', 'style_data_conditional'), Output('tableclick', 'data'),
         Output('performancedatatable', 'selected_rows')],
        [
            Input('performancedatatable', 'active_cell'),
        ], [State('tableclick', 'data')]
    )
    def highlight_row(cell, prevrow):
        if cell is None:
            if prevrow is None:
                return [{}], None, []
            else:
                return [{}], None, prevrow
        elif "row" in cell:
            if cell.get("row", "") == prevrow:
                return [{}], None, []
            else:
                return ([{
                    "if": {"row_index": cell.get("row", "")},
                    "backgroundColor": "rgba(146, 192, 234, 0.5)",
                }], cell.get("row", ""), [cell.get("row", "")])
    
    
    # Is triggered by changing the dcc.storage "tableclick"
    # resets active cell and selected cell via callback below
    @app.callback([Output('loopbreaker_div', "children")], [Input('tableclick', 'data')])
    def reset_active_cell(input):
        return [html.Div(id='loopbreaker', children=True)]
    
    
    #loopbreaker to avoid circular dependency
    @app.callback([Output('performancedatatable', "active_cell"), Output('performancedatatable', 'selected_cells')], [Input('loopbreaker', 'children')])
    def reset_active_cell(input):
        time.sleep(1)
        return (None, [])
    

    感谢 http://yaaics.blogspot.com/2019/03/circular-references-in-plotlydash.html 帮助解决循环依赖

    【讨论】:

      【解决方案2】:

      一个更简单的解决方案(但它有其他缺点)是选择一个隐藏的单元格。这会让用户觉得没有选择任何内容。

      在下面的示例中,一个单元格由回调处理和取消选择。显然,此回调也可以用于“取消全选”按钮或您需要的任何其他内容。

      添加名为“cant_see”的列:

      df = pd.read_csv("my_data.csv")
      df.insert(0, "cant_see", ["" for i in df.iloc[:, 0] ]) 
      

      使用 style_data_conditionalstyle_header_conditional 创建 DataTable 时将其隐藏:

      dash_table.DataTable(
          id="table",
          columns=[{"name": i, "id": i} for i in df.columns],
          data=df.to_dict("records"),
          is_focused=True,
          style_data_conditional=[
              {'if': {'column_id': 'cant_see',}, 'display': 'None',}
          ],
          style_header_conditional=[
              {'if': {'column_id': 'cant_see',}, 'display': 'None',}
          ], 
      )
      

      然后回调可以设置表格的“active_cell”和/或“selected_cells”

      @app.callback(
          Output("table", "active_cell"),
          Output("table", "selected_cells"),
          Input("table", "active_cell"),)
      
      def cell_clicked(cell):
          # Do something useful with cell, 
          # such as toggling it's style to mimic select/de-select
      
          # Now make it look like the cell is de-selected
          # by selecting a hidden cell
          #
          # return active cell 0,0 and selected_cells list [ 0,0 ]
          return {'column':0, 'row':0}, [{'column':0, 'row':0}]
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-09
        • 2021-05-06
        • 1970-01-01
        • 2011-08-25
        • 2013-10-09
        • 1970-01-01
        • 2012-07-03
        相关资源
        最近更新 更多