Skip to content

Commit 7984b09

Browse files
committed
Merge branch 'main' of github.com:geo-engine/geoengine-ui into geoengine-2-rework
2 parents b2eb1da + 543bab5 commit 7984b09

File tree

6 files changed

+130
-150
lines changed

6 files changed

+130
-150
lines changed

projects/common/src/lib/colors/color-table-editor/color-table-editor.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<cdk-virtual-scroll-viewport itemSize="80" class="tabs-viewport">
2-
<div *cdkVirtualFor="let colorAttribute of colorAttributes; let i = index" class="grid-container">
2+
<div *cdkVirtualFor="let colorAttribute of colorAttributes(); let i = index" class="grid-container">
33
<geoengine-color-attribute-input
44
class="grid-colorpicker"
55
[ngModel]="colorAttribute"
66
(ngModelChange)="updateColorAt(i, $event)"
7-
[colorAttributeHinter]="colorHints"
7+
[colorAttributeHinter]="colorHints()"
88
></geoengine-color-attribute-input>
99
<button mat-icon-button (click)="removeColorAt(i)" class="grid-removebutton"><mat-icon>remove</mat-icon></button>
1010
@if (isNoNumber(i)) {

projects/common/src/lib/colors/color-table-editor/color-table-editor.component.ts

Lines changed: 69 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import {CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll, CdkVirtualForOf} fr
22
import {
33
ChangeDetectionStrategy,
44
Component,
5-
OnInit,
65
ChangeDetectorRef,
7-
OnChanges,
8-
SimpleChanges,
96
inject,
107
input,
118
output,
129
viewChild,
10+
computed,
11+
linkedSignal,
12+
effect,
1313
} from '@angular/core';
1414
import {WHITE} from '../color';
1515
import {
@@ -39,7 +39,7 @@ import {MatIcon} from '@angular/material/icon';
3939
MatIcon,
4040
],
4141
})
42-
export class ColorTableEditorComponent implements OnInit, OnChanges {
42+
export class ColorTableEditorComponent {
4343
private ref = inject(ChangeDetectorRef);
4444

4545
// Symbology to use for creating color tabs
@@ -52,26 +52,58 @@ export class ColorTableEditorComponent implements OnInit, OnChanges {
5252

5353
readonly virtualScrollViewport = viewChild.required(CdkVirtualScrollViewport);
5454

55-
colorAttributes: Array<ColorAttributeInput> = [];
56-
colorHints?: ColorAttributeInputHinter;
57-
58-
ngOnInit(): void {
59-
this.updateColorAttributes();
55+
readonly colorAttributes = linkedSignal<Array<ColorBreakpoint>, Array<ColorAttributeInput>>({
56+
source: () => this.colorTable(),
57+
computation: (colorTable: Array<ColorBreakpoint>) =>
58+
colorTable.map((color: ColorBreakpoint) => {
59+
return {key: color.value.toString(), value: color.color};
60+
}),
61+
equal: (a, b) => {
62+
if (a.length !== b.length) {
63+
return false;
64+
}
65+
for (let i = 0; i < a.length; i++) {
66+
if (a[i].key !== b[i].key) {
67+
return false;
68+
}
69+
if (!a[i].value.equals(b[i].value)) {
70+
return false;
71+
}
72+
}
73+
return true;
74+
},
75+
});
76+
readonly colorHints = computed<ColorAttributeInputHinter | undefined>(() => {
6077
const measurement = this.measurement();
78+
6179
if (measurement instanceof ClassificationMeasurement) {
62-
this.colorHints = measurement as ColorAttributeInputHinter;
80+
return measurement as ColorAttributeInputHinter;
6381
}
64-
}
6582

66-
ngOnChanges(_changes: SimpleChanges): void {
67-
this.updateColorAttributes();
68-
}
83+
return undefined;
84+
});
85+
86+
constructor() {
87+
effect(() => {
88+
const colorAttributes = this.colorAttributes();
89+
let hadError = false;
90+
91+
const colorTable: Array<ColorBreakpoint> = colorAttributes.map((color: ColorAttributeInput) => {
92+
const value = Number(color.key);
93+
94+
if (isNaN(value)) {
95+
hadError = true;
96+
}
6997

70-
updateColorAttributes(): void {
71-
this.colorAttributes = this.colorTable().map((color: ColorBreakpoint) => {
72-
return {key: color.value.toString(), value: color.color};
98+
return new ColorBreakpoint(value, color.value);
99+
});
100+
101+
if (hadError) {
102+
return;
103+
}
104+
105+
this.colorTableChanged.emit(colorTable);
73106
});
74-
this.ref.detectChanges();
75107
}
76108

77109
/**
@@ -81,75 +113,43 @@ export class ColorTableEditorComponent implements OnInit, OnChanges {
81113
* the time of updating.
82114
*/
83115
updateColorAt(index: number, color: ColorAttributeInput): void {
84-
this.colorAttributes.splice(index, 1, color);
85-
86-
// TODO: only sort if necessary
87-
this.sortColorAttributeInputs();
116+
const colorAttributes = [...this.colorAttributes()]; // copy
117+
colorAttributes.splice(index, 1, color);
88118

89-
this.emitColorTable();
119+
this.colorAttributes.set(sorted(colorAttributes));
90120
}
91121

92122
removeColorAt(index: number): void {
93-
this.colorAttributes.splice(index, 1);
94-
this.colorAttributes = [...this.colorAttributes]; // new array
123+
const colorAttributes = [...this.colorAttributes()]; // copy
124+
colorAttributes.splice(index, 1);
95125

96-
setTimeout(() => this.ref.detectChanges());
97-
98-
this.emitColorTable();
99-
}
100-
101-
/**
102-
* Sort allColors by raster layer values, so ColorAttributeInputs are displayed in the correct order.
103-
* Only called by parent when apply is pressed, so Inputs don't jump around while user is editing.
104-
*/
105-
sortColorAttributeInputs(): void {
106-
this.colorAttributes = this.colorAttributes.sort((a: ColorAttributeInput, b: ColorAttributeInput) =>
107-
Math.sign(parseFloat(a.key) - parseFloat(b.key)),
108-
);
109-
110-
setTimeout(() => this.ref.markForCheck());
126+
this.colorAttributes.set(colorAttributes);
111127
}
112128

113129
appendColor(): void {
130+
const colorAttributes = this.colorAttributes();
131+
114132
let newValue;
115-
if (this.colorAttributes.length) {
133+
if (colorAttributes.length) {
116134
// Determine a value so that the new tab will appear at the bottom of the list.
117-
newValue = parseFloat(this.colorAttributes[this.colorAttributes.length - 1].key) + 1;
135+
newValue = parseFloat(colorAttributes[colorAttributes.length - 1].key) + 1;
118136
} else {
119137
newValue = 0;
120138
}
121139

122-
this.colorAttributes = [...this.colorAttributes, {key: newValue.toString(), value: WHITE}];
123-
124-
// TODO: do we need that?
125-
this.sortColorAttributeInputs();
140+
this.colorAttributes.set(sorted([...colorAttributes, {key: newValue.toString(), value: WHITE}]));
126141

127142
setTimeout(() => this.virtualScrollViewport().scrollTo({bottom: 0}), 0); // Delay of 0 to include new tab in scroll
128-
129-
this.emitColorTable();
130143
}
131144

132145
isNoNumber(index: number): boolean {
133-
return isNaN(Number(this.colorAttributes[index].key));
134-
}
135-
136-
emitColorTable(): void {
137-
let hadError = false;
138-
139-
const colorTable: Array<ColorBreakpoint> = this.colorAttributes.map((color: ColorAttributeInput) => {
140-
const value = Number(color.key);
141-
142-
if (isNaN(value)) {
143-
hadError = true;
144-
}
145-
146-
return new ColorBreakpoint(value, color.value);
147-
});
148-
149-
if (hadError) {
150-
return;
151-
}
152-
153-
this.colorTableChanged.emit(colorTable);
146+
return isNaN(Number(this.colorAttributes()[index].key));
154147
}
155148
}
149+
150+
/**
151+
* Sort allColors by raster layer values, so ColorAttributeInputs are displayed in the correct order.
152+
* Only called by parent when apply is pressed, so Inputs don't jump around while user is editing.
153+
*/
154+
const sorted = (colorAttributes: Array<ColorAttributeInput>): Array<ColorAttributeInput> =>
155+
colorAttributes.sort((a: ColorAttributeInput, b: ColorAttributeInput) => Math.sign(parseFloat(a.key) - parseFloat(b.key)));

projects/common/src/lib/symbology/raster-gradient-symbology-editor/raster-gradient-symbology-editor.component.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
</div>
3333
</mat-card-content>
3434

35-
<div class="colorizer-preview" [style.background]="colorizer | geoengineColorizerCssGradient: 90"></div>
35+
<div class="colorizer-preview" [style.background]="colorizer() | geoengineColorizerCssGradient: 90"></div>
3636
</mat-card>
3737

3838
<mat-card>
@@ -46,7 +46,7 @@
4646
<mat-card-content>
4747
<mat-tab-group>
4848
<mat-tab label="Min/Max">
49-
@if (queryParams) {
49+
@if (queryParams()) {
5050
@if (histogramCreated === true) {
5151
<div class="histogram">
5252
@if (histogramData | async; as histogramData) {
@@ -87,7 +87,7 @@
8787

8888
<button mat-stroked-button (click)="createColorTable()">Create color table</button>
8989
</mat-tab>
90-
@if (queryParams) {
90+
@if (queryParams(); as queryParams) {
9191
<mat-tab label="Percentiles">
9292
<geoengine-percentile-breakpoint-selector
9393
(breakpointsChange)="updateBreakpoints($event)"

0 commit comments

Comments
 (0)