-
Notifications
You must be signed in to change notification settings - Fork 1
Combine segment summary and cell heat map #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 24 commits
5b9705c
c68574c
e959516
2ea9599
34fd2a3
afc49d9
c508468
b904a10
bb09fff
4239d1c
b75ff62
65bcd5c
33a444e
7d26125
4a2343c
77d3b86
15c0048
ea29fd7
0938719
bf9857c
91f3497
adb7861
7059adc
43f5671
3fc68c6
a7db85b
a84a6c7
b1cac8b
5687a7e
a7fee3b
70e647a
af8a9b9
616e5d0
d402a98
c23e8a2
c390c97
8799201
3d4bcc2
bfbead7
3f602e5
43761da
c739cba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,28 @@ | |
| mat-grid-tile { | ||
| overflow: visible !important; /* Allow dropdown to overflow */ | ||
| } | ||
|
|
||
| /* ── Section header row ── */ | ||
|
||
| .section-header { | ||
| display: flex; | ||
| align-items: center; | ||
| padding: clamp(8px, 1.25vw, 24px) 0 clamp(4px, 0.63vw, 12px); | ||
| gap: clamp(6px, 0.94vw, 18px); | ||
| } | ||
|
|
||
| .section-title { | ||
| font-family: 'Roboto', sans-serif; | ||
| font-weight: 700; | ||
| font-size: clamp(18px, 2.66vw, 44px); | ||
| color: #efefef; | ||
| } | ||
|
|
||
| .section-title-right { | ||
| margin-left: auto; | ||
| } | ||
|
|
||
| .segment-rows { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: clamp(2px, 0.35vw, 8px); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,31 +2,31 @@ | |
| @if (isMobile) { | ||
| <!-- TODO: Add mobile display component --> | ||
| } @else { | ||
| <!-- TODO: Add components for the segment summary--> | ||
| <mat-grid-list cols="6" gutterSize="15px" rowHeight="1.5rem" style="margin-top: -20px"> | ||
| <mat-grid-tile [colspan]="6" rowspan="3"> | ||
| <bms-header style="width: 100%" [pageTitle]="this.windowSize < 1200 ? 'ACCU' : 'Accumulator'" /> | ||
| </mat-grid-tile> | ||
| <mat-grid-tile [colspan]="6" rowspan="5"> | ||
| <bms-at-a-glance style="height: 100%; width: 100%" /> | ||
| </mat-grid-tile> | ||
| <mat-grid-tile [colspan]="windowSize > 1300 ? 1 : 2" [rowspan]="16"> | ||
| <div style="display: flex; flex-direction: column; width: 100%; height: 100%; gap: 3%"> | ||
| <acc-high-voltage style="width: 100%; min-height: 31%" /> | ||
| <acc-low-voltage style="width: 100%; min-height: 31%" /> | ||
| <acc-high-temp style="width: 100%; min-height: 32%" /> | ||
| </div> | ||
| </mat-grid-tile> | ||
| @for (segment of segments; track segment) { | ||
| <mat-grid-tile [colspan]="windowSize > 1300 ? 1 : 2" rowspan="16"> | ||
| <segment-summary [segmentNumber]="segment" style="height: 100%; width: 100%" /> | ||
| </mat-grid-tile> | ||
| } | ||
| </mat-grid-list> | ||
|
|
||
| <!-- Section header with "Set ALL Maps" dropdown --> | ||
| <div class="section-header"> | ||
|
||
| <span class="section-title">Cell-by-Cell Heat Map</span> | ||
| <select-dropdown | ||
| [options]="allSegSelectorConfig.options" | ||
| [placeholder]="allSegSelectorConfig.placeholder" | ||
| [defaultValue]="allSegSelectorConfig.defaultValue" | ||
| /> | ||
| <span class="section-title section-title-right">Segment Overview</span> | ||
| </div> | ||
|
|
||
| <!-- Unified segment rows --> | ||
| <div class="segment-rows"> | ||
| @for (segment of segments; track segment) { | ||
| <mat-grid-tile colspan="6" rowspan="8"> | ||
| <cell-by-cell-heat-map style="width: 100%; height: 100%" [currentSegment]="segment"></cell-by-cell-heat-map> | ||
| </mat-grid-tile> | ||
| <segment-row [segment]="segment" /> | ||
| } | ||
| </mat-grid-list> | ||
| </div> | ||
| } | ||
| </div> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,3 +2,11 @@ | |
| mat-grid-tile { | ||
| overflow: visible !important; /* Allow dropdown to overflow */ | ||
| } | ||
|
|
||
| .segment-page-heatmap { | ||
| --hex-w: clamp(60px, 5.5vw, 85px); | ||
|
||
| --hex-h: calc(var(--hex-w) * 1.155); | ||
| --hex-gap: 3px; | ||
| --row-offset: calc(var(--hex-w) / 2 + 3px); | ||
| margin: 0 auto; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,16 @@ | |
| <segment-at-a-glance style="width: 100%; height: 100%" [segmentNumber]="this.segmentId" /> | ||
| </mat-grid-tile> | ||
| <mat-grid-tile colspan="6" rowspan="8"> | ||
| <cell-by-cell-heat-map style="width: 100%; height: 100%" [currentSegment]="this.segmentId"></cell-by-cell-heat-map> | ||
| <info-background | ||
| style="width: 100%; height: 100%" | ||
| [title]="this.getHeatmapTitle()" | ||
| svgIcon="battery_charging_2" | ||
| [slicedLeftCorner]="true" | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add option for percentage that the corner is sliced. |
||
| [selectorConfigs]="[this.currentSegmentSelectorConfig, this.allSegSelectorConfig]" | ||
| > | ||
| <div style="padding-top: 20px"></div> | ||
| <segment-heatmap class="segment-page-heatmap" [segment]="this.segmentId" /> | ||
| </info-background> | ||
| </mat-grid-tile> | ||
| <mat-grid-tile colspan="3" rowspan="8"> | ||
| <!-- Alpha --> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,20 @@ | ||
| import { Component, HostListener, OnInit } from '@angular/core'; | ||
| import { inject } from '@angular/core'; | ||
| import { Component, HostListener, inject, OnDestroy, OnInit } from '@angular/core'; | ||
| import { ActivatedRoute, Router } from '@angular/router'; | ||
| import { Subscription } from 'rxjs'; | ||
| import { allSegments, Chip, Segment } from 'src/utils/bms.utils'; | ||
| import { MatGridList, MatGridTile } from '@angular/material/grid-list'; | ||
| import { BmsHeaderComponent } from '../components/bms-header/bms-header.component'; | ||
| import { SegmentAtAGlanceComponent } from '../components/segment-at-a-glance/segment-at-a-glance.component'; | ||
| import { CellByCellHeatMapComponent } from '../components/cell-by-cell-heat-map/cell-by-cell-heat-map.component'; | ||
| import { SegmentHeatmapComponent } from '../components/segment-heatmap/segment-heatmap.component'; | ||
| import { ChipDiagnosticsComponent } from '../components/chip-diagnostics/chip-diagnostics.component'; | ||
| import { ChipFaultsComponent } from '../components/chip-faults/chip-faults.component'; | ||
| import { InfoBackgroundComponent } from '../../../components/info-background/info-background.component'; | ||
| import { DropdownOption, SelectorConfig } from 'src/components/select-dropdown/select-dropdown.component'; | ||
| import { HeatMapService, HeatMapView } from 'src/services/heat-map.service'; | ||
|
|
||
| const formatAllSelectorName = (name: string) => { | ||
| return 'Set ALL Maps: ' + name; | ||
| }; | ||
|
|
||
| @Component({ | ||
| selector: 'bms-segment-view', | ||
|
|
@@ -19,23 +26,84 @@ import { ChipFaultsComponent } from '../components/chip-faults/chip-faults.compo | |
| MatGridTile, | ||
| BmsHeaderComponent, | ||
| SegmentAtAGlanceComponent, | ||
| CellByCellHeatMapComponent, | ||
| SegmentHeatmapComponent, | ||
| InfoBackgroundComponent, | ||
| ChipDiagnosticsComponent, | ||
| ChipFaultsComponent | ||
| ] | ||
| }) | ||
| export class BmsSegmentViewComponent implements OnInit { | ||
| export class BmsSegmentViewComponent implements OnInit, OnDestroy { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add comment |
||
| private readonly route = inject(ActivatedRoute); | ||
| private router = inject(Router); | ||
| private heatMapService = inject(HeatMapService); | ||
| private subscriptions: Subscription[] = []; | ||
| changeTitleSize = window.innerWidth < 1060; | ||
| segmentId!: Segment; | ||
| chipAlpha: Chip = Chip.Alpha; | ||
| chipBeta: Chip = Chip.Beta; | ||
|
|
||
| cellViewSelectOptions: DropdownOption[] = [ | ||
| { | ||
| name: HeatMapView.Temperature.toString(), | ||
| function: () => { | ||
| this.heatMapService.setCurrentView(this.segmentId, HeatMapView.Temperature); | ||
| } | ||
| }, | ||
| { | ||
| name: HeatMapView.Voltage.toString(), | ||
| function: () => { | ||
| this.heatMapService.setCurrentView(this.segmentId, HeatMapView.Voltage); | ||
| } | ||
| }, | ||
| { | ||
| name: HeatMapView.Balancing.toString(), | ||
| function: () => { | ||
| this.heatMapService.setCurrentView(this.segmentId, HeatMapView.Balancing); | ||
| } | ||
| } | ||
| ]; | ||
|
|
||
| currentSegmentSelectorConfig: SelectorConfig = { | ||
| options: this.cellViewSelectOptions, | ||
| placeholder: 'Change View' | ||
| }; | ||
|
|
||
| allSegSelectorConfig: SelectorConfig = { | ||
| options: this.cellViewSelectOptions.map((option) => ({ | ||
| name: formatAllSelectorName(option.name), | ||
| function: () => { | ||
| this.heatMapService.setAllSegViews(option.name as HeatMapView); | ||
| } | ||
| })), | ||
| placeholder: 'Change ALL Segments' | ||
| }; | ||
|
|
||
| ngOnInit(): void { | ||
| this.subscribeToSegmentID(); | ||
| } | ||
|
|
||
| getHeatmapTitle(): string { | ||
| return 'Segment ' + (this.segmentId + 1) + ': Cell-by-Cell'; | ||
| } | ||
|
|
||
| private subscribeToView(): void { | ||
| const viewSub = this.heatMapService.getCurrentView(this.segmentId); | ||
| if (viewSub) { | ||
| this.subscriptions.push( | ||
| viewSub.subscribe((view) => { | ||
| this.allSegSelectorConfig = { | ||
| ...this.allSegSelectorConfig, | ||
| defaultValue: view !== undefined ? formatAllSelectorName(view.toString()) : 'Change ALL Segments' | ||
| }; | ||
| this.currentSegmentSelectorConfig = { | ||
| ...this.currentSegmentSelectorConfig, | ||
| defaultValue: view !== undefined ? view : 'Change View' | ||
| }; | ||
| }) | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| // Update view width | ||
| @HostListener('window:resize', ['$event']) | ||
| onResize() { | ||
|
|
@@ -47,9 +115,14 @@ export class BmsSegmentViewComponent implements OnInit { | |
| this.route.paramMap.subscribe((params) => { | ||
| const possibleSegId = Number(params.get('id')) - 1; | ||
| allSegments.indexOf(possibleSegId) !== -1 ? (this.segmentId = possibleSegId) : this.router.navigate(['bms']); | ||
| this.subscribeToView(); | ||
| }); | ||
| } else { | ||
| this.router.navigate(['bms']); | ||
| } | ||
| }; | ||
|
|
||
| ngOnDestroy(): void { | ||
| this.subscriptions.forEach((s) => s.unsubscribe()); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.