Skip to content

Commit

Permalink
Merge pull request #741 from gisaia/feature/enhanceColorGenerator
Browse files Browse the repository at this point in the history
Feat: enhance color service
  • Loading branch information
mbarbet authored Aug 11, 2023
2 parents db48f65 + 295a841 commit 5da4058
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 46 deletions.
15 changes: 8 additions & 7 deletions projects/arlas-components/src/lib/components/componentsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { mix } from 'tinycolor2';
import { isNumber } from 'util';
import { UntypedFormControl, Validators } from '@angular/forms';
import { Observable, Subject } from 'rxjs';

export function formatNumber(x, formatChar = ' '): string {
if (formatChar === NUMBER_FORMAT_CHAR) {
Expand Down Expand Up @@ -67,8 +68,9 @@ export function getValues(map): Array<any> {
}

export abstract class ColorGeneratorLoader {
public abstract keysToColors: Array<Array<string>>;
public abstract colorsSaturationWeight: number ;
public abstract keysToColors: Array<[string, string]>;
public abstract colorsSaturationWeight: number;
public abstract changekeysToColors$: Observable<void>;
/**
* This method generates a determistic color from the given key, a list of [key, color] and a saturation weight.
* @param key The text from which the color is generated
Expand All @@ -81,9 +83,9 @@ export abstract class ColorGeneratorLoader {
}

export class AwcColorGeneratorLoader extends ColorGeneratorLoader {
public keysToColors: Array<Array<string>>;
public colorsSaturationWeight = 0.5 ;

public changekeysToColors$: Observable<void> = new Subject<void>().asObservable();
public keysToColors: Array<[string, string]>;
public colorsSaturationWeight = 0.5;
/**
* This method generates a determistic color from the given key, a list of [key, color] and a saturation weight.
* - First the method checks if the [key,color] is defined in externalkeysToColors and returns the correspondant color.
Expand Down Expand Up @@ -135,12 +137,11 @@ export class AwcColorGeneratorLoader extends ColorGeneratorLoader {
}
// int to rgb
let hex = (hash & 0x00FFFFFF).toString(16).toUpperCase();
hex = '00000'.substring(0, 6 - hex.length) + hex;
hex = '00000'.substring(0, 6 - hex.length) + hex;
const color = mix(hex, hex);
color.saturate(color.toHsv().s * saturationWeight + ((1 - saturationWeight) * 100));
return color.toHexString();
}

}

export class SelectFormControl extends UntypedFormControl {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { DonutComponent } from './donut.component';
import { ArlasColorService } from '../../services/color.generator.service';
import { ColorGeneratorLoader } from '../componentsUtils';
import { AwcColorGeneratorLoader, ColorGeneratorLoader } from '../componentsUtils';
import { TranslateModule, TranslateLoader, TranslateFakeLoader } from '@ngx-translate/core';
import { ColorGeneratorModule } from '../../services/color.generator.module';

describe('DonutComponent', () => {
let component: DonutComponent;
Expand All @@ -33,11 +34,15 @@ describe('DonutComponent', () => {
declarations: [ DonutComponent ],
imports: [
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateFakeLoader } }),
ColorGeneratorModule.forRoot({
loader: {
provide: ColorGeneratorLoader,
useClass: AwcColorGeneratorLoader
}
})
],
providers: [
ArlasColorService,
ColorGeneratorLoader
]
ArlasColorService ]
})
.compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ export class DonutComponent implements OnChanges {
.subscribe((event: Event) => {
this.donut.resize(this.el.nativeElement.childNodes[0]);
});
this.colorService.changekeysToColors$.subscribe(() => {
this.donut.donutParams.keysToColors = this.colorService.colorGenerator.keysToColors;
this.donut.donutParams.donutNodeColorizer = this.colorService;
this.donut.resize(this.el.nativeElement.childNodes[0]);
});
}

public ngOnChanges(changes: SimpleChanges): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,30 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { HistogramComponent } from './histogram.component';
import { ArlasColorService } from '../../services/color.generator.service';
import { ColorGeneratorLoader } from '../componentsUtils';
import { AwcColorGeneratorLoader, ColorGeneratorLoader } from '../componentsUtils';
import { TranslateModule, TranslateLoader, TranslateFakeLoader } from '@ngx-translate/core';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ColorGeneratorModule } from '../../services/color.generator.module';

describe('HistogramComponent', () => {
let component: HistogramComponent;
let fixture: ComponentFixture<HistogramComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HistogramComponent ],
declarations: [HistogramComponent],
imports: [
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateFakeLoader } }),
MatTooltipModule
MatTooltipModule,
ColorGeneratorModule.forRoot({
loader: {
provide: ColorGeneratorLoader,
useClass: AwcColorGeneratorLoader
}
})
],
providers: [
ArlasColorService,
ColorGeneratorLoader
ArlasColorService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule, TranslateLoader, TranslateFakeLoader } from '@ngx-translate/core';
import { ArlasColorService } from '../../services/color.generator.service';
import { ColorGeneratorLoader } from '../componentsUtils';
import { AwcColorGeneratorLoader, ColorGeneratorLoader } from '../componentsUtils';
import { LayerIdToName } from './layer-name.pipe';
import { MapglLayerIconModule } from '../mapgl-layer-icon/mapgl-layer-icon.module';
import { MatMenuModule } from '@angular/material/menu';
import { ColorGeneratorModule } from '../../services/color.generator.module';

describe('MapglLegendComponent', () => {
let component: MapglLegendComponent;
Expand All @@ -25,11 +26,16 @@ describe('MapglLegendComponent', () => {
MatMenuModule,
MatTooltipModule,
MapglLayerIconModule,
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateFakeLoader } })
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateFakeLoader } }),
ColorGeneratorModule.forRoot({
loader: {
provide: ColorGeneratorLoader,
useClass: AwcColorGeneratorLoader
}
})
],
providers: [
ArlasColorService,
ColorGeneratorLoader
ArlasColorService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { PowerbarsComponent } from './powerbars.component';
import { ArlasColorService } from '../../services/color.generator.service';
import { ColorGeneratorLoader } from '../componentsUtils';
import { AwcColorGeneratorLoader, ColorGeneratorLoader } from '../componentsUtils';
import { TranslateModule, TranslateLoader, TranslateFakeLoader } from '@ngx-translate/core';
import { FormatNumberPipe } from '../../pipes/format-number/format-number.pipe';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatInputModule } from '@angular/material/input';
import { ColorGeneratorModule } from '../../services/color.generator.module';

describe('PowerbarsComponent', () => {
let component: PowerbarsComponent;
Expand All @@ -42,10 +43,15 @@ describe('PowerbarsComponent', () => {
MatIconModule,
MatTooltipModule,
MatInputModule,
ColorGeneratorModule.forRoot({
loader: {
provide: ColorGeneratorLoader,
useClass: AwcColorGeneratorLoader
}
})
],
providers: [
ArlasColorService,
ColorGeneratorLoader
ArlasColorService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,15 @@ export class PowerbarsComponent implements OnInit, OnChanges, AfterViewInit {
public NUMBER_FORMAT_CHAR = NUMBER_FORMAT_CHAR;

public constructor(private colorService: ArlasColorService) {
this.colorService.changekeysToColors$.subscribe(() => {
this.powerBarsList.forEach(p => {
if (this.useColorService) {
const rgbaColor = tinycolor.default(this.colorService.getColor(p.term, this.keysToColors,
this.colorsSaturationWeight)).toRgb();
p.color = this.getPowerbarColor(rgbaColor);
}
});
});
}

public static getPowerbarsJsonSchema(): Object {
Expand All @@ -216,7 +225,7 @@ export class PowerbarsComponent implements OnInit, OnChanges, AfterViewInit {
if (this.useColorService) {
const rgbaColor = tinycolor.default(this.colorService.getColor(missingLeafToUpdate.term, this.keysToColors,
this.colorsSaturationWeight)).toRgb();
missingLeafToUpdate.color = 'rgba(' + [rgbaColor.r, rgbaColor.g, rgbaColor.b, 0.7].join(',') + ')';
missingLeafToUpdate.color = this.getPowerbarColor(rgbaColor);
}
this.selectedPowerbarsSet.delete(missingLeaf);
this.selectedPowerbarsSet.add(missingLeafToUpdate);
Expand Down Expand Up @@ -309,11 +318,9 @@ export class PowerbarsComponent implements OnInit, OnChanges, AfterViewInit {
if (this.useColorService) {
const rgbaColor = tinycolor.default(this.colorService.getColor(powerBar.term, this.keysToColors,
this.colorsSaturationWeight)).toRgb();
powerBar.color = 'rgba(' + [rgbaColor.r, rgbaColor.g, rgbaColor.b, 0.7].join(',') + ')';
powerBar.color = this.getPowerbarColor(rgbaColor);
}
} else {


powerBar = currentPath.length > 1 ? new PowerBar(currentPath[0].fieldValue, currentPath[1].fieldValue, 0) :
new PowerBar(currentPath[0].fieldValue, 'root', 0);
powerBar.path = currentPath;
Expand Down Expand Up @@ -387,7 +394,7 @@ export class PowerbarsComponent implements OnInit, OnChanges, AfterViewInit {
if (this.useColorService) {
const rgbaColor = tinycolor.default(this.colorService.getColor(powerBar.term, this.keysToColors,
this.colorsSaturationWeight)).toRgb();
powerBar.color = 'rgba(' + [rgbaColor.r, rgbaColor.g, rgbaColor.b, 0.7].join(',') + ')';
powerBar.color = this.getPowerbarColor(rgbaColor);
}
if (this.useColorFromData) {
powerBar.color = child.color.toString()[0] === '#' ? child.color.toString() : '#'.concat(child.color.toString());
Expand Down Expand Up @@ -490,4 +497,8 @@ export class PowerbarsComponent implements OnInit, OnChanges, AfterViewInit {
});
return foundPowerbar;
}

private getPowerbarColor(rgbaColor: tinycolor.ColorFormats.RGBA): string{
return 'rgba(' + [rgbaColor.r, rgbaColor.g, rgbaColor.b, 0.7].join(',') + ')';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
</label>
<ng-template #labelModeIsDefined>
<label *ngIf="cellBackgroundStyle === CellBackgroundStyleEnum.filled && column.useColorService" class="resultitem__cell--label resultitem__cell--label__filled"
[style.background-color]="getColor(rowItem?.itemData.get(column.fieldName))" [style.color]="getTextColor(getColor(rowItem?.itemData.get(column.fieldName)))">
[style.background-color]="colors[rowItem?.itemData.get(column.fieldName)]['color']"
[style.color]="colors[rowItem?.itemData.get(column.fieldName)]['textColor']">
{{rowItem?.itemData.get(column.fieldName) | formatNumber:NUMBER_FORMAT_CHAR}}{{column.dataType}}
</label>
<label *ngIf="cellBackgroundStyle === CellBackgroundStyleEnum.outlined && column.useColorService && !!rowItem?.itemData.get(column.fieldName) && rowItem?.itemData.get(column.fieldName) !== ''" class="resultitem__cell--label resultitem__cell--label__outlined"
[style.border-color]="getColor(rowItem?.itemData.get(column.fieldName))">
[style.border-color]="colors[rowItem?.itemData.get(column.fieldName)]['color']" >
{{rowItem?.itemData.get(column.fieldName) | formatNumber:NUMBER_FORMAT_CHAR}}{{column.dataType}}
</label>
</ng-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { ResultItemComponent } from './result-item.component';
import { ArlasColorService } from '../../../services/color.generator.service';
import { ColorGeneratorLoader } from '../../componentsUtils';
import { AwcColorGeneratorLoader, ColorGeneratorLoader } from '../../componentsUtils';
import { TranslateFakeLoader, TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ColorGeneratorModule } from '../../../services/color.generator.module';
import { Item } from '../model/item';

describe('ResultItemComponent', () => {
let component: ResultItemComponent;
Expand All @@ -36,10 +38,15 @@ describe('ResultItemComponent', () => {
imports: [
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: TranslateFakeLoader } }),
MatIconModule,
MatTooltipModule
MatTooltipModule,
ColorGeneratorModule.forRoot({
loader: {
provide: ColorGeneratorLoader,
useClass: AwcColorGeneratorLoader
}
})
],
providers: [
ColorGeneratorLoader,
ArlasColorService
]
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,20 @@ export class ResultItemComponent extends ItemComponent implements OnInit {
public detailedData = '';
public actions;
public borderStyle = 'solid';
public colors = {};
protected identifier: string;

public NUMBER_FORMAT_CHAR = NUMBER_FORMAT_CHAR;

public constructor(public colorService: ArlasColorService, public translate: TranslateService) {
super();
this.colorService.changekeysToColors$.subscribe(() => this.updateColors());
}

public ngOnInit() {
this.identifier = this.rowItem?.identifier;
this.updateColors();

}

// Detailed data is retrieved wheb the row is toggled for the first time
Expand Down Expand Up @@ -166,24 +170,42 @@ export class ResultItemComponent extends ItemComponent implements OnInit {
this.selectedItemsEvent.next(this.selectedItems);
}

public getColor(key): string {
public getTextColor(key): string {
if (key !== undefined && key !== null) {
return this.colorService.getColor(key.toString(), this.keysToColors, this.colorsSaturationWeight);
return this.colorService.getTextColor(key.toString());
} else {
return '';
}
}

public getTextColor(key: string): string {
public triggerActionOnItem(action: Action) {
this.actionOnItemEvent.next({ action: action, elementidentifier: { idFieldName: this.idFieldName, idValue: this.rowItem.identifier } });
}

private updateColors() {
const newColor = {};
this.rowItem?.columns.forEach(c => {
if(c.useColorService){
const key = this.rowItem?.itemData.get(c.fieldName);
if (key !== undefined && key !== null) {
newColor[key.toString()] = {};
newColor[key.toString()]['color'] = this.getColor(key);
newColor[key.toString()]['textColor'] = this.getTextColor(key);

}
}
});
this.colors = newColor;
}

private getColor(key): string {
if (key !== undefined && key !== null) {
return this.colorService.getTextColor(key.toString());
return this.colorService.getColor(key.toString(), this.keysToColors, this.colorsSaturationWeight);
} else {
return '';
}
}

public triggerActionOnItem(action: Action) {
this.actionOnItemEvent.next({ action: action, elementidentifier: { idFieldName: this.idFieldName, idValue: this.rowItem.identifier } });
}


}
Loading

0 comments on commit 5da4058

Please sign in to comment.