@DashUser2247 wrote:
So I am trying to have a table/graph combo where I have a table with multiple columns, something like: (time, weight, name) and a graph that plots each person’s weight over time. You can assume that time is an int (0,1,2,3,4,5) etc.
For example, this is what the table might look like:
+------+------+--------+ | time | name | weight | +------+------+--------+ | 0 | john | 200 | +------+------+--------+ | 1 | john | 220 | +------+------+--------+ | 0 | amy | 200 | +------+------+--------+ | 1 | amy | 210 | +------+------+--------+ | 2 | john | 230 | +------+------+--------+ | 3 | john | 240 | +------+------+--------+You can imagine a corresponding plot with two lines, one for
johnand one foramy.
Now, I’m trying to get it so that if a user selects a point on the graph, and the graph’s
selectedDatacallback is called, I can then update the table’sselected-rowscallback so that the appropriate person’s entry in the table can be highlighted.The problem is that selected data gives me information in the following format:
{'points': [{'curveNumber': 5, 'pointIndex': 9, 'pointNumber': 9, 'x': 250, 'y': 1.236}]}Now, I don’t have that curve information and which person each curve corresponds to. More importantly, the table can be filtered, so I can have some people not even be visible on the table.
The way I have it right now is that I disregard the
Input(Graph_ID, 'selectedData')callback and use the state of the graph instead:State(Graph_ID, 'figure'). This provides more information, specifically I get this bit of info for each curve on the plot:{ # ... # Some figure data.... # .... {'data': [{'line': {'color': 'rgba(133, 133, 133,1)', 'dash': 'dash'}, 'marker': {'color': 'rgba(133, 133, 133,1)', 'symbol': 'o'}, 'mode': 'lines+markers', 'name': 'john', 'selectedpoints': [9], 'type': 'scatter', 'unselected': {'line': {'opacity': 0.3}, 'marker': {'opacity': 0.3}}, 'x': [0, 2, 7, 15, 30, 60, 90, 150, 180, 250, 365, 550], 'y': [1.62563, 1.38846, 1.30052, 1.34375, 1.35601, 1.31275, 1.27629, 1.236, 1.236, 1.236, 1.2345, 1.23321]} } ## Bunch of other figure data.... }So, if I know the x-axis’ corresponding column name in the table, I pass that into the callback as well, convert the table to a pandas DataFrame, and then do something like:
def get_row_from_table(dff, point_idx, curve_name): # Get just john's rows (obviously can be someone other than john, but this is just for example) john_rows = dff[dff['name'] == curve_name] # Get the index of the row that matches the given point index using pandas' iloc, which # retrieves a table row by it's row index, which is the same as point_index after filtering # and reseting the index. return john_rows.reset_index().iloc[point_idx,:] @app.callback( [Output(TABLE_ID, 'selected_rows')], [Input(GRAPH_ID, 'selectedData')], [State(SVI_TABLE_ID, 'data'), State(SVI_GRAPH_ID, 'figure')]) def svi_update_style_on_user_input(_, table_data, graph_data): dff = pd.DataFrame(table_data) # Get Selected points: curve_points = [] for curve in graph_data['data']: selected_points = curve.get('selectedpoints', []) if len(selected_points) > 0: curve_points.append((curve['name'], selected_points)) table_selected_rows = [] for curveName, selectedPoints in curve_points: for point_idx in selected_points: row_df = get_row_from_table(point_idx, curve_name) if len(row_df) > 0: table_selected_rows.append(list(row_df)[0]) return table_selected_rows
Does dash have a better way to handle this? Any ideas if there are any built in components that can handle this for me? This works right now, but imagine scaling up.
Like for example, the actual
get_row_from_tablefunction that I use is wayy more complex because my curve names are very different than the actualnamecolumn’s values.Any ideas what the proper behavior should be?
Posts: 1
Participants: 1