New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BrushY: A dummy vertical Brush for scaling/panning the YAxis #4036
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really appreciate you taking the time to add this, I think we'll need to think on this a little more before full release though. We want to sure we test fully to catch any edge cases and aren't adding to our already large pile of tech debt.
There are some changes in this PR that are outside of the context of the PR (version bump, eslint changes) that will need to be reverted if we are to merge this.
Will also approvals on direction from some others as this doesn't look like the direction we want to continue to move in.
Really appreciate the legwork!
{ day: '14', value: 10 }, | ||
]; | ||
|
||
function BrushYDemo() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't really use the demo project anymore, can you add this code to the storybook instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, as soon as I figure out how to do it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be similar code luckily! You can add this to the Brush examples: storybook - Examples - Cartesian - Brush
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add it as a new component as I couldn't figure out how to incorporate changes in the Brush component and have it rendered twice. I trust that the planned refactoring will enable this. Until then...
package.json
Outdated
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "recharts", | |||
"version": "2.10.3", | |||
"version": "2.10.4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't bump the version unless an official recharts release, we'll handle this internally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course, I'll revert this.
Thank you @ckifer for your lightning fast response. I need this component for the react app we are developing. If you decide not to include it in the master, could you please kindly advise the best approach to achieve this functionality? At the moment, I am keeping the changes in the fork and installing them using yalc. |
We definitely want the functionality eventually! We're just trying to take a different approach with some things (as you can see the generate function is very large and hard to follow). If we can get this to a good place we can maybe merge it, but we might also wait until after some more refactoring has been done to make it easier to understand/test and so we can have a more robust API. So it just might be a little bit before this gets merged/released with that said. I'll wait for your changes and some reviews from others and we can go from there. In terms of publishing yourself you can publish your own fork of recharts on npm if you'd like though it's always better to follow along with master since you'll miss out. You could publish your fork and use that until we merge this if you really need this functionality now. Thanks! |
const { offset, updateId } = this.state; | ||
|
||
// TODO: update brush when children update | ||
return cloneElement(element, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is precisely the pattern we are trying to get rid of 😬 try to think of an API that does not require cloning, and replacing the props internally
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm on the other hand it would make sense to have the same API as the existing Brush. After all it's the same thing, isn't it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@PavelVanecek I couldn't find an easy answer to the problem of rendering the same component twice. Now that I am a bit more familiar with the workings of the package, it might have been easier than I thought. However, I had to make some detailed conformational changes, and played with the endIndex range. So, a separate component made sense
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this does not add any extra effort for future migration, if it simply stays in line with the existing brush. We will have to migrate the brush either way.
@@ -0,0 +1,570 @@ | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't even see this file... I wonder if we can do these changes without a new component and instead with an orientation
prop or similar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is not being able to render the same component twice. If that's solved, than BrushY could be integrated into Brush
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. We could remove the once
flag and just rely on consumers to not render more than one brush in the same orientation (or throw an invariant if they do) @PavelVanecek what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pattern to solve this is done for the Axis. A shared CartesianAxis exists, but then we also have XAxis and YAxis. Both of them internally use CartesianAxis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work with user value here, please do not copy paste the component but instead extend the existing one in alignment with the libraries concepts.
i.e. we also have a CartesianAxis and then we have an XAxis component and a YAxis component.
That is a pattern that seems well applicable here. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is certainly the blocking thing here.
We do not want to simply copy code with small variations.
This will reduce our velocity going forward massively.
Please do reuse the existing code for the Brush and extend it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the existing pattern makes sense. Would it be acceptable to decommission Brush and create both an XBrush and a YBrush component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be preferred, but sadly not possible without a major version increase. For now I would suggest to export Brush, and XBrush (an alias for Brush), and YBrush, and mark Brush as deprecated (but still export and not break anything).
@ckifer Would that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be completely honest, in the next (or a future) major version I think we should remove Brush entirely and instead implement a recharts native pan and zoom feature. Brush is clunky, especially for Y values.
(That's opinion only and probably won't happen)
What's the issue with removal of the once prop and just using Brush with an orientation prop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also possible, but I like the consistency of patterns between components that we would have if we had YBrush and XBrush
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, lets get it to that state where components are shared and go from there
I believe that the brush could be accepted as a child of the x and y axes, behaving in the orientation of the axis. |
Yeah I think that could make sense. Breaking API change of course. Once we get brush info into context all of this gets easier |
I find this super useful for vertical barcharts ( |
The changes clone and transform Brush as a vertical slider, but do not cast a function to it.
Description
The new BrushY keeps track of the startIndex and endIndex within a user-defined number of steps. BrushY can be linked to the YAxis to set an appropriate domain for vertical scrolling/zooming.
Related Issue
Zoom and pan - Issue #710 : #710 (comment)
Motivation and Context
Brush performs horizontal scrolling/zooming by filtering the source data as needed. BrushY removes the filtering step and provides a dummy vertical slider to scale/pan the YAxis.
How Has This Been Tested?
A demo is included in the demo/component folder to show how the link between BrushY and YAxis can be established by the user. The demo uses the useState hook to update the YAxis limits. In addition, a test is included in the test/cartesian folder (similar to the test for Brush) to confirm that the component is properly rendered.
To enable rendering the component and remove the data (domain) filtering step, changes are also done in generateCategoricalChart.tsx.
Screenshot:
Types of changes
Checklist: