Skip to content

[FEAT] Add highlight_diagonal builtin - #1422

Open
priyam0k wants to merge 5 commits into
mainfrom
feature/issue-1334-highlight-diagonal
Open

priyam0k wants to merge 5 commits into
mainfrom
feature/issue-1334-highlight-diagonal

Conversation

@priyam0k

@priyam0k priyam0k commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Summary of Changes

  • Adds highlight_diagonal to the Triangle styler to highlight the latest diagonal by default or any specific valuation date.
  • Introduces apply_from_triangle to generalize mask-based styling across builtins.
  • Includes unit tests and an example in the styling tutorial.

Related GitHub Issue(s)

Closes #1334

AI/LLM Usage

Used AI assistance for drafting unit tests and ruff checks.

Additional Context for Reviewers

Follows the pattern from highlight_lower_triangle and supports chaining both methods. Both builtins now route through apply_from_triangle

Submitter's Checklist

  • I have reviewed and am adhering to the standards outlined in the project Governing Doc.
  • The PR subject title summarizes the changes, with one proper prefix ([FIX], [FEAT], [DOCS], [TST], [CHORE], or [BRK]).
  • I am a human (not a bot), and this PR form is written by a human.

Reviewer's Checklist

  • The implementation addresses the associated issue(s).
  • The implementation is appropriate, maintainable, and follows ARCHITECTURE.md.
  • PR subject title has the proper prefix and the subject is appropriate.
  • Relevant issue(s) are linked.
  • AI/LLM usage is disclosed and appropriate.
  • Documentation and tests are appropriate.
  • CI tests passed, or any failures are acceptable.
  • Leave a comment with the final recommendation (e.g. approve as is, request a secondary review, or flag an area for more review).

Note

Low Risk
Presentation-layer API additions and a refactor of existing highlight logic; no auth, persistence, or numerical core changes.

Overview
Adds triangle-aware styling on Styler: new apply_from_triangle styles cells where a same-shaped mask Triangle is non-missing/truthy (with validation for valuation/multi-D triangles and sparse backends), and new highlight_diagonal highlights the latest or a chosen valuation diagonal (valuation / valuation_date alias, color/text_color/props).

Refactors highlight_lower_triangle to build a mask triangle and route through apply_from_triangle instead of inlining Styler.apply. Tests cover defaults, date formats, full triangles, chaining with lower-triangle highlight, and errors; docs add a “Highlighting diagonals” section in the style user guide.

Reviewed by Cursor Bugbot for commit 3509d9b. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions

github-actions Bot commented Sep 22, 2026

Copy link
Copy Markdown

Pyright Type Completeness

View the full pyright --verifytypes output for this commit

Project (full chainladder package, at this PR's head): 15.5% of exported symbols fully typed (224 / 1445)

Known Ambiguous Unknown Total
Project (head) 224 111 1110 1445

Other symbols referenced but not exported by chainladder: 13

Known Ambiguous Unknown Total
Other (head) 3 1 9 13

Symbols without documentation:

  • Functions without docstring: 328
  • Functions without default param: 0
  • Classes without docstring: 10

Patch (exported symbols added or changed by this PR): 20.0% fully typed (3 / 15)

Known Ambiguous Unknown Total
Patch 3 0 12 15
Patch symbol details
Symbol Status Change
chainladder.core.style.Styler.apply_from_triangle ✅ known new
chainladder.core.style.Styler.highlight_diagonal ✅ known new
chainladder.core.tests.test_style.test_apply_from_triangle_sparse_mask ❌ unknown new
chainladder.core.tests.test_style.test_apply_from_triangle_styles_selected_cells ❌ unknown new
chainladder.core.tests.test_style.test_apply_from_triangle_validation ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_chaining_with_lower_triangle ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_explicit_dates ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_finer_development_grain ✅ known new
chainladder.core.tests.test_style.test_highlight_diagonal_invalid_valuation_raises ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_predicted_cells_full_triangle ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_props_overrides_color ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_rejects_valuation_triangle ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_styles_latest_diagonal_by_default ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_text_color ❌ unknown new
chainladder.core.tests.test_style.test_highlight_diagonal_valuation_date_alias ❌ unknown new

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread chainladder/core/style.py
@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.40%. Comparing base (f8fc115) to head (3509d9b).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
chainladder/core/style.py 92.72% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1422      +/-   ##
==========================================
+ Coverage   92.36%   92.40%   +0.04%     
==========================================
  Files         102      102              
  Lines        5864     5940      +76     
  Branches      723      744      +21     
==========================================
+ Hits         5416     5489      +73     
- Misses        326      328       +2     
- Partials      122      123       +1     
Flag Coverage Δ
unittests 92.40% <92.85%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@henrydingliu

henrydingliu commented Sep 22, 2026

Copy link
Copy Markdown
Member

@priyam0k thanks for putting this together!

  • a lot of the valuation reshaping seems to be recreating the wheel. would ~np.isnan(tri[tri.valuation == valuation_date].values) help you simplify? essentially routing the reshaping through the existing API around valuation slicing
  • a lot of the checks at the top of the method looks to be similar to what's in highlight_lower_triangle. can you generalize into an apply_from_triangle method that's basically those same checks and relies on a supplied mask triangle? then highlight_diagonal can just route through apply_from_triangle

@priyam0k

Copy link
Copy Markdown
Contributor Author

Thanks @henrydingliu!

Added apply_from_triangle and routed both highlight methods through it.

For the slicing shortcut, slicing a past diagonal drops newer origin years that are all NaN (for example, 10x10 becomes 8x8), causing a shape mismatch with the styler. Keeping the 2D mask preserves the full table shape across all historical diagonals.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bb4dba2. Configure here.

Comment thread chainladder/core/style.py
assert len(styled) == 8


def test_highlight_diagonal_valuation_date_alias(raa) -> None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is this test redundant given this line?

Comment thread chainladder/core/style.py
if not isinstance(mask, Triangle):
raise TypeError("mask must be a Triangle instance.")

if self._triangle.is_val_tri or mask.is_val_tri:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this should be checked at the individual styler level only. many masks will work fine (like origin) on a val tri

@@ -1,8 +1,9 @@
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can you add an example for apple_from_triangle?

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.

[ENH] Add Styler builtin for diagonals

2 participants