Skip to content

Commit fea707f

Browse files
committed
optimization
Signed-off-by: Qxisylolo <[email protected]>
1 parent 41e7dbb commit fea707f

File tree

2 files changed

+67
-87
lines changed

2 files changed

+67
-87
lines changed

src/plugins/explore/public/components/visualizations/bar_gauge/bar_gauge_utils.ts

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -80,26 +80,6 @@ export const getGradientConfig = (
8080
};
8181
};
8282

83-
export const darkenColor = (hex: string, degree = 1) => {
84-
// degree: 1 = 10%, 2 = 20%, etc.
85-
const factor = 1 - degree * 0.1;
86-
87-
if (hex.length === 4) {
88-
hex = '#' + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
89-
}
90-
91-
let r = parseInt(hex.slice(1, 3), 16);
92-
let g = parseInt(hex.slice(3, 5), 16);
93-
let b = parseInt(hex.slice(5, 7), 16);
94-
95-
r = Math.max(Math.floor(r * factor), 0);
96-
g = Math.max(Math.floor(g * factor), 0);
97-
b = Math.max(Math.floor(b * factor), 0);
98-
99-
const toHex = (n: number) => n.toString(16).padStart(2, '0');
100-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
101-
};
102-
10383
export const processThresholds = (thresholds: Threshold[]) => {
10484
const result: Threshold[] = [];
10585

@@ -136,34 +116,33 @@ export const generateParams = (
136116

137117
if (i === 0) {
138118
result.push({
139-
name: `test${i}`,
140-
value: {
141-
gradient: 'linear',
142-
...getGradientConfig(
143-
styleOptions.exclusive.orientation,
144-
styleOptions.exclusive.displayMode,
145-
isXaxisNumerical
146-
),
147-
stops: [
148-
{ offset: 0, color: thresholds[0].color },
149-
{
150-
offset: 1,
151-
color: darkenColor(thresholds[0]?.color, 2),
152-
},
153-
],
154-
},
119+
name: `gradient${i}`,
120+
value: thresholds[0]?.color,
155121
});
156122
continue;
157123
}
158124

159-
// collect stops up to current threshold
160-
const stops = thresholds.slice(0, i + 1).map((threshold) => {
161-
const offset = normalizeData(threshold.value, start, end);
162-
return { offset, color: threshold.color };
163-
});
125+
const allStops = thresholds.slice(0, i + 1).map((t) => ({
126+
offset: normalizeData(t.value, start, end),
127+
color: t.color,
128+
}));
129+
130+
const stops = [];
131+
for (let j = 0; j < allStops.length; j++) {
132+
const curr = allStops[j];
133+
const prev = allStops[j - 1];
134+
135+
if (j === 0 || j === allStops.length - 1 || curr.color !== prev?.color) {
136+
stops.push(curr);
137+
}
138+
}
139+
140+
if (stops.length > 2 && stops[stops.length - 1].color === stops[stops.length - 2].color) {
141+
stops.splice(stops.length - 2, 1);
142+
}
164143

165144
result.push({
166-
name: `test${i}`,
145+
name: `gradient${i}`,
167146
value: {
168147
gradient: 'linear',
169148
...getGradientConfig(

src/plugins/explore/public/components/visualizations/bar_gauge/to_expression.ts

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
getBarOrientation,
1414
thresholdsToGradient,
1515
symbolOpposite,
16-
darkenColor,
1716
processThresholds,
1817
generateParams,
1918
} from './bar_gauge_utils';
@@ -76,29 +75,38 @@ export const createBarGaugeSpec = (
7675
}
7776
}
7877

79-
const validThresholds =
80-
styleOptions.thresholdOptions.thresholds?.filter(
78+
const validThresholds = [
79+
{ value: styleOptions?.min ?? 0, color: styleOptions.thresholdOptions.baseColor } as Threshold,
80+
...(styleOptions.thresholdOptions.thresholds?.filter(
8181
(t) =>
8282
t.value <= maxNumber &&
8383
t.value >= (styleOptions.min ?? 0) &&
8484
t.value <= (styleOptions.max ?? Infinity)
85-
) ?? [];
86-
const lastThreshold = validThresholds[validThresholds.length - 1];
85+
) ?? []),
86+
] as Threshold[];
87+
88+
// transfer value to threshold
89+
const valueToThreshold = [];
90+
91+
for (const record of newRecord) {
92+
for (let i = validThresholds.length - 1; i >= 0; i--) {
93+
if (numericField && record[numericField] >= validThresholds[i].value) {
94+
valueToThreshold.push({ value: record[numericField], color: validThresholds[i].color });
95+
break;
96+
}
97+
}
98+
}
99+
100+
// only use value-based thresholds in gradient mode
101+
const finalThreshold = styleOptions?.exclusive.displayMode === 'gradient' ? valueToThreshold : [];
87102

88-
// invalid case: max <= min and min > maxNumber, only show the base threshold
89103
const completeThreshold = [
90-
{ value: styleOptions?.min ?? 0, color: styleOptions.thresholdOptions.baseColor } as Threshold,
91104
...validThresholds,
92105
...((styleOptions?.max && styleOptions?.min && styleOptions.max <= styleOptions.min) ||
93106
(styleOptions?.min && styleOptions.min > maxNumber)
94107
? []
95-
: [
96-
{
97-
value: styleOptions.max ?? maxNumber,
98-
color: darkenColor(lastThreshold?.color ?? styleOptions.thresholdOptions.baseColor, 2),
99-
} as Threshold,
100-
]),
101-
];
108+
: finalThreshold),
109+
].sort((a, b) => a.value - b.value);
102110

103111
const processedThresholds = processThresholds(completeThreshold);
104112

@@ -107,14 +115,15 @@ export const createBarGaugeSpec = (
107115
const maxBase = styleOptions?.max ?? maxNumber;
108116
const minBase = styleOptions?.min ?? 0;
109117

110-
const scaleType =
111-
styleOptions.exclusive.displayMode === 'stack'
112-
? {
113-
scale: {
114-
domainMin: { expr: 'minBase' },
115-
},
116-
}
117-
: { domain: { expr: '[minBase,maxBase]' } };
118+
const invalidCase = minBase >= maxBase || minBase > maxNumber;
119+
120+
const scaleType = !invalidCase
121+
? {
122+
scale: {
123+
domainMin: { expr: 'minBase' },
124+
},
125+
}
126+
: {};
118127

119128
const params = [
120129
{ name: 'fontColor', value: getColors().text },
@@ -198,34 +207,32 @@ export const createBarGaugeSpec = (
198207
let expression = '';
199208

200209
for (let i = thresholds.length - 1; i >= 1; i--) {
201-
expression += `datum['${numericField}'] >= datum.threshold${i} ? test${i} : `;
210+
expression += `datum['${numericField}'] >= datum.threshold${i} ? gradient${i} : `;
202211
}
203212

204-
expression += `test0`;
213+
expression += `gradient0`;
205214

206215
return expression;
207216
};
208217

209218
let bars = [] as any;
210219

211220
// Handle invalid domain cases (minBase >= maxBase or minBase > maxNumber)
212-
// valid cases will not add the layer .
213-
if (minBase >= maxBase || minBase > maxNumber) {
221+
// invalid cases will not add the layer .
222+
if (invalidCase) {
214223
bars = [];
215224
} else if (styleOptions.exclusive.displayMode === 'stack') {
216-
// dispose the last threshold
217-
bars = processedThresholds.slice(0, -1)?.map((threshold, index) => {
225+
bars = processedThresholds.map((threshold, index) => {
218226
return {
219227
transform: [
220228
{ calculate: `datum.threshold${index}`, as: 'gradStart' },
221-
{ calculate: `datum.threshold${index + 1}`, as: 'gradEndTemp' },
222229
{
223-
calculate: `datum['${numericField}'] < datum.gradEndTemp ? datum['${numericField}']: datum.gradEndTemp`,
224-
as: 'gradEnd',
230+
calculate: `datum.threshold${index + 1}|| maxBase`,
231+
as: 'gradEndTemp',
225232
},
226233
{
227-
calculate: `datum['${numericField}'] < datum.gradEndTemp`,
228-
as: 'useSolidColor',
234+
calculate: `datum['${numericField}'] < datum.gradEndTemp ? datum['${numericField}']: datum.gradEndTemp`,
235+
as: 'gradEnd',
229236
},
230237
{ filter: `datum['${numericField}'] >= datum.threshold${index}` },
231238
],
@@ -253,7 +260,7 @@ export const createBarGaugeSpec = (
253260
} else if (styleOptions.exclusive.displayMode === 'gradient') {
254261
bars = [
255262
{
256-
mark: { type: 'bar' },
263+
mark: { type: 'bar', clip: true },
257264
transform: [
258265
{
259266
calculate: `datum['${numericField}']>=datum.maxVal?datum.maxVal:datum['${numericField}']`,
@@ -277,7 +284,7 @@ export const createBarGaugeSpec = (
277284
} else if (styleOptions.exclusive.displayMode === 'basic') {
278285
bars = [
279286
{
280-
mark: { type: 'bar' },
287+
mark: { type: 'bar', clip: true },
281288
transform: [
282289
{
283290
calculate: `datum['${numericField}']>=datum.maxVal?datum.maxVal:datum['${numericField}']`,
@@ -296,11 +303,8 @@ export const createBarGaugeSpec = (
296303
scale: {
297304
type: 'threshold',
298305
// last threshold which is just for max value capping in gradient mode
299-
domain: processedThresholds.map((t) => t.value).slice(0, -1),
300-
range: [
301-
getColors().backgroundShade,
302-
...processedThresholds.map((t) => t.color),
303-
].slice(0, -1),
306+
domain: processedThresholds.map((t) => t.value),
307+
range: [getColors().backgroundShade, ...processedThresholds.map((t) => t.color)],
304308
},
305309
legend: null,
306310
},
@@ -342,11 +346,8 @@ export const createBarGaugeSpec = (
342346
type: 'quantitative',
343347
scale: {
344348
type: 'threshold',
345-
domain: processedThresholds.map((t) => t.value).slice(0, -1),
346-
range: [getColors().backgroundShade, ...processedThresholds.map((t) => t.color)].slice(
347-
0,
348-
-1
349-
),
349+
domain: processedThresholds.map((t) => t.value),
350+
range: [getColors().backgroundShade, ...processedThresholds.map((t) => t.color)],
350351
},
351352
legend: null,
352353
},

0 commit comments

Comments
 (0)