Skip to content

upcoming: [DI-29393] : Utils and Hooks set up for supporting zoom in inside the charts in CloudPulse graphs#13308

Merged
venkymano-akamai merged 6 commits intolinode:developfrom
venkymano-akamai:widget_zoom_util_setup
Jan 23, 2026
Merged

upcoming: [DI-29393] : Utils and Hooks set up for supporting zoom in inside the charts in CloudPulse graphs#13308
venkymano-akamai merged 6 commits intolinode:developfrom
venkymano-akamai:widget_zoom_util_setup

Conversation

@venkymano-akamai
Copy link
Contributor

@venkymano-akamai venkymano-akamai commented Jan 22, 2026

Description 📝

As a ask from customer, we are working towards adding the support for zooming in inside the CloudPulse graphs using click and drag on the timestamps inside the graphs, this PR has the initial changes for the zoom in such as the utilities required to support the click and drag and update data based on it,

Changes 🔄

  1. Add a CloudPulseWidgetZoomInUtils, which has three functions and they do the following,
    computeZoomedInData - Using the original data, and left and right timestamp of the click and drag event, returns the updated / truncated data
    computeLegendRowsBasedOnData - Using the truncated data and left and right timestamp, re-calculates the avergage, max and last displayed in the legend rows
    getMetricsFromDimensionData - Calculated the Average, Max and Last for the given data
  2. A new hook useZoomController, that does the following
    - Returns the zoom state, the min timestamp and the max timestamp
    - Returns the OnMouseDown, OnMouseUp and OnMouseMove callbacks to listen to click and drag event
    - Returns whether the data is actually zoomed in or not
    - Retuns zoomOut callback, to reset the zoom state
  3. Add relevant UT's for those files.

Scope 🚢

Upon production release, changes in this PR will be visible to:

  • All customers
  • Some customers (e.g. in Beta or Limited Availability)
  • No customers / Not applicable

No customers are impacted, since this is just utilities

Target release date 🗓️ Next Release

Preview 📷

No visible UI changes as this is just adding of utilities / helpers needed for zoom in

How to test 🧪

No visible UI changes as this is just adding of utilities / helpers needed for zoom in

Author Checklists

As an Author, to speed up the review process, I considered 🤔

👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support


  • I have read and considered all applicable items listed above.

As an Author, before moving this PR from Draft to Open, I confirmed ✅

  • All tests and CI checks are passing
  • TypeScript compilation succeeded without errors
  • Code passes all linting rules

@venkymano-akamai
Copy link
Contributor Author

Team, Around 355 lines are UT's

@venkymano-akamai
Copy link
Contributor Author

@pmakode-akamai , can we have a look at this?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces infrastructure for zoom-in functionality in CloudPulse metrics graphs through new utilities and a custom React hook. The changes enable users to click and drag on chart timestamps to zoom into specific time ranges, with support for dynamic data filtering and legend recalculation.

Changes:

  • Added useZoomController hook to manage drag-to-zoom state and mouse event handlers
  • Created CloudPulseZoomInUtils with functions for filtering data, recalculating legend metrics, and computing aggregated values based on zoom state
  • Comprehensive unit tests for both the hook and utility functions

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/manager/src/features/CloudPulse/Widget/components/useZoomController.ts Implements zoom state management and mouse event handlers for drag-to-zoom
packages/manager/src/features/CloudPulse/Widget/components/useZoomController.test.ts Unit tests covering zoom controller behavior including drag handling and state reset
packages/manager/src/features/CloudPulse/Utils/CloudPulseZoomInUtils.ts Utility functions for filtering data by zoom range and recalculating metrics
packages/manager/src/features/CloudPulse/Utils/CloudPulseZoomInUtils.test.ts Unit tests for zoom utilities covering edge cases and metric calculations
packages/manager/.changeset/pr-13308-upcoming-features-1769081320065.md Changeset documenting the new zoom functionality

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

const data = [10, 20, NaN];
const result = getMetricsFromDimensionData(data);

expect(result.last).toBe(0);
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The test expects last to be 0 when the last value is NaN, but according to the implementation in getMetricsFromDimensionData (line 138 of CloudPulseZoomInUtils.ts), last is assigned data[length - 1] || 0. Since NaN || 0 evaluates to 0, the test is correct. However, this behavior is inconsistent with how NaN values are handled in sum and max calculations (where they are skipped). Consider updating getMetricsFromDimensionData to filter out NaN values when determining the last value, or document this edge case behavior explicitly.

Copilot uses AI. Check for mistakes.
it('should ignore NaN values', () => {
const data = [10, NaN, 30, NaN, 50];
const result = getMetricsFromDimensionData(data);
expect(result.total).toBe(90);
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The test checks total and max but does not verify average and length when NaN values are present. The current implementation includes NaN values in the length calculation (line 133), which would make the average calculation include them in the denominator despite excluding them from the sum. Add assertions for average and length to ensure the behavior matches expectations.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@pmakode-akamai pmakode-akamai left a comment

Choose a reason for hiding this comment

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

I can see the tests are passing but I noticed some edge cases and potential issues, and left comments for them that you might want to take a look at. We could consider adding additional test coverage for those scenarios if possible

return legendRows;
}

const minZoom = zoom.left === 'dataMin' ? data[0].timestamp : zoom.left; // left zoom boundary
Copy link
Contributor

Choose a reason for hiding this comment

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

This could throw error if data is undefined or [] array. We may want to add a similar early return as in the utility above (returning whatever is appropriate in this context)

if (!data || data.length === 0) {
  return legendRows;
}


const onMouseDown = React.useCallback((e: CategoricalChartState) => {
const payload = e?.activePayload?.[0]?.payload;
if (!payload?.timestamp) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (!payload?.timestamp) return;
if (payload?.timestamp === undefined) return;

If timestamp can be 0, this check would incorrectly exit early. The same applies to other similar checks in this hook

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pmakode-akamai , timestamps can never be 0, as there will no time with 0 value, but it is better to have a defensive check as well, so addressed these too.

if (dragStart === null) return;

const payload = e?.activePayload?.[0]?.payload;
if (!payload?.timestamp) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

same potential issue

Comment on lines 86 to 87
!prev.refAreaLeft ||
!prev.refAreaRight ||
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
!prev.refAreaLeft ||
!prev.refAreaRight ||
prev.refAreaLeft === undefined ||
prev.refAreaRight === undefined ||

Same potential issue: 0 can be a valid value, so this check could fail. Could you double check this?

@venkymano-akamai
Copy link
Contributor Author

@pmakode-akamai , addressed the comments, lets see if it is good for approval

@github-project-automation github-project-automation bot moved this from Review to Approved in Cloud Manager Jan 23, 2026
@linode-gh-bot
Copy link
Collaborator

Cloud Manager UI test results

🔺 1 failing test on test run #5 ↗︎

❌ Failing✅ Passing↪️ Skipped🕐 Duration
1 Failing864 Passing11 Skipped37m 1s

Details

Failing Tests
SpecTest
clone-linode.spec.tsCloud Manager Cypress Tests→clone linode » can clone a Linode from Linode details page

Troubleshooting

Use this command to re-run the failing tests:

pnpm cy:run -s "cypress/e2e/core/linodes/clone-linode.spec.ts"

@venkymano-akamai venkymano-akamai added the Approved Multiple approvals and ready to merge! label Jan 23, 2026
@venkymano-akamai
Copy link
Contributor Author

Merging it since it has enough approvals, cypress test failures are unrelated, jobs passed

@venkymano-akamai venkymano-akamai merged commit 0c3607b into linode:develop Jan 23, 2026
34 of 35 checks passed
@github-project-automation github-project-automation bot moved this from Approved to Merged in Cloud Manager Jan 23, 2026
dchyrva-akamai pushed a commit to dchyrva-akamai/manager that referenced this pull request Jan 26, 2026
…inside the charts in CloudPulse graphs (linode#13308)

* [DI-29167] - Initial changes for widget zoom in feature, Utility setup

* [DI-29167] - Add understanding comments

* Added changeset: Utils and Hooks set up for supporting zoom in inside the charts in `CloudPulse metrics graphs`

* [DI-29167] - Address PR comments
dchyrva-akamai pushed a commit to dchyrva-akamai/manager that referenced this pull request Jan 27, 2026
…inside the charts in CloudPulse graphs (linode#13308)

* [DI-29167] - Initial changes for widget zoom in feature, Utility setup

* [DI-29167] - Add understanding comments

* Added changeset: Utils and Hooks set up for supporting zoom in inside the charts in `CloudPulse metrics graphs`

* [DI-29167] - Address PR comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved Multiple approvals and ready to merge! Cloud Pulse - Dashboards Cloud Pulse

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants