This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to refs/heads/dev by this push:
     new 0477476a8a feat: Improve handling of label colors (#3831)
0477476a8a is described below

commit 0477476a8a33b7e13ce6adac505bbc91a4d390fe
Author: Dominik Riemer <[email protected]>
AuthorDate: Tue Oct 14 10:44:24 2025 +0200

    feat: Improve handling of label colors (#3831)
---
 .../src/lib/services/colorization.service.ts       | 107 +++++++++++++++++++--
 .../edit-label/edit-label.component.html           |   2 +-
 .../edit-label/edit-label.component.ts             |  21 +++-
 3 files changed, 120 insertions(+), 10 deletions(-)

diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/services/colorization.service.ts 
b/ui/projects/streampipes/shared-ui/src/lib/services/colorization.service.ts
index 6e1c82d258..0356ab45f7 100644
--- a/ui/projects/streampipes/shared-ui/src/lib/services/colorization.service.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/services/colorization.service.ts
@@ -20,12 +20,105 @@ import { Injectable } from '@angular/core';
 
 @Injectable({ providedIn: 'root' })
 export class SpColorizationService {
-    generateContrastColor(bgColor: string) {
-        const color =
-            bgColor.charAt(0) === '#' ? bgColor.substring(1, 7) : bgColor;
-        const r = parseInt(color.substring(0, 2), 16);
-        const g = parseInt(color.substring(2, 4), 16);
-        const b = parseInt(color.substring(4, 6), 16);
-        return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? '#000' : '#FFF';
+    generateContrastColor(bgColor: string): string {
+        const hex = bgColor.startsWith('#') ? bgColor.substring(1) : bgColor;
+        const r = parseInt(hex.substring(0, 2), 16);
+        const g = parseInt(hex.substring(2, 4), 16);
+        const b = parseInt(hex.substring(4, 6), 16);
+
+        // Convert to HSL
+        const { h, s, l } = this.rgbToHsl(r, g, b);
+
+        // Adjust lightness: if background is dark, make text lighter; else 
make it darker
+        const textLightness = l > 0.5 ? l - 0.45 : l + 0.45;
+
+        // Convert back to RGB
+        const {
+            r: tr,
+            g: tg,
+            b: tb,
+        } = this.hslToRgb(h, s, Math.min(1, Math.max(0, textLightness)));
+
+        // Return as hex
+        return this.rgbToHex(tr, tg, tb);
+    }
+
+    generateRandomColor(): string {
+        // Use HSL for easier color control
+        const h = Math.floor(Math.random() * 360);
+        const s = 0.55 + Math.random() * 0.25;
+        const l = 0.45 + (Math.random() - 0.5) * 0.2;
+
+        const { r, g, b } = this.hslToRgb(h / 360, s, l);
+        return this.rgbToHex(r, g, b);
+    }
+
+    private rgbToHsl(r: number, g: number, b: number) {
+        r /= 255;
+        g /= 255;
+        b /= 255;
+        const max = Math.max(r, g, b);
+        const min = Math.min(r, g, b);
+        let h = 0,
+            s = 0;
+        const l = (max + min) / 2;
+
+        if (max !== min) {
+            const d = max - min;
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+            switch (max) {
+                case r:
+                    h = (g - b) / d + (g < b ? 6 : 0);
+                    break;
+                case g:
+                    h = (b - r) / d + 2;
+                    break;
+                case b:
+                    h = (r - g) / d + 4;
+                    break;
+            }
+            h /= 6;
+        }
+
+        return { h, s, l };
+    }
+
+    private hslToRgb(h: number, s: number, l: number) {
+        let r: number, g: number, b: number;
+
+        if (s === 0) {
+            r = g = b = l; // achromatic
+        } else {
+            const hue2rgb = (p: number, q: number, t: number) => {
+                if (t < 0) t += 1;
+                if (t > 1) t -= 1;
+                if (t < 1 / 6) return p + (q - p) * 6 * t;
+                if (t < 1 / 2) return q;
+                if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+                return p;
+            };
+
+            const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+            const p = 2 * l - q;
+            r = hue2rgb(p, q, h + 1 / 3);
+            g = hue2rgb(p, q, h);
+            b = hue2rgb(p, q, h - 1 / 3);
+        }
+
+        return {
+            r: Math.round(r * 255),
+            g: Math.round(g * 255),
+            b: Math.round(b * 255),
+        };
+    }
+
+    private rgbToHex(r: number, g: number, b: number): string {
+        return (
+            '#' +
+            [r, g, b]
+                .map(x => x.toString(16).padStart(2, '0'))
+                .join('')
+                .toUpperCase()
+        );
     }
 }
diff --git 
a/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.html
 
b/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.html
index 6d643f852d..e605c7ac17 100644
--- 
a/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.html
+++ 
b/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.html
@@ -64,7 +64,7 @@
                 mat-flat-button
                 color="accent"
                 data-cy="save-label-button"
-                (click)="saveEmitter.emit(label)"
+                (click)="saveLabel()"
             >
                 {{ 'Save' | translate }}
             </button>
diff --git 
a/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.ts
 
b/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.ts
index 420bfc9497..c10f73a52c 100644
--- 
a/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.ts
+++ 
b/ui/src/app/configuration/label-configuration/edit-label/edit-label.component.ts
@@ -16,8 +16,16 @@
  *
  */
 
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import {
+    Component,
+    EventEmitter,
+    inject,
+    Input,
+    OnInit,
+    Output,
+} from '@angular/core';
 import { SpLabel } from '@streampipes/platform-services';
+import { SpColorizationService } from '@streampipes/shared-ui';
 
 @Component({
     selector: 'sp-edit-label',
@@ -26,6 +34,8 @@ import { SpLabel } from '@streampipes/platform-services';
     standalone: false,
 })
 export class SpEditLabelComponent implements OnInit {
+    private colorizationService = inject(SpColorizationService);
+
     @Input()
     editMode = false;
 
@@ -44,10 +54,17 @@ export class SpEditLabelComponent implements OnInit {
     ngOnInit(): void {
         if (!this.label) {
             this.label = {
-                color: '#00a7fc',
+                color: this.colorizationService.generateRandomColor(),
                 label: '',
                 description: '',
             };
         }
     }
+
+    saveLabel(): void {
+        this.saveEmitter.emit(this.label);
+        if (this.showPreview) {
+            this.label.color = this.colorizationService.generateRandomColor();
+        }
+    }
 }

Reply via email to