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

[charts] Improve charts interaction for mobile users #13692

Conversation

JCQuintas
Copy link
Member

@JCQuintas JCQuintas commented Jul 1, 2024

  • Disable touchActions on mobile inside the SVG
  • Move events to use pointer events instead of high-level touch/mouse for better pointer capture control.
    • This allows users to move the thumb around on mobile and the tooltip updates accordingly
  • Move tooltip to the top when we detect user is not using a mouse
  • Add some extra padding between pointer and tooltip
    • const yPosition = y - (pointerType === 'touch' ? 40 - height : 0);
    • height is the height of the pointer itself, eg: a mouse is usually 1px, a thumb is around 2-5px, a touch indicator on mobile emulation is a big circle, ~30px, this formula allows us to display somewhat decently in most common situations.

Recoding on actual mobile

Screen_Recording_20240701_175555_Chrome.mov

fixes #13109

@JCQuintas JCQuintas added enhancement This is not a bug, nor a new feature component: charts This is the name of the generic UI component, not the React module! labels Jul 1, 2024
@JCQuintas JCQuintas self-assigned this Jul 1, 2024
@mui-bot
Copy link

mui-bot commented Jul 1, 2024

Deploy preview: https://deploy-preview-13692--material-ui-x.netlify.app/

Generated by 🚫 dangerJS against 81b0e5a

Copy link
Member

@alexfauquette alexfauquette left a comment

Choose a reason for hiding this comment

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

Looks nice

packages/x-charts/src/ChartsSurface.tsx Show resolved Hide resolved
const { x, y } = mousePosition;
const { x, y, pointerType, height } = mousePosition;
const xPosition = x;
const yPosition = y - (pointerType === 'touch' ? 40 - height : 0);
Copy link
Member

Choose a reason for hiding this comment

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

What is the height? I've seen it come from the event, but I don't know what it's referring to.

I'm not sure it's the correct place to add space. This yPosition tracks the pointer position. If a user what to have a different behavior they will have to take that condition into account.

For now, the sapce is added by sx={{ mx: 2 }} in the tooltip. Maybe we could move this behavior at the same place

Copy link
Member Author

Choose a reason for hiding this comment

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

I explained height in the description of the PR 😅

Unsure if it would be a good idea to use mx for that, but we should probably allow it to be controllable somehow, the goal of this change is to allow the tooltip to be visible regardless of the pointer type, eg: a mouse cursor has a very thin point, so it is easy to see behind it, a thumb on the other hand would mostly hide the tooltip we want to see 😅

Copy link
Member

Choose a reason for hiding this comment

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

I explained height in the description of the PR 😅

My bad

Another issue with modifying this point position is that tooltip is not aware of this modification. So when the tooltip does not have the space to display the content, it swiches.

Here for example the charts are at the top, preventing the tooltip to be at the top. So it displays at the bottom but still have some shift to the top (I added a red dot to show where the pointer were

Screenshot from 2024-07-02 15-39-29

Copy link
Member Author

Choose a reason for hiding this comment

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

I've moved the logic to use popper.modifiers.offset, it seems to solve your concerns while keeping the functionality. Let me know what you think

Comment on lines +14 to +18
const onPointerDown = (event: React.PointerEvent) => {
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
event.currentTarget.releasePointerCapture(event.pointerId);
}
};
Copy link
Member

Choose a reason for hiding this comment

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

Could you explain what this code is doing?

I'm not familiar with those pointer specific events

Copy link
Member Author

Choose a reason for hiding this comment

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

The if is mostly optional I believe, is just there for an early return if the pointer has been released. But in general,

if :element is capturing all the pointer events for pointer with :id
then release pointer capture for :id so it can be captured by another element :element'

In effect what it does is allow a single touch to be captured by any element it passes over rather than just the first one. 😅

JCQuintas and others added 2 commits July 2, 2024 14:18
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com>
Signed-off-by: Jose C Quintas Jr <juniorquintas@gmail.com>
@JCQuintas JCQuintas enabled auto-merge (squash) July 2, 2024 18:13
@JCQuintas JCQuintas merged commit 18b7be6 into mui:master Jul 2, 2024
15 checks passed
@JCQuintas JCQuintas deleted the 13109-charts-improve-interaction-for-mobile-user branch July 2, 2024 18:32
DungTiger pushed a commit to DungTiger/mui-x that referenced this pull request Jul 23, 2024
Signed-off-by: Jose C Quintas Jr <juniorquintas@gmail.com>
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com>
thomasmoon pushed a commit to thomasmoon/mui-x that referenced this pull request Sep 9, 2024
Signed-off-by: Jose C Quintas Jr <juniorquintas@gmail.com>
Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: charts This is the name of the generic UI component, not the React module! enhancement This is not a bug, nor a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[charts] Improve interaction for mobile user
3 participants