Skip to content

Show the hovered time in the ruler at the top of the timeline.#4748

Merged
julienw merged 2 commits into
firefox-devtools:mainfrom
fqueze:show-hovered-time
Sep 27, 2023
Merged

Show the hovered time in the ruler at the top of the timeline.#4748
julienw merged 2 commits into
firefox-devtools:mainfrom
fqueze:show-hovered-time

Conversation

@fqueze

@fqueze fqueze commented Sep 14, 2023

Copy link
Copy Markdown
Contributor
Capture d’écran 2023-09-14 à 18 28 50

@codecov

codecov Bot commented Sep 14, 2023

Copy link
Copy Markdown

Codecov Report

Attention: 9 lines in your changes are missing coverage. Please review.

Comparison is base (3e8d88f) 88.33% compared to head (128bd24) 88.32%.
Report is 8 commits behind head on main.

❗ Current head 128bd24 differs from pull request most recent head 6205fb5. Consider uploading reports for the commit 6205fb5 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4748      +/-   ##
==========================================
- Coverage   88.33%   88.32%   -0.02%     
==========================================
  Files         300      300              
  Lines       26768    26794      +26     
  Branches     7220     7237      +17     
==========================================
+ Hits        23646    23666      +20     
- Misses       2910     2916       +6     
  Partials      212      212              
Files Coverage Δ
src/components/timeline/Selection.js 79.54% <100.00%> (+0.47%) ⬆️
src/profile-logic/committed-ranges.js 84.84% <100.00%> (+0.23%) ⬆️
src/utils/format-numbers.js 85.02% <79.54%> (-1.87%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@julienw julienw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks pretty good to me, however I think that getFormattedTimeLength doesn't do the right thing in this case. Please have a look at my suggestion instead :-)

Comment thread src/components/timeline/Selection.js Outdated
event.pageY < rect.top ||
event.pageY >= rect.bottom
event.pageY >= rect.bottom ||
width === 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you please explain why this change in a comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do you want a comment in the code or is a comment here good enough?

The reason was that when moving the mouse around over the profiler page while the profiler was still loading, this code was triggered, with width == 0, causing the mouseTimePosition to become Infinity, and my new code to explode attempting to number format NaN.

I think a cleaner fix would be finding a way to register the mousemove handler later when the profile has finished loading, but returning early when width === 0 seemed good enough to avoid the crash.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be better to do an early return for width==0? It would be good to have a proper comment in the code too indeed :-)

Comment thread src/components/timeline/Selection.js Outdated
>
<span className="timelineSelectionOverlayTime">
{mouseTimePosition !== null
? getFormattedTimeLength(mouseTimePosition - zeroAt)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe it should use a similar logic for the precision than the ruler, because otherwise it's not useful when zoomed in a lot (except at the start of the profile).
The logic is in timeline/Ruler.js, but here is what is I believe a good enough approximation:

const range = committedRange.end - committedRange.start;
const exponent = Math.floor(Math.log10(range));
const digits = Math.max(0, -(exponent - 4))
const timeString = (mouseTimePosition - zeroAt).toFixed(digits);

I haven't tried it though, tell me how that looks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually care more about showing something useful for long profiles (ie. not hundreads or thousands of seconds, but something in minutes and seconds) than about the high precision when zoomed into extremely short intervals.
Of course having both would be best, but that might require a lot more, like an alternative version of formatNumber(or adding an extra parameter to it) to specify the required smallest unit to display.

The numbers displayed in the ruler are currently difficult to read for long profiles. That's something I would like to improve someday. Maybe I could fix the numbers displayed in the ruler and polish the number in this new overlay at the same time?

A short term alternative if you really care about short intervals could be to switch to the implementation you suggested when the commited range lasts less than a few seconds. Not sure if that would be better or more confusing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe you could do:

const range = committedRange.end - committedRange.start;
const exponent = Math.floor(Math.log10(range));
const digits = Math.max(0, -(exponent - 4))
const timeString =
  digits > 0
  ? ((mouseTimePosition - zeroAt)/1000).toFixed(digits) + "s"
  : getFormattedTimeLength(mouseTimePosition - zeroAt);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I thought about it some more, and I think the correct behavior is to ensure that whenever we move the mouse by 1px, the displayed time changes. So we need to adjust the precision of the displayed timestamp based on how much time is represented by 1px. I updated the PR to do that.

Here's a long (> 1 day) profile that I used for testing: https://share.firefox.dev/46mER8G

@fqueze fqueze requested a review from julienw September 21, 2023 18:00
Comment thread src/components/timeline/Selection.js Outdated
event.pageY < rect.top ||
event.pageY >= rect.bottom
event.pageY >= rect.bottom ||
width === 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be better to do an early return for width==0? It would be good to have a proper comment in the code too indeed :-)

precision: Milliseconds = Infinity
) {
if (precision !== Infinity) {
precision = 10 ** Math.floor(Math.log10(precision));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I just wonder if this part should be done in the caller, so that the precision arguments have the same meaning in all the functions here. What do you think?

Although I'm not 100% sure about this line does. Would we have too much precision without this line?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think doing it in the caller would be more effort once there are multiple callers (I'm hoping the TimelineRuler code will eventually use this code path too). The precision argument still works in the same way in all the functions, thanks to the Math.floor(Math.log10( call in formatSeconds.

I added a comment in the code to explain what behavior these lines implement. Not the most useful part of the patch, unless it was needed to fix an edge case I don't remember.

@fqueze fqueze requested a review from julienw September 27, 2023 11:13
@julienw julienw enabled auto-merge (squash) September 27, 2023 12:21
@julienw julienw merged commit aa8089f into firefox-devtools:main Sep 27, 2023
tenderlove added a commit to tenderlove/profiler that referenced this pull request Jan 16, 2024
* main: (37 commits)
  Show the hovered time in the ruler at the top of the timeline. (PR firefox-devtools#4748)
  Hardcode 'project' to 'firefox-profiler' in .taskcluster.yml (PR firefox-devtools#4759)
  Update all Yarn dependencies (2023-09-27) (PR firefox-devtools#4758)
  Update the uploading command in the developer documentation (PR firefox-devtools#4752)
  Make prettier ignore the taskcluster files
  Add taskcluster
  Update all Yarn dependencies (2023-09-20) (PR firefox-devtools#4756)
  Add a robots.txt file to disallow indexing our profile links (PR firefox-devtools#4753)
  Avoid showing the calltree panel in profiles without samples. (PR firefox-devtools#4744)
  Display the vertical line in the timeline when hovering the marker chart or stack chart (PR firefox-devtools#4742)
  Draw a single rectangle for 2 markers in bar charts only if both the start and end horizontal pixels match. (PR firefox-devtools#4734)
  Update all Yarn dependencies (2023-09-13) (firefox-devtools#4746)
  Update all Yarn dependencies (2023-09-06) (PR firefox-devtools#4741)
  Remove prefer-wait-for rule in our config because it's been removed from the plugin
  ⬆️ Update eslint-plugin-testing-library to version 6.0.1
  Use a cache for prettier (PR firefox-devtools#4731)
  Remove leftover eslint error
  Run prettier on the codebase
  Upgrade prettier to latest version
  Ignore the coverage directory when present
  ...
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.

2 participants