Skip to content

Combine segment summary and cell heat map#532

Open
bracyw wants to merge 24 commits intodevelopfrom
527-combine-segment-summary-and-cell-heat-map
Open

Combine segment summary and cell heat map#532
bracyw wants to merge 24 commits intodevelopfrom
527-combine-segment-summary-and-cell-heat-map

Conversation

@bracyw
Copy link
Collaborator

@bracyw bracyw commented Feb 22, 2026

Changes

Combines the segment summary stats and cell heatmap into unified segment rows on the BMS debug page. Each row has a dark controls zone (segment label, view selector, "See more" link) and a light content zone with the hex-tile heatmap and overview stats side by side.

Key architectural decisions:

  • Extracted reusable components: SegmentRowComponent, SegmentHeatmapComponent, SegmentOverviewComponent, and HexTileComponent — each segment row is self-contained with its own view selector
  • Refactored CellReading to a single-cell model (from paired cells) so each hex tile maps 1:1 to a cell reading. This simplifies the data flow and makes the heatmap config-driven via BMS_CONFIG
  • Extracted BMS_CONFIG to bms.config.ts to break a circular import between bms.utils.ts and topic.utils.ts
  • Temperature view uses merged double-hex tiles — thermistors map to groups of cells via ALPHA_THERM_CELL_MAP / BETA_THERM_CELL_MAP. The double-hex shape uses a V-notch clip-path polygon to visually distinguish temperature tiles from single-cell voltage/balancing tiles
  • Multi-cell comparison dialog — clicking any hex tile selects it (with a glow highlight), opening a shared comparison dialog. Multiple cells can be selected across segments. Clicking a temperature double-hex expands to show each cell in the therm group as separate columns
  • View selectors sync via HeatMapService — a globalView$ BehaviorSubject drives the "Set ALL Maps" selector and the initial default for per-row selectors. Per-row selectors subscribe to their segment's view and stay in sync when the global selector changes. The SelectDropdownComponent now uses an effect() to reactively track defaultValue changes
  • Dynamic sizing with clamp() for hex tiles and row heights to support 70–150% browser zoom

Notes

  • The two #525 commits at the base are from the 525-generalize-bms-cell-data-model branch which this depends on
  • Cell comparison dialog uses setInterval polling to refresh MQTT values — this could be replaced with proper observable subscriptions in a follow-up

Test Cases

  • Switching view selector on a single row changes only that row's heatmap
  • "Set ALL Maps" changes all row selectors and heatmaps simultaneously
  • Per-row selectors visually sync when "Set ALL Maps" is used
  • Clicking a voltage/balancing tile selects it with glow, opens comparison dialog
  • Clicking a second tile adds it as another column in the dialog
  • Clicking a selected tile deselects it; deselecting all closes the dialog
  • Clicking a temperature double-hex tile expands to show all cells in the therm group
  • Browser zoom from 70% to 150% renders hex tiles and rows without overflow or clipping

Checklist

It can be helpful to check the Checks and Files changed tabs.
Please review the contributor guide and reach out to your Tech Lead if anything is unclear.
Please request reviewers and ping on slack only after you've gone through this whole checklist.

  • All commits are tagged with the ticket number
  • No linting errors / newline at end of file warnings
  • All code follows repository-configured prettier formatting
  • No merge conflicts
  • All checks passing
  • Remove any non-applicable sections of this template
  • Assign the PR to yourself
  • No package-lock.json changes (unless dependencies have changed)
  • Request reviewers & ping on Slack
  • PR is linked to the ticket (fill in the closes line below)

Closes #527

@bracyw bracyw self-assigned this Feb 22, 2026
@bracyw bracyw changed the title Combine segment summary and cell heat map #527 Combine segment summary and cell heat map Feb 22, 2026
Copy link
Collaborator Author

@bracyw bracyw left a comment

Choose a reason for hiding this comment

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

Some changes I would like to make before merging

constructor() {
// React to defaultValue changes (e.g. from "Set ALL Maps" selector)
effect(() => {
const val = this.defaultValue();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is unneeded we should just put the correct default value in the first time. I believe initial problem was with synchronizing set all and single selectors.

style="width: 100%; height: 100%"
[title]="this.getHeatmapTitle()"
svgIcon="battery_charging_2"
[slicedLeftCorner]="true"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add option for percentage that the corner is sliced.

]
})
export class BmsSegmentViewComponent implements OnInit {
export class BmsSegmentViewComponent implements OnInit, OnDestroy {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add comment

></cell-tile>
}

@for (cell of betaCells.slice().reverse(); track cell) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add comment saying that reverse is to better match the actual battery setup.

}

.segment-page-heatmap {
--hex-w: clamp(60px, 5.5vw, 85px);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add comments with explanation for css

private subscriptions: Subscription[] = [];

segment = input.required<Segment>();
temperature!: number;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

abstract to be able to take in multiple values, that have format functions tied to them

@@ -0,0 +1,29 @@
<!-- Unified segment row: dark wrapper with light heatmap and overview panels -->
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Going to make ticket to abstract to be a general wrapper that can have two related parts, then use that abstracted component here. Not supper necessary but will be nice to have and a lot easier to maintain.

display: block;
}

/* ── Segment Row ── */
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

add ai-gen ack, and more comments

overflow: visible !important; /* Allow dropdown to overflow */
}

/* ── Section header row ── */
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AI gen ack and more comments

</mat-grid-list>

<!-- Section header with "Set ALL Maps" dropdown -->
<div class="section-header">
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

abstract section header to it's own re-usable component, with left and right title inputs and select drop down options (allow for multiple select dropdowns, via a list of selector configs.)

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.

Combine segment summary and cell heat map into unified segment rows

1 participant