victory
victory copied to clipboard
Add responsive container example to docs
Hello everyone
Bugs and Questions
Checklist
-
[X] I have read through the FAQ and Guides before asking a question
-
[X] I am using the latest version of Victory
-
[X] I've searched open issues to make sure I'm not opening a duplicate issue
The Problem
I have some troubles to create a responsive chart. It seems so simple in the demo but cannot reproduce in real context.
here what looks like with default settings (so responsive) it does not fill at all the container:
here with a width set, depending on the width it will display better but does not handle all screen size:
Here with preserveAspectRatio="none"
, technically it works, but so ugly.
Reproduction
Here a sandbox that try to reproduce the problem as close as I could : sandbox
Hi @newza-fullmetal, I don't think Victory provides a built-in way to do this currently. In the past, I have needed to do a bit of manual work to measure the size of the container, and pass in updated width and height props when the container changes size. Check out this code sandbox for an example. https://codesandbox.io/s/responsive-victory-chart-bsy53
It wouldn't be a bad idea to add this to our how-to guides in the documentation - I'll keep this issue open for now as a reminder to do that.
@beccanelson hooo ok. I though that the responsive props was meant to do that. I did not understand I have to calculate myself. Thanks for the sandbox, I will give it a try :)
@beccanelson Ok after some tries I have been able to make it works, but I removed the props height, it workds better in my case to only let the width responsive cause height is fixed. But it does not work on first Render, even in your sandbox, it is always undefined
I have been able to do it by modifiyng the code you send me, and regroup everything one component
const ResponsiveVictoryChart = (initialProps) => {
const ref = React.useRef();
const [width, setWidth] = useState();
const [height, setHeight] = useState();
const getSize = () => {
if (ref && ref.current !== null) {
setWidth(ref.current.clientWidth);
setHeight(ref.current.clientHeight);
}
};
useEffect(() => {
getSize();
window.addEventListener('resize', getSize);
return () => window.removeEventListener('resize', getSize);
}, [ref]);
const props = {
...initialProps,
width,
height,
};
return (
<div style={{ height: '100%' }} ref={ref}>
<VictoryChart {...props} />
</div>
);
};
I am not sure of the usefullness of the line
return () => window.removeEventListener('resize', getSize);
But it seems to prevent some errors
Thanks for the tip
Return statements from useEffect
hooks aren't super intuitive, but basically that's the cleanup function that prevents the window from listening for events after the component has unmounted.
This was a pretty simplified example, but there might be more work to do to get the width and height working on first render. It looks like you might also be able to call element.getBoundingClientRect
to get a similar measurement.
@becca-bailey @newza-fullmetal well, as for a new user it is not really intuitive to get into that responsive container. I would rather prefer the recharts <ResponsiveContainer> which itself sets height and width without any additional props. In my case with the upper code I still have to resize screen first to make graph fit all the space...
here is nice topics with nice examples with responsive container
https://github.com/FormidableLabs/victory/issues/396
This issue is stale because it has been open for 90 days with no activity. If there is no activity in the next 7 days, the issue will be closed.