in packages/charts/src/chart_types/bullet_graph/utils/color.ts [139:230]
function getScaleInputs(baseDomain: ContinuousDomain, config: BulletColorConfig, backgroundColor: Color): ScaleInputs {
if (!Array.isArray(config) || !isComplexConfig(config)) {
const { colors: rawColors, steps }: { colors: string[]; steps?: number | number[] } = !Array.isArray(config)
? config
: {
colors: config,
};
// TODO - fix thrown error for RGBA colors from storybook
const colors = rawColors.map((c) => c.toLowerCase());
if (colors.length === 1) {
// Adds second color
const [color] = colors;
// should always have color
if (color) {
const secondary = getChromaColor(color).alpha(0.7).hex();
const blendedSecondary = combineColors(colorToRgba(secondary), colorToRgba(backgroundColor));
colors.push(RGBATupleToString(blendedSecondary));
}
}
return {
colors,
steps,
};
}
if (!isComplexConfig(config)) {
return {
colors: config,
};
}
const getDomainPair = getDomainPairFn(baseDomain);
const { colors, boundedDomains } = config.reduce<{
boundedDomains: [number | null, number | null][];
colors: string[];
}>(
(acc, colorConfig) => {
if (typeof colorConfig === 'string') {
acc.colors.push(colorConfig);
} else {
acc.colors.push(colorConfig.color);
const domainPair = getDomainPair(colorConfig);
acc.boundedDomains.push(domainPair);
}
return acc;
},
{
boundedDomains: [],
colors: [],
},
);
let prevMax = -Infinity;
return boundedDomains.reduce<Required<ScaleInputs, 'colorBandDomain'>>(
(acc, [min, max], i) => {
// TODO: Add better error handling around this logic, the complex config right now assumes the following:
// - All ranges are ordered from min to max
// - All ranges are compatible with each other such that there is no overlapping or excluded ranges
// Ideally we validate the config and fix it the best we can based on what is provided, filling or clamping as needed
const testMinValue = isFiniteNumber(min) ? min : isFiniteNumber(max) ? max : null;
if (testMinValue === null || testMinValue < prevMax) {
Logger.warn(`Error with ColorBandComplexConfig:
Ranges are incompatible with each other such that there is either overlapping or excluded range pairs`);
return acc;
}
const newMaxValue = isFiniteNumber(max) ? max : isFiniteNumber(min) ? min : null;
if (newMaxValue === null) return acc;
prevMax = newMaxValue;
const color = colors[i] ?? Colors.Transparent.keyword;
if (isFiniteNumber(min)) {
acc.colorBandDomain.push(min);
acc.colors.push(color);
}
if (isFiniteNumber(max)) {
acc.colorBandDomain.push(max);
acc.colors.push(color);
}
return acc;
},
{
colorBandDomain: [],
colors: [],
},
);
}