diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6454a302..bef59a2111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - [#1953](https://github.com/plotly/dash/pull/1953) Fix bug [#1783](https://github.com/plotly/dash/issues/1783) in which a failed hot reloader blocks the UI with alerts. +- [#1942](https://github.com/plotly/dash/pull/1942) Fix bug [#1663](https://github.com/plotly/dash/issues/1663) preventing pie traces from sending `customdata` with `clickData` and other events. + ## [2.2.0] - 2022-02-18 ### Added diff --git a/components/dash-core-components/src/fragments/Graph.react.js b/components/dash-core-components/src/fragments/Graph.react.js index f249c23f32..9789c41660 100644 --- a/components/dash-core-components/src/fragments/Graph.react.js +++ b/components/dash-core-components/src/fragments/Graph.react.js @@ -84,13 +84,18 @@ const filterEventData = (gd, eventData, event) => { if ( has('curveNumber', fullPoint) && - has('pointNumber', fullPoint) && has('customdata', data[pointData.curveNumber]) ) { - pointData.customdata = - data[pointData.curveNumber].customdata[ - fullPoint.pointNumber - ]; + if (has('pointNumber', fullPoint)) { + pointData.customdata = + data[pointData.curveNumber].customdata[ + fullPoint.pointNumber + ]; + } else if (has('pointNumbers', fullPoint)) { + pointData.customdata = fullPoint.pointNumbers.map(point => { + return data[pointData.curveNumber].customdata[point]; + }); + } } // specific to histogram. see https://github.com/plotly/plotly.js/pull/2113/ diff --git a/components/dash-core-components/tests/integration/graph/test_graph_basics.py b/components/dash-core-components/tests/integration/graph/test_graph_basics.py index 8823922f09..1513a1e59b 100644 --- a/components/dash-core-components/tests/integration/graph/test_graph_basics.py +++ b/components/dash-core-components/tests/integration/graph/test_graph_basics.py @@ -4,6 +4,7 @@ from multiprocessing import Value, Lock import numpy as np from time import sleep +import plotly.express as px import plotly.graph_objects as go from dash import Dash, Input, Output, dcc, html @@ -165,7 +166,46 @@ def update_graph(n_clicks): assert dash_dcc.get_logs() == [] -def test_grbs005_graph_update_frames(dash_dcc): +def test_grbs005_graph_customdata(dash_dcc): + app = Dash(__name__) + + df = px.data.tips() + df["id"] = df.index + + app.layout = html.Div( + [ + dcc.Graph( + id="pie-chart", + figure=go.Figure( + data=[ + go.Pie( + labels=df["day"], ids=df["id"].map(str), customdata=df["id"] + ) + ] + ), + ), + dcc.Textarea(id="text-area"), + ] + ) + + @app.callback(Output("text-area", "value"), Input("pie-chart", "clickData")) + def handleClick(clickData): + return json.dumps(clickData) + + dash_dcc.start_server(app) + dash_dcc.wait_for_element("#pie-chart") + + dash_dcc.find_elements("g .slice")[0].click() + + data = dash_dcc.wait_for_element("#text-area").get_attribute("value") + assert data != "", "graph clickData must contain data" + + data = json.loads(data) + assert "customdata" in data["points"][0], "graph clickData must contain customdata" + assert data["points"][0]["customdata"][0] == data["points"][0]["pointNumbers"][0] + + +def test_grbs006_graph_update_frames(dash_dcc): app = Dash(__name__) def get_scatter(multiplier, offset):