Bladeren bron

Resize graph bruteforce fix

A-Konig 1 week geleden
bovenliggende
commit
b8773c412a

+ 6 - 4
src/app/sensor/components/sensor.component.html

@@ -32,6 +32,8 @@
     </div>
       <div class="graph-range-dates">
           <div class="input-group form-group">
+              <label for="from">From:</label>
+
               <p-calendar
                       id="from"
                       [style]="{'width':'100%'}"
@@ -44,10 +46,10 @@
                       showButtonBar=true>
               </p-calendar>
           </div>
-          <div class="graph-range-dates-separator">
-              <div></div>
-          </div>
+
           <div class="input-group form-group">
+              <label for="to">To:</label>
+
               <p-calendar
                       id="to"
                       [style]="{'width':'100%'}"
@@ -69,6 +71,6 @@
       </div>
   </div>
   <div class="graph-view-wrapper">
-    <div id="view" style="width:100%; height:auto;"></div>
+    <div #viewPanel id="view" style="width:100%; height:auto;"></div>
   </div>
 </div>

+ 9 - 0
src/app/sensor/components/sensor.component.scss

@@ -8,8 +8,11 @@
   border-top-right-radius: 6px;
   border-bottom-right-radius: 6px;
   border-left: none;
+  background: #174B97 !important;
+  border-color: #174B97 !important;
 }
 
+
 /* Add space to the right of every button except the last one */
 ::ng-deep .button-row .p-button:not(:last-child) {
   margin-right: 1rem;
@@ -17,4 +20,10 @@
 
 ::ng-deep .interval-alert {
   margin: 5px !important;
+}
+
+::ng-deep .input-group {
+  display: flex;
+  flex-direction: column;
+  padding-right: 50px;
 }

+ 34 - 16
src/app/sensor/components/sensor.component.ts

@@ -1,4 +1,4 @@
-import { Component, OnDestroy, OnInit, HostListener } from '@angular/core';
+import {Component, OnDestroy, OnInit, HostListener, AfterViewInit, NgZone, ElementRef, ViewChild} from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 import * as moment from 'moment-timezone';
 import { GraphLoader } from '../../shared/graph-loading/graphloader';
@@ -16,7 +16,7 @@ import type { View } from 'vega';
   templateUrl: './sensor.component.html',
   styleUrls: ['./sensor.component.scss']
 })
-export class SensorComponent implements OnInit, OnDestroy {
+export class SensorComponent implements OnInit, OnDestroy, AfterViewInit {
 
   sensorId: number;
   unitId: number;
@@ -32,6 +32,7 @@ export class SensorComponent implements OnInit, OnDestroy {
   showIntervalError = false;
   private resizeObserver!: ResizeObserver; // Will watch the container size
   graphView;
+  @ViewChild('viewPanel') viewElement!: ElementRef;
 
   constructor(
     private activatedRoute: ActivatedRoute,
@@ -39,6 +40,7 @@ export class SensorComponent implements OnInit, OnDestroy {
     private toastService: ToastService,
     private sensorsService: SensorsService,
     private route: ActivatedRoute,
+    private ngZone: NgZone
   ) {
     this.getInitData();
     this.sensorsService.getUnitSensors({ unit_id: this.unitId }).subscribe(sensors => {
@@ -49,16 +51,25 @@ export class SensorComponent implements OnInit, OnDestroy {
     }, err => this.toastService.showError(err.error.message));
   }
 
+  ngOnInit(): void {
+  }
+
   ngAfterViewInit() {
-    window.addEventListener('resize', () => console.log('raw'))
+    this.setupResizeObserver();
   }
 
-  /*
-    Fires on every resize event
-   */
-  @HostListener('window:resize', ['$event'])
-  public onWindowResize(event: UIEvent): void {
-    this.onResize();
+  private setupResizeObserver() {
+    this.resizeObserver = new ResizeObserver((entries) => {
+      // Use NgZone.run if you need to update Angular variables/UI or requestAnimationFrame to sync with the browser paint
+      this.ngZone.run(() => {
+        this.onResize();
+      });
+    });
+
+    // Start observing the native element
+    if (this.viewElement) {
+      this.resizeObserver.observe(this.viewElement.nativeElement);
+    }
   }
 
   /**
@@ -71,7 +82,7 @@ export class SensorComponent implements OnInit, OnDestroy {
       }
     });
     this.sensorId = parseInt(this.activatedRoute.snapshot.paramMap.get('sensorId'), 10);
-    this.unitId = parseInt(this.activatedRoute.snapshot.paramMap.get('unitId'), 10);   
+    this.unitId = parseInt(this.activatedRoute.snapshot.paramMap.get('unitId'), 10);
   }
 
   /**
@@ -79,9 +90,9 @@ export class SensorComponent implements OnInit, OnDestroy {
    */
   ngOnDestroy(): void {
     this.subscription.forEach(subs => subs.unsubscribe());
-  }
-
-  ngOnInit(): void {
+    if (this.resizeObserver) {
+      this.resizeObserver.disconnect();
+    }
   }
 
   /**
@@ -149,11 +160,18 @@ export class SensorComponent implements OnInit, OnDestroy {
 
   private onResize(): void {
     // resize graph width if window changes size
-    const box = document.getElementById('view');
-
+    const box = this.viewElement.nativeElement;
     if (this.graphView) {
       const newWidth = box.getBoundingClientRect().width - 50;
-      this.graphView.width(newWidth).height(300).runAsync();
+      this.graphView.width(newWidth).height(300).run();
+      console.log('Requested width : ', newWidth);
+      console.log('Got width: ', this.graphView.width());
+
+      // 3. Check if Vega "stole" pixels. If it did, force it again.
+      if (this.graphView.width() < newWidth - 50) {
+        this.graphView.width(newWidth).height(300).runAsync();
+        console.log('Calling resize twice');
+      }
     }
   }
 }

+ 2 - 0
src/app/shared/graph-loading/graphloader.ts

@@ -95,6 +95,8 @@ export class GraphLoader {
     config.width = this.width;
     config.height = this.height;
 
+    console.log(JSON.stringify(config));
+
     // const view = await
     return new vega.View(vega.parse(spec, config))
       .tooltip(handler.call)

+ 2 - 1
src/app/unit/components/unit.component.html

@@ -32,7 +32,8 @@
       </div>
 
       <div class="input-group form-group">
-          To:
+          <label for="to">To:</label>
+
           <p-calendar
                   id="to"
                   [style]="{'width':'100%'}"

+ 23 - 11
src/app/unit/components/unit.component.ts

@@ -88,19 +88,31 @@ export class UnitComponent implements OnInit, OnDestroy {
     const itemCount = Object.keys(this.graphViews).length;
     console.log('Number of entries:', itemCount);
 
-    Object.entries(this.graphViews).forEach(([key, view]) => {
-      // Process each pair here
+    window.requestAnimationFrame(() => {
+      Object.entries(this.graphViews).forEach(([key, view]) => {
+        // Process each pair here
 
-      const sensorGroupElement = '#vega_container_' + key;
-      const box = document.getElementById('vega_container_' + key);
-      const boxWidth = box.getBoundingClientRect().width;
-      const boxHeight = box.getBoundingClientRect().height;
+        const sensorGroupElement = '#vega_container_' + key;
+        const box = document.getElementById('vega_container_' + key);
+        const boxWidth = box.getBoundingClientRect().width;
+        const boxHeight = box.getBoundingClientRect().height;
 
-      if (view) {
-        const newWidth = box.getBoundingClientRect().width - 50;
-        console.log('Key:', key, 'NewWidth:', newWidth);
-        view.width(newWidth).height(300).runAsync();
-      }
+        console.log('Container Style:', window.getComputedStyle(box).width);
+
+        if (view) {
+          const newWidth = box.getBoundingClientRect().width - 60;
+          console.log('Key:', key, 'NewWidth:', newWidth);
+
+          view.width(newWidth).runAsync().then(v => {
+            console.log('--- Debugging Vega Layout ---');
+            console.log('Target Width Signal:', v.signal('width'));
+            console.log('Actual View Width:', v.width());
+            console.log('Padding:', v.padding());
+            // If this returns a different number than 'width',
+            // a signal in your JSON is overriding the layout.
+          });
+        }
+      })
     });
   }
 

+ 5 - 1
src/vega/config/config.json

@@ -5,7 +5,11 @@
     {"name":  "axeLegendPath", "value":  "phenomenon.phenomenonName"},
     {"name":  "axeUnitPath", "value":  "phenomenon.unit"}
   ],
-  "autosize": "fit-x",
+  "autosize": {
+    "type": "fit-x",
+    "contains": "content"
+  },
+  "padding": {"left": 0, "right": 0, "top": 0, "bottom": 0},
   "width": 800,
   "height": 300
 }