This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch improve-label-coloring in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit 07c0aeb0e93bf85a7684d8d18f663a4e0ed4c80e Author: Dominik Riemer <[email protected]> AuthorDate: Tue Oct 14 07:31:11 2025 +0200 feat: Improve handling of label colors --- .../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(); + } + } }
