Skip to content
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

Brush Interaction for XY-chart #117

Merged
merged 12 commits into from
Aug 22, 2018
Merged

Conversation

conglei
Copy link
Collaborator

@conglei conglei commented Aug 13, 2018

💔 Breaking Changes

🏆 Enhancements

Brush interaction is supported!

more_control_brush

📜 Documentation

🐛 Bug Fix

🏠 Internal

Copy link
Owner

@williaster williaster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great overall! 🙌

@@ -25,3 +25,4 @@ export { PatternLines, PatternCircles, PatternWaves, PatternHexagons } from '@vx
export { withScreenSize, withParentSize, ParentSize } from '@vx/responsive';
export { default as withTheme } from './enhancer/withTheme';
export { chartTheme as theme } from '@data-ui/theme';
export { default as Brush } from './selection/Brush';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you think all of the brush components should go under src/components/brush/... and the utils could go under src/util/brush?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here, I was thinking for a long term, will we keep the code here or we should move it to vx? The reason I put it in the utils is that I think now it is the temporary solution.

return React.cloneElement(Child, {
xScale,
yScale,
innerHeight,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious if innerWidth/Height can be computed from the passed scales?

}));
}

width() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit -- I'd call these getWidth/Height for clarity

}}
</Drag>
{/* selection */}
{start &&
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if start/end happened to be 0 these might not work

stageWidth={stageWidth}
stageHeight={stageHeight}
brush={{ ...this.state }}
fill="rgba(4, 154, 251, 1.000)"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we expose style parameters as props do you think?

stageWidth={stageWidth}
stageHeight={stageHeight}
updateBrush={this.update}
brush={this.state}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason you pass state directly here vs copy it for BrushSelection?

import React from 'react';
import { Drag } from '../drag';

function handleResizeMove(drag, onBrushEnd) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd possibly add these as statics

@@ -0,0 +1,115 @@
import React from 'react';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you'll get some linting errors for Drag.js not having a .jsx name. Also similar to brush we could move this to a src/components folder.

@conglei
Copy link
Collaborator Author

conglei commented Aug 21, 2018

@williaster Now the code is done for the first version. PTLA :)

Copy link
Owner

@williaster williaster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is amazing! really nice work!!! 🤑

Sorry for the many comments, they're mostly just conventions/nothing huge. I appreciate all of the time you've put into this!

xScale={{ type: 'time' }}
yScale={{ type: 'linear' }}
margin={{ left: 100, top: 64, bottom: 64 }}
{...rest}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can get rid of this right?

margin={{ left: 100, top: 64, bottom: 64 }}
{...rest}
>
<LinearGradient id="area_gradient" from={colors.categories[2]} to="#fff" />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need the gradient + pattern? (I'd just remove anything unneeded in case people look at the example usage)

@@ -259,6 +275,10 @@ class XYChart extends React.PureComponent {
const { numXTicks, numYTicks } = this.getNumTicks(innerWidth, innerHeight);
const barWidth = xScale.barWidth || (xScale.bandwidth && xScale.bandwidth()) || 0;
const CrossHairs = []; // ensure these are the top-most layer
let hasBrush = false;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you initially set let Brush = null and then just call Brush && React.cloneElement(Brush ...) below to get rid of the extra hasBrush var?

innerHeight,
innerWidth,
margin,
registerStartEvent:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add a comment about why this isn't needed for a series event trigger?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! In deed for area chart and bar chart, we do need to do like this. Will revise the code logic.

} else if (brushRegion === 'yAxis') {
top = 0;
brushRegionHeight = innerHeight;
if (yAxisOrientation === 'right') {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does anything break if there are no axes passed to XYChart and brushRegion is the axis that's not passed? (which would make x/yAxisOrientation null)?

I guess that makes no sense from a user perspective, but maybe should fail intelligently?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@williaster it won't to broken. User can still brush from margin areas.

<rect
width={6}
height={height}
x={brush.domain.x1 - left - 3}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this getting a magic-number error?

cursor: brush.isBrushing ? undefined : 'ew-resize',
}}
onMouseUp={event => {
if (brush.isBrushing) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote for moving these into class functions/binding them, so they aren't created on renders

@@ -0,0 +1,119 @@
/* eslint react/jsx-handler-names: 0 */
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we also rename them according to the eslint conventions?

}
}

Drag.propTypes = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment re top of file for Airbnb style convention.

);
}

function simulateFullDrag(target) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! 💯

@conglei
Copy link
Collaborator Author

conglei commented Aug 22, 2018

@williaster I've revised the code per comments :) Thanks for catching so many issues :)

For react/jsx-handler-names, as we discussed, all the files with this will be moved to @vx/brush and the current naming convention follows the style in @vx

@conglei
Copy link
Collaborator Author

conglei commented Aug 22, 2018

Hmm, I still haven't figured out why the testings failed here. :(

@williaster
Copy link
Owner

Hmm, I'll try to pull/debug tomorrow, and worse case scenario we can merge to get into DLS. Thanks for making the other fixes!

@williaster
Copy link
Owner

I noticed a couple of possible issues when playing with it:

  • In this one I'm not able to move the brush all the way to the right, and at the end it jumps vertically

  • In this one I'm able to move the x-axis brush vertically even though that should be disabled.

@conglei
Copy link
Collaborator Author

conglei commented Aug 22, 2018

@williaster it seems to be resizing issue. so the bugs happened after the window size changed right ?

@conglei
Copy link
Collaborator Author

conglei commented Aug 22, 2018

@williaster Just fixed the issue. Maybe we can first merge this and I will create an issue for remaining tasks on the brush package.

@williaster
Copy link
Owner

SGTM 👍 Thanks for all of the time spent so far 🙌Excited for this! 🎉

@williaster williaster merged commit f7d35b9 into williaster:master Aug 22, 2018
@williaster williaster changed the title [WIP] Brush Interaction for XY-chart Brush Interaction for XY-chart Aug 22, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants