Ponownie uruchamia responsywny kontener nieprawidłowo zmienia rozmiar w module flexbox


Próbuję utworzyć niestandardową zwijaną legendę dla mojej aplikacji do wizualizacji danych. Używa reagowania i rechartów. komponent renderuje się dobrze za pierwszym razem. Ale kiedy zwijam legendę i ponownie ją otwieram, responsywny kontener nie kurczy się, by pasować. Byłoby łatwiej, gdybym znał rozmiar kontenera nadrzędnego w pikselach, ale nie mam tego rodzaju informacji o renderowaniu. Czy to błąd z rechartami lub flex box, czy też robię to źle?
Oto kod:

https://codesandbox.io/s/8krz9qjk52
https://codesandbox.io/s/8krz9qjk52
Wyjaśnienie: Problem polega na tym, że kiedy zamykam, a następnie otwieram legendę, komponent legendy jest wypychany z rzutni, a diagram nie zmniejsza się z powrotem do swojego pierwotnego mniejszego rozmiaru.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wydaje się to dość powszechne, ale realnym rozwiązaniem jest ustawienie szerokości na 99% z wysokością lub współczynnikiem proporcji.
<ResponsiveContainer width="99%" aspect={3}>
Zobacz ten numer:
https://github.com/recharts/recharts/issues/172
https://github.com/recharts/recharts/issues/172
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ponieważ mam podobne problemy w swoim projekcie, zdecydowałem się trzymać tego pytania. W końcu udało mi się uzyskać działające rozwiązanie!
codesandbox
https://codesandbox.io/s/xpz8y5w77w
Wymienię zmiany, które wprowadziłem, od największych do najmniejszych:

ja

podniósł stan
https://reactjs.org/docs/lifting-state-up.html
z
CustomLegend
do
CustomChart
.

  • Teraz
    CustomChart
    odpowiada za to, co się dzieje. Przekazuje informacje o widoczności do
    CustomLegend
    jako rekwizytu. Skąd
    CustomChart
    wie, kiedy należy zmienić stan
  • CustomChart
    ma funkcję składową o nazwie
    handleButtonClick
    , która ustawia jej stan.
    handleButtonClick
    jest wysyłany do
    CustomLegend
    w postaci pomoc. Dlatego
    CustomChart
    renderuje
    CustomLegend
    w następujący sposób:
    <CustomLegend items={legendData} onClick={this.handleButtonClick} legendVisible={this.state.legendVisible}/>
    Teraz w
    CustomLegend
    możemy uwzględnić to w definicji przycisku
    :
    onClick = {this.props.onClick}
    zwróć uwagę, że ten szablon działa tylko w jeśli oryginalna funkcja jest powiązana z rodzicem, ponieważ zmienia stan rodzica.
chart-container
jest teraz

CSS
Siatkowaty
https://gridbyexample.com/examples/
pojemnik.

  • Renderuje styl wbudowany, który obsługuje szerokość kolumn na podstawie stanu.
    <div className="chart-container" style={{ gridTemplateColumns: this.state.legendVisible  "80% 1fr" : "1fr min-content" }}>
    Zauważ, że
    1fr
    to jednostka ułamkowa, która w tym przypadku służy do wypełnienia pozostałej przestrzeni.
  • W
    styles.css
    grid-auto-flow
    to
    column
    , co pozwala na umieszczanie obiektów w siatce w kolumnach. Elementy, które umieściliśmy w siatce, to
    SampleChart
    i
    CustomLegend
    , więc
    SampleChart
    to lewa kolumna, a
    CustomLegend
    -right .
  • gridTemplateColumns: 80% 1fr
    : Kiedy legenda jest widoczna, chcemy, aby lewa kolumna wypełniała 80% szerokości, a prawa kolumna wypełniła resztę.
  • gridTemplateColumns: 1fr min-content
    : Kiedy legenda jest niewidoczna, chcemy, aby prawa kolumna zajmowała minimum miejsca, które wypełniają jej elementy, a lewa kolumna - pozostałe miejsce.
CustomLegend
ma tylko jedną metodę
render
.

  • Zamiast
    renderVisible
    i
    renderHidden
    istnieje jedna metoda, która warunkowo renderuje
    legend-list
    na podstawie właściwości (w zależności od stanu
    CustomChart
    ).
  • kontener-legendy
    jest teraz zawsze renderowany (jest to element siatki).
Inne drobne zmiany:

  • W
    SampleChart
    :
    & < ResponsiveContainer width = "100%" height = "100%" className = {props.className} & >
    zostało to zmienione, ponieważ
    & < SampleChart className = "chart-area" data = {data}/& >
    w rzeczywistości wysyła
    className
    jako odniesienie. Uważaj z tym! Musisz ustawić
    className
    bezpośrednio na tag nadrzędny w zwracanej hierarchii
    SampleChart
    (w tym przypadku
    ResponsiveContainer
    ). spróbuj wrócić do kod źródłowy https://codesandbox.io/s/8krz9qjk52i zmień
    background-color
    na
    chart-area
    w
    styles.css
    (nic się nie dzieje!).
  • overflow: scroll
    we wszystkich przypadkach pochodzi z
    styles.css
    , ponieważ już go nie potrzebujemy.

Zauważysz, że jeśli spróbujesz utworzyć układ siatki, używając tylko jednostek
fr
lub dowolnego elastycznego układu w
chart-container
, rozmiar wykresu nie zostanie odpowiednio zmieniony. Niestety
ResponsiveContainer
firmy Recharts po prostu nie działa zbyt dobrze z Grid lub Flexbox (główni współtwórcy wycofują wsparcie -

bez zatwierdzeń
https://github.com/recharts/re ... ivity
obecnie przez 3 miesiące).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dodaj następujące elementy do swojego pliku
styles.css
:
html, body, #root {
width: 100%;
height: 100%;
}

w przeciwnym razie
.chart-container
, nawet jeśli jego szerokość i wysokość są ustawione na 100%, nie wypełni całego widocznego obszaru. Następnie w
SampleChart.jsx
zmień to:
<ResponsiveContainer width="100%" height={400}>

do tego:
<ResponsiveContainer width="100%" height="100%">

aby Twój
ResponsiveContainer
„urósł ... no, responsywny.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się