plotly / plotly/react-plotly.js

uirevision not preserving the trace's visibility (legend click)

Đang mở
#171 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
JavaScript
Star
1.1k
Fork
138
Merge trung bình
3 ngày 2 giờ
Pull request đã merge (30 ngày)
4

Mô tả

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;

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu với component App được cung cấp cùng các component plotly_test và NavbarTop, sau đó tái hiện vấn đề bằng cách nhấp vào một mục trong chú giải và kích hoạt các cập nhật setState dựa trên callback của Button2. Theo dõi cách react-plotly.js nhận các Props đã cập nhật và xác định lý do uirevision không còn duy trì khả năng hiển thị; hoàn tất khi khả năng hiển thị của trace được chọn vẫn không thay đổi sau các cập nhật đó.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript, react
Lĩnh vực
data-visualization, frontend
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.