Я пытаюсь создать настраиваемую сворачиваемую легенду для своего приложения визуализации данных. Он использует реакцию и перерисовку. компонент хорошо отображается в первый раз. Но когда я сворачиваю легенду и снова открываю ее, отзывчивый контейнер не сжимается, чтобы поместиться. Это было бы проще, если бы я знал размер родительского контейнера в пикселях, но у меня нет этой информации о рендеринге. Это ошибка с recharts или flex box, или я делаю это неправильно?
Вот код: https://codesandbox.io/s/8krz9qjk52
Уточнение: проблема в том, что когда я закрываю, а затем открываю легенду, компонент легенды выталкивается из области просмотра, и диаграмма не возвращается к исходному меньшему размеру.






Добавьте к вашему styles.css следующее:
html, body, #root {
width: 100%;
height: 100%;
}
в противном случае .chart-container, даже если его ширина и высота установлены на 100%, не займет всю область просмотра. Затем в SampleChart.jsx измените это:
<ResponsiveContainer width = "100%" height = {400}>
к этому:
<ResponsiveContainer width = "100%" height = "100%">
чтобы сделать ваш ResponsiveContainer высотой ... ну, отзывчивым.
Извините, я неправильно истолковал вопрос. Посмотрите мой второй ответ!
Поскольку в моем проекте у меня возникают аналогичные проблемы, я решил остановиться на этом вопросе. Наконец-то я смог получить рабочее решение!
Я перечислю сделанные мной изменения от самых больших до самых маленьких:
I lifted state up from
CustomLegendtoCustomChart.
Теперь за то, что происходит, отвечает CustomChart. Он передает информацию о видимости в CustomLegend как опору. Как CustomChart узнает, когда нужно изменить состояние?
CustomChart имеет функцию-член handleButtonClick, которая устанавливает его состояние. handleButtonClick отправляется на CustomLegend как опора. Итак, CustomChart отображает CustomLegend следующим образом:
<CustomLegend
items = {legendData}
onClick = {this.handleButtonClick}
legendVisible = {this.state.legendVisible}
/>
Теперь в CustomLegend мы можем включить это в определение button: onClick = {this.props.onClick} Обратите внимание, что этот шаблон работает только в том случае, если исходная функция привязана к родительскому элементу, поскольку он изменяет состояние родительского элемента.
chart-containeris now a CSS Grid container.
Он отображает встроенный стиль, обрабатывающий ширину столбца в зависимости от состояния.
<div
className = "chart-container"
style = {{
gridTemplateColumns: this.state.legendVisible
? "80% 1fr"
: "1fr min-content"
}}
>
Обратите внимание, что 1fr - это дробная единица, которая в данном случае служит для заполнения оставшегося места.
styles.css для grid-auto-flow установлено значение column, что позволяет размещать объекты в сетке в виде столбцов. В сетку мы помещаем SampleChart и CustomLegend, поэтому SampleChart - это левый столбец, а CustomLegend - правый столбец.gridTemplateColumns: 80% 1fr: когда легенда видна, мы хотим, чтобы левый столбец занимал 80% ширины, а правый столбец заполнял остальную часть.gridTemplateColumns: 1fr min-content: когда легенда невидима, мы хотим, чтобы правый столбец занимал минимальное пространство, которое заполняют его элементы, а левый столбец - оставшееся пространство.
CustomLegendhas only a singlerendermethod.
renderVisible и renderHidden существует один метод, который условно отображает legend-list на основе свойств (в зависимости от состояния CustomChart).legend-container всегда выполняет рендеринг (это элемент сетки).Other small changes:
SampleChart: <ResponsiveContainer width = "100%" height = "100%" className = {props.className}> Это было изменено, потому что <SampleChart className = "chart-area" data = {data} /> фактически отправляет className как опору. Будьте осторожны с этим! Вам необходимо установить className непосредственно на родительский тег в возвращаемой иерархии SampleChart (в данном случае ResponsiveContainer). Попробуйте вернуться к своему оригинальные коды и заменить background-color на chart-area в styles.css (ничего не происходит!).overflow: scroll во всех случаях от styles.css, потому что он нам больше не нужен.Вы заметите, что если вы попытаетесь разметить сетку, используя только блоки fr или любую гибкую разметку на chart-container, размер диаграммы не изменится должным образом. К сожалению, ResponsiveContainer от Recharts не очень хорошо работают с Grid или Flexbox (основные участники проекта постепенно сокращают поддержку - нет коммитов уже через 3 месяца).
Это кажется довольно хакерским, но жизнеспособное решение - установить ширину 99% с высотой или соотношением сторон.
<ResponsiveContainer width = "99%" aspect = {3}>
См. Эту проблему:
https://github.com/recharts/recharts/issues/172
Это сработало для меня. Не знаю, почему это работает. Спасибо, если кто-то сможет пролить свет на этот вопрос.
это действительно помогает. Когда я закрываю, а затем открываю легенду, компонент легенды выталкивается из области просмотра, и диаграмма не возвращается к исходному меньшему размеру.