plotly / plotly/react-plotly.js

OnClick callback receives incomplete data when using React.SetStateAction

オープン
#358 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
JavaScript
スター
1.1k
フォーク
138
平均マージ
3日 2時間
マージ済み PR(30日)
4

説明

I'm writing an onClick event for my Pie chart and then using data provided in event.points[index] for my needs to create a custom popover. I noticed that when I click on the pie chart slice for the first time, I receive data including the properties percent and text, and both are numbers. percent represents a decimal percentage value, and the text shows the real value

{ 
...
  percent : 0.5773337926283155,
  pointNumber: 0,
  pointNumbers: [0],
  text: 1676,
  v: 1676,
  value: 1676,
... 
}

When I click just right after that on the other pie sector, I recieve the different data structure

{ 
...
  percent : undefined,
  pointNumber: 0,
  pointNumbers: [0],
  text: '57%',
  v: 1676,
  value: 1676,
... 
}

As you can see now, percent is undefined, and text is a formatted string with a percent unit. It also missing bbox props. I do not use it by I just noticed that.

In my onClick handlers, I'm changing the state of the React component to store the clicked point. Also, I have a popover outside click event (provided by Mantine), which is basically a document click listener, and I'm resetting my stored click point.

When I don't mutate the React component state and just console.log the event points in my onClick handler, the data is consistent and always contains the property percent, and the text is a number.

It seems like the React state update in my component triggers some Plotly rerender, which breaks the logic of computing the data.

From the code of plotly.js, I noticed that you are reusing hoverData, computing it, and sending it as a callback parameter. I decided to compare onClick and onHover events parameters. Comes up that the onHover handler always receives correct data and properties percent, bbox and text is a number, but just right after click this parameters are missing in onClick event.

Here is an example in Codepen where I managed to reproduce similar issues

https://codepen.io/graylog-max/pen/myPjYZN

I this example I have:

  • onCLickHandler it stores data from points to react.useStates and logs in console percent, bbox and text
  • onHoverHandler it stores data from points to react.useStates and logs in console percent, bbox and text
  • React.useEffect, which adds document.addEventListener to somehow mock Mantine onOutsideClick which also change the state

Here are scenarios of inconsistent behaviors depending on whether in some of these cases the state update is disabled. You can do that by just commented lines setClickPoint(ev.points[0]); , setHoverPoint(ev.points[0]); or whole useEffect

  1. All three handlers do not mutate state. No matter how many times we click or hover the data is consistent
Image Image
  1. only onCLickHandler mutating the state. The first click on the slice has all data, but when we click, just right after that, on the same slice again, the data doesn't contain all fields. If before clicking on the slice again we click somewhere outside of the chart, then the click data is fine. Hover data is always fine.
Image Image Image
  1. onCLickHandler enabled mutation and useEffect or onHoverHandler as well. Then onClick data is missing bbox and percent but hover is fine
Image Image
  1. If you put the brakepoint node_modules/plotly.js/src/traces/pie/plot.js line 471 inside the function sliceTop.on('click', function(pt) then everything works fine in any scenarion. I think that proves that computed data needs more time to be completed before getting to onClick callbacks.

I can fix my initial issue just by calculating the percent by myself, but this bug might be a sign of other potential issues, so it would be nice to find a solid fix. The bug relates to React state updates, which are happening very often.

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされたCodePenの再現から始め、Reactのstate更新とdocument click listenerを有効にした状態で、onClickイベントデータとonHoverイベントデータを比較します。node_modules/plotly.js/src/traces/pie/plot.jsの471行目付近を調べ、click callbackがそのポイントデータを受け取るまでの流れを追跡します。Reactの再レンダリング後に繰り返しクリックしても、percent、bbox、期待される数値テキストが一貫して含まれていれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
javascript, react
領域
data-visualization, frontend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。