feat(legacy-plugin-chart-calendar): increase the contrast of calendar heatmap color and label (#1452)
* feat(legacy-plugin-chart-calendar): increasecontrast of calendar heatmap * rename getContrastingColor and put it core * fix: unit test
This commit is contained in:
parent
259ff67ef7
commit
a71d3caa6c
|
|
@ -27,5 +27,6 @@ export { default as getSequentialSchemeRegistry } from './SequentialSchemeRegist
|
|||
export { default as SequentialScheme } from './SequentialScheme';
|
||||
export { default as ColorSchemeRegistry } from './ColorSchemeRegistry';
|
||||
export * from './colorSchemes';
|
||||
export * from './utils';
|
||||
|
||||
export const BRAND_COLOR = '#00A699';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
const rgbRegex = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/;
|
||||
export function getContrastingColor(color: string, thresholds = 186) {
|
||||
let r = 0;
|
||||
let g = 0;
|
||||
let b = 0;
|
||||
if (color.length > 7) {
|
||||
// rgb
|
||||
const matchColor = rgbRegex.exec(color);
|
||||
if (!matchColor) {
|
||||
throw new Error(`Invalid color: ${color}`);
|
||||
}
|
||||
r = parseInt(matchColor[1], 10);
|
||||
g = parseInt(matchColor[2], 10);
|
||||
b = parseInt(matchColor[3], 10);
|
||||
} else {
|
||||
// hex
|
||||
let hex = color;
|
||||
if (hex.startsWith('#')) {
|
||||
hex = hex.substring(1);
|
||||
}
|
||||
// #FFF
|
||||
if (hex.length === 3) {
|
||||
hex = [hex[0], hex[0], hex[1], hex[1], hex[2], hex[2]].join('');
|
||||
}
|
||||
if (hex.length !== 6) {
|
||||
throw new Error(`Invalid color: ${color}`);
|
||||
}
|
||||
r = parseInt(hex.slice(0, 2), 16);
|
||||
g = parseInt(hex.slice(2, 4), 16);
|
||||
b = parseInt(hex.slice(4, 6), 16);
|
||||
}
|
||||
|
||||
return r * 0.299 + g * 0.587 + b * 0.114 > thresholds ? '#000' : '#FFF';
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { getContrastingColor } from '@superset-ui/core/src/color';
|
||||
|
||||
describe('color utils', () => {
|
||||
describe('getContrastingColor', () => {
|
||||
it('when called with 3-digit hex color', () => {
|
||||
const color = getContrastingColor('#000');
|
||||
expect(color).toBe('#FFF');
|
||||
});
|
||||
|
||||
it('when called with 6-digit hex color', () => {
|
||||
const color = getContrastingColor('#000000');
|
||||
expect(color).toBe('#FFF');
|
||||
});
|
||||
|
||||
it('when called with no # prefix hex color', () => {
|
||||
const color = getContrastingColor('000000');
|
||||
expect(color).toBe('#FFF');
|
||||
});
|
||||
|
||||
it('when called with rgb color', () => {
|
||||
const color = getContrastingColor('rgb(0, 0, 0)');
|
||||
expect(color).toBe('#FFF');
|
||||
});
|
||||
|
||||
it('when called with thresholds', () => {
|
||||
const color1 = getContrastingColor('rgb(255, 255, 255)');
|
||||
const color2 = getContrastingColor('rgb(255, 255, 255)', 255);
|
||||
expect(color1).toBe('#000');
|
||||
expect(color2).toBe('#FFF');
|
||||
});
|
||||
|
||||
it('when called with rgba color, throw error', () => {
|
||||
expect(() => {
|
||||
getContrastingColor('rgba(0, 0, 0, 0.1)');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('when called with invalid color, throw error', () => {
|
||||
expect(() => {
|
||||
getContrastingColor('#0000');
|
||||
}).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
.cal-heatmap-container .subdomain-text {
|
||||
font-size: 8px;
|
||||
fill: #999;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
/* eslint-disable */
|
||||
|
||||
import d3tip from 'd3-tip';
|
||||
import { getContrastingColor } from '@superset-ui/core';
|
||||
import './d3tip.css';
|
||||
|
||||
var d3 = typeof require === 'function' ? require('d3') : window.d3;
|
||||
|
|
@ -1664,7 +1665,12 @@ CalHeatMap.prototype = {
|
|||
.attr('class', function (d) {
|
||||
return 'subdomain-text' + parent.getHighlightClassName(d.t);
|
||||
})
|
||||
.call(formatSubDomainText);
|
||||
.call(formatSubDomainText)
|
||||
.attr('fill', d => {
|
||||
if (!d.v) return '#000';
|
||||
const rgb = parent.legendScale(Math.min(d.v, options.legend[options.legend.length - 1]));
|
||||
return getContrastingColor(rgb, 135);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue