plotly / plotly/react-plotly.js
uirevision not preserving the trace's visibility (legend click)
まだ誰も着手していません。
- 主要言語
- JavaScript
- スター
- 1.1k
- フォーク
- 138
- 平均マージ
- 3日 2時間
- マージ済み PR(30日)
- 4
説明
When adding the below line to the layout [1], one would expect that the chart preserves the trace's visibility even after the data is reload, or other elements of a webapp change.
Whilst it works nice and clean in a simple test, in an almost empty react project, it doesn't seem to work well in a medium sized app, with dozens of Components and states.
In my specific example, it is enough for someone to change the navigation bar dropdowns, which trigger an event changing the state of App.js, where the charts originate, too. In the very same second when the dropdown changes its value, the charts lose their 'memory' of what was previously selected, and revert back to their original state.
I'll see if I can reproduce this in a sharable code-pen, but perhaps someone already encountered this issue?
Am using react-plotly 2.4.0 with plotly.js 1.48.0
**1**
uirevision: 'true'
Was able to recreate it. ui revision seems to be failing when callbacks are used in reacts setState.
Clicking 'Button2' twice, will reset the selected traces to their default. Simply removing the callback (which does not affect the plot) makes it behave as intended again.
import React, { Component } from 'react';
import './App.css';
import MyPlot from "./plotly_test";
import NavbarTop from "./NavbarTop";
class App extends Component {
constructor() {
super();
this.onClickButton = this.onClickButton.bind(this);
this.onClickButton2 = this.onClickButton2.bind(this);
this.state = {
myID: 1,
countries: {names: ['Alal', 'lqwel', 'qpweok'], labels: ['loqwe', 'qwoel', 'qlweo']},
country: 'Poland',
}
};
onClickButton() {
this.setState({myID: this.state.myID + 1})
this.changeCountry = this.changeCountry.bind(this);
var labels = this.state.countries.labels
this.setState({
labels: labels.push('SomeLabel')
})
}
onClickButton2() {
this.setState({
country: "SomeCountry",
}, ()=>{
this.setState({
country: 'Yet Another'
})
})
}
changeCountry = (value, callback) => {
this.setState({
country: value,
}, () => {
callback(value)
})
};
getCharts() {
let components = [];
components.push((<MyPlot id={this.state.myID}/>));
return components
}
render() {
let charts = this.getCharts();
return (
<div>
<h1>{this.state.country}</h1>
<NavbarTop callbackChange={this.changeCountry}/>
<div className="App">
{charts}
<button
onClick={this.onClickButton}
> Button1
</button>
<button
onClick={this.onClickButton2}
> Button2
</button>
</div>
</div>
)
}
}
export default App;
Navbar:
import React, { Component } from 'react';
class NavbarTop extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.props.callbackChange(event.target.value, (something) => {
console.log(something);
})
}
render() {
return (
<div>
<nav>
<nav>
<select name="countries" id="countries"
onChange={this.handleChange} value={'PL'}>
<option value='DE'>Germany</option>
<option value='FR'>France</option>
<option value='ES'>Spain</option>
<option value='UK'>United Kingdom</option>
</select>
</nav>
</nav>
</div>
);
}
}
export default NavbarTop;
plotly_test:
import React, {Component} from 'react'
import Plot from 'react-plotly.js'
class MyPlot extends Component {
render() {
const rand = () => 1;
var x = [1, 2, 3, 4, 5];
const new_data = (trace) => Object.assign(trace, {y: x.map(rand)});
// add random data to three line traces
var data = [
{mode:'lines', line: {color: "#b55400"}},
{mode: 'lines', line: {color: "#393e46"}},
{mode: 'lines', line: {color: "#222831"}}
].map(new_data);
var layout = {
title: this.props.id,
uirevision:'true',
xaxis: {autorange: true},
yaxis: {autorange: true}
};
return (
<div>
<Plot
layout={layout}
data={data}
/>
</div>
);
}
}
export default MyPlot;
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
提供された App コンポーネントと plotly_test および NavbarTop コンポーネントから始め、凡例項目をクリックして Button2 の callback ベースの setState 更新を発生させることで問題を再現します。react-plotly.js が更新された Props をどのように受け取るかを追跡し、なぜ uirevision が可視性の保持を停止するのかを特定します。これらの更新後も選択した trace の可視性が変わらない状態になれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- javascript, react
- 領域
- data-visualization, frontend
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100