Trace View: Disallow a span colour that is the same or looks similar to previous colour (#58146)

* Disallow sequential spans with the same color

* Disallow same prev color and similar color

* Tests

* Remove assignemnt
This commit is contained in:
Joey Tawadrous 2022-11-30 15:14:58 +00:00 committed by GitHub
parent 6d6cb0a478
commit 3b53fdb53a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 3 deletions

View File

@ -26,7 +26,7 @@ it('gives the same color for the same key', () => {
expect(colorOne).toBe(colorTwo);
});
it('gives different colors for each for each key', () => {
it('gives different colors for each key', () => {
clear();
const colorOne = getColorByKey('serviceA', createTheme());
const colorTwo = getColorByKey('serviceB', createTheme());
@ -35,8 +35,10 @@ it('gives different colors for each for each key', () => {
it('should not allow red', () => {
expect(colorsToFilter.indexOf('#E24D42')).toBe(4);
expect(colorsToFilter.indexOf('#BF1B00')).toBe(28);
const filteredColors = getFilteredColors(colorsToFilter, createTheme());
expect(filteredColors.indexOf('#E24D42')).toBe(-1);
expect(filteredColors.indexOf('#BF1B00')).toBe(-1);
});
it('should not allow colors with a contrast ratio < 3 in light mode', () => {
@ -54,3 +56,23 @@ it('should not allow colors with a contrast ratio < 3 in dark mode', () => {
expect(filteredColors.indexOf('#890F02')).toBe(-1);
expect(filteredColors.indexOf('#0A437C')).toBe(-1);
});
it('should not allow a color that is the same as the previous color', () => {
clear();
const theme = createTheme();
const colorOne = getColorByKey('random4', theme); // #447EBC
const colorTwo = getColorByKey('random17', theme); // #447EBC
expect(colorOne).not.toBe(colorTwo);
expect(colorOne).toBe('#447EBC');
expect(colorTwo).toBe('#B7DBAB');
});
it('should not allow a color that looks similar to the previous color', () => {
clear();
const theme = createTheme({ colors: { mode: 'light' } });
const colorOne = getColorByKey('random9', theme); // #58140C
const colorTwo = getColorByKey('random18', theme); // #511749
expect(colorOne).toBe('#58140C');
// #1F78C1 is the next color that has a contrast ratio >= 3 for the current theme
expect(colorTwo).toBe('#1F78C1');
});

View File

@ -45,13 +45,40 @@ class ColorGenerator {
let i = this.cache.get(key);
if (i == null) {
const hash = this.hashCode(key.toLowerCase());
const hashIndex = Math.abs(hash % this.colorsHex.length);
i = hashIndex === 4 ? hashIndex + 1 : hashIndex;
i = Math.abs(hash % this.colorsHex.length);
const prevCacheItem = Array.from(this.cache).pop();
if (prevCacheItem && prevCacheItem[1]) {
// disallow a color that is the same as the previous color
if (prevCacheItem[1] === i) {
i = this.getNextIndex(i);
}
// disallow a color that looks very similar to the previous color
const prevColor = this.colorsHex[prevCacheItem[1]];
if (tinycolor.readability(prevColor, this.colorsHex[i]) < 1.5) {
let newIndex = i;
for (let j = 0; j < this.colorsHex.length; j++) {
newIndex = this.getNextIndex(newIndex);
if (tinycolor.readability(prevColor, this.colorsHex[newIndex]) > 1.5) {
i = newIndex;
break;
}
}
}
}
this.cache.set(key, i);
}
return i;
}
getNextIndex(i: number) {
// get next index or go back to 0
return i + 1 < this.colorsHex.length ? i + 1 : 0;
}
hashCode(key: string) {
let hash = 0,
i,
@ -110,6 +137,10 @@ export function getFilteredColors(colorsHex: string[], theme: GrafanaTheme2) {
if (redIndex > -1) {
colorsHex.splice(redIndex, 1);
}
const redIndex2 = colorsHex.indexOf('#BF1B00');
if (redIndex2 > -1) {
colorsHex.splice(redIndex2, 1);
}
// Only add colors that have a contrast ratio >= 3 for the current theme
let filteredColors = [];