Skip to content

Add unified chart option for temperature#240

Merged
miharekar merged 2 commits intomainfrom
grouped-temperature-chart
Mar 11, 2026
Merged

Add unified chart option for temperature#240
miharekar merged 2 commits intomainfrom
grouped-temperature-chart

Conversation

@miharekar
Copy link
Owner

@miharekar miharekar commented Mar 11, 2026

Resolves #238

Let users overlay temperature series on the main shot chart while keeping the split chart layout as the default.

Summary by CodeRabbit

  • New Features

    • Added a "Unified Chart" toggle in user profile settings that allows temperature data to be displayed directly on the main chart instead of as a separate chart.
  • Tests

    • Added test coverage for the unified chart feature to ensure temperature data displays correctly based on user preference.

Let users overlay temperature series on the main shot chart while keeping the split chart layout as the default.
@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

📝 Walkthrough

Walkthrough

Implements a feature enabling users to optionally display temperature data on the main shot chart alongside other variables rather than in a separate chart, controlled by a new unified_chart boolean user preference.

Changes

Cohort / File(s) Summary
Database Schema
db/migrate/20260311180000_add_unified_chart_to_users.rb, db/schema.rb
Adds unified_chart boolean column (default false, not null) to users table with schema version bump.
User Model
app/models/user.rb
Adds unified_chart boolean attribute to User model with default false.
Chart Logic
app/models/shot_chart.rb
Introduces shot_chart_data and temperature_chart_data helpers that conditionally include/exclude temperature data based on user.unified_chart?; adds secondary Y-axis for temperature when unified mode is enabled.
Controller & Parameters
app/controllers/profiles_controller.rb
Allows unified_chart parameter in profile_params for admin/premium conditionals.
Profile Form
app/views/profiles/_form.html.erb
Adds new Unified Chart checkbox option with label and helper text; adjusts spacing with md:py-6 padding and space-y-1 utilities.
Shot Views
app/views/shots/show.html.erb, app/views/shots/compare.html.erb
Wraps temperature chart blocks in conditionals to render only when temperature data is present, avoiding empty containers.
Test Factory
test/factories/users.rb
Adds default unified_chart { false } to user factory.
Test Coverage
test/models/shot_chart_test.rb, test/models/user_test.rb
Introduces unit tests validating default separation of temperature series, unified chart rendering, and user preference storage.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Controller
    participant ShotChart
    participant View
    
    rect rgba(100, 200, 100, 0.5)
    Note over User,View: Unified Chart Enabled (user.unified_chart = true)
    User->>Controller: Load shot with unified_chart: true
    Controller->>ShotChart: Render with user.unified_chart?
    ShotChart->>ShotChart: shot_chart_data returns all data<br/>(includes temperature)
    ShotChart->>ShotChart: temperature_chart_data returns empty
    ShotChart->>View: Assign secondary Y-axis for temperature series
    View->>View: Render main chart with temperature<br/>(secondary_axis)
    View->>View: Skip temperature chart (empty)
    end
    
    rect rgba(200, 100, 100, 0.5)
    Note over User,View: Unified Chart Disabled (user.unified_chart = false)
    User->>Controller: Load shot with unified_chart: false
    Controller->>ShotChart: Render with user.unified_chart?
    ShotChart->>ShotChart: shot_chart_data excludes temperature keys
    ShotChart->>ShotChart: temperature_chart_data returns temperature only
    View->>View: Render main chart (no temperature)
    View->>View: Render separate temperature chart
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A chart now unified, oh what a sight!
No more split screens, just temperatures right—
Toggled by preference, a user's delight,
Data flows smoothly from left chart to light,
One dashboard to rule them all, burning bright! 🔥📊

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding a unified chart option that allows temperature data to be displayed on the main chart rather than separately.
Linked Issues check ✅ Passed The pull request fulfills the requirement from issue #238 to display temperature lines on the main graph alongside other variables, implementing this as a configurable option (unified_chart) that users can enable.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the unified chart feature: adding the unified_chart user attribute, updating shot chart logic, adding UI controls, and including comprehensive tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch grouped-temperature-chart

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Duplicate per-series chart settings before applying unified chart overrides so temperature axis changes do not leak across requests.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/models/shot_chart.rb (1)

54-54: Avoid mutating the ChartSettings entry in place.

Line 54 writes back into setting just to derive yAxis. If ChartSettings#for_label returns a shared or frozen hash, unified-chart requests can leak secondary_axis into later series or raise on mutation. A local flag is safer here.

♻️ Proposed change
-      setting["secondary_axis"] = true if user&.unified_chart? && label.include?("temperature")
+      secondary_axis = setting["secondary_axis"] || (user&.unified_chart? && label.include?("temperature"))
       if setting["comparison"]
         dash_style = setting["dashed"] ? "DashDot" : "ShortDot"
       else
         dash_style = setting["dashed"] ? "Dash" : "Solid"
       end
@@
-        yAxis: setting["secondary_axis"] ? 1 : 0
+        yAxis: secondary_axis ? 1 : 0
       }
#!/bin/bash
set -euo pipefail

for file in $(fd 'chart_settings\.rb$' app lib); do
  echo "=== $file ==="
  sed -n '1,220p' "$file"
  rg -n -C2 'def for_label|freeze|dup|deep_dup|secondary_axis' "$file"
done

Expected result: ChartSettings#for_label should return a dup, or callers should avoid mutating the returned hash.

Also applies to: 74-74

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/models/shot_chart.rb` at line 54, The code mutates the hash returned by
ChartSettings.for_label by setting setting["secondary_axis"] = true, which can
leak state or raise if the hash is shared/frozen; instead compute a local flag
(e.g., secondary_axis = user&.unified_chart? && label.include?("temperature"))
and use that when deriving yAxis (or downstream consumers) without writing back
into the returned setting; update occurrences around the setting variable and
references at the same pattern (including the other instance at line 74) so
callers don’t mutate ChartSettings.for_label results.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/models/user_test.rb`:
- Around line 53-58: The test "unified_chart follows the user preference"
currently uses build(:user) which does not persist the unified_chart flag;
change the test to persist the user(s) (e.g., use create(:user) and
create(:user, unified_chart: true) or call user.save and user.reload) so the
assertions exercise the stored DB value for unified_chart?; update references to
build(:user) in that test to create(:user) (or save+reload) and assert against
the persisted record.

---

Nitpick comments:
In `@app/models/shot_chart.rb`:
- Line 54: The code mutates the hash returned by ChartSettings.for_label by
setting setting["secondary_axis"] = true, which can leak state or raise if the
hash is shared/frozen; instead compute a local flag (e.g., secondary_axis =
user&.unified_chart? && label.include?("temperature")) and use that when
deriving yAxis (or downstream consumers) without writing back into the returned
setting; update occurrences around the setting variable and references at the
same pattern (including the other instance at line 74) so callers don’t mutate
ChartSettings.for_label results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 19d827d9-6c32-49f7-8452-89c5eb763279

📥 Commits

Reviewing files that changed from the base of the PR and between 693c916 and a24de6f.

📒 Files selected for processing (11)
  • app/controllers/profiles_controller.rb
  • app/models/shot_chart.rb
  • app/models/user.rb
  • app/views/profiles/_form.html.erb
  • app/views/shots/compare.html.erb
  • app/views/shots/show.html.erb
  • db/migrate/20260311180000_add_unified_chart_to_users.rb
  • db/schema.rb
  • test/factories/users.rb
  • test/models/shot_chart_test.rb
  • test/models/user_test.rb

Comment on lines +53 to +58
test "unified_chart follows the user preference" do
user = build(:user)
assert_not user.unified_chart?

user = build(:user, unified_chart: true)
assert user.unified_chart?
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Persist this flag in the test instead of only building it.

The assert_not user.unified_chart? branch is currently proving the factory default from test/factories/users.rb, not the stored preference this PR adds. A broken DB default or update path would still pass here.

🧪 Suggested change
   test "unified_chart follows the user preference" do
-    user = build(:user)
-    assert_not user.unified_chart?
-
-    user = build(:user, unified_chart: true)
-    assert user.unified_chart?
+    user = User.create!(attributes_for(:user).except(:unified_chart))
+    assert_not user.reload.unified_chart?
+
+    user.update!(unified_chart: true)
+    assert user.reload.unified_chart?
   end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/models/user_test.rb` around lines 53 - 58, The test "unified_chart
follows the user preference" currently uses build(:user) which does not persist
the unified_chart flag; change the test to persist the user(s) (e.g., use
create(:user) and create(:user, unified_chart: true) or call user.save and
user.reload) so the assertions exercise the stored DB value for unified_chart?;
update references to build(:user) in that test to create(:user) (or save+reload)
and assert against the persisted record.

@miharekar miharekar merged commit c742961 into main Mar 11, 2026
7 checks passed
@miharekar miharekar deleted the grouped-temperature-chart branch March 11, 2026 18:04
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.

Temperature graph together with others

1 participant