@swimlane/ngx-charts
Version:
Declarative Charting Framework for Angular
145 lines • 17.8 kB
JavaScript
import { range } from 'd3-array';
import { scaleBand, scaleLinear, scaleOrdinal, scaleQuantile } from 'd3-scale';
import { colorSets } from '../utils/color-sets';
import { ScaleType } from './types/scale-type.enum';
export class ColorHelper {
constructor(scheme, type, domain, customColors) {
if (typeof scheme === 'string') {
scheme = colorSets.find(cs => {
return cs.name === scheme;
});
}
this.colorDomain = scheme.domain;
this.scaleType = type;
this.domain = domain;
this.customColors = customColors;
this.scale = this.generateColorScheme(scheme, type, this.domain);
}
generateColorScheme(scheme, type, domain) {
if (typeof scheme === 'string') {
scheme = colorSets.find(cs => {
return cs.name === scheme;
});
}
let colorScale;
switch (type) {
case ScaleType.Quantile:
colorScale = scaleQuantile()
.range(scheme.domain)
.domain(domain);
break;
case ScaleType.Ordinal:
colorScale = scaleOrdinal()
.range(scheme.domain)
.domain(domain);
break;
case ScaleType.Linear:
{
const colorDomain = [...scheme.domain];
if (colorDomain.length === 1) {
colorDomain.push(colorDomain[0]);
this.colorDomain = colorDomain;
}
const points = range(0, 1, 1.0 / colorDomain.length);
colorScale = scaleLinear()
.range(colorDomain)
.domain(points);
}
break;
default:
break;
}
return colorScale;
}
getColor(value) {
if (value === undefined || value === null) {
throw new Error('Value can not be null');
}
if (this.scaleType === ScaleType.Linear) {
const valueScale = scaleLinear()
.domain(this.domain)
.range([0, 1]);
return this.scale(valueScale(value));
}
else {
if (typeof this.customColors === 'function') {
return this.customColors(value);
}
const formattedValue = value.toString();
let found; // todo type customColors
if (this.customColors && this.customColors.length > 0) {
found = this.customColors.find(mapping => {
return mapping.name.toLowerCase() === formattedValue.toLowerCase();
});
}
if (found) {
return found.value;
}
else {
return this.scale(value);
}
}
}
getLinearGradientStops(value, start) {
if (start === undefined) {
start = this.domain[0];
}
const valueScale = scaleLinear()
.domain(this.domain)
.range([0, 1]);
const colorValueScale = scaleBand().domain(this.colorDomain).range([0, 1]);
const endColor = this.getColor(value);
// generate the stops
const startVal = valueScale(start);
const startColor = this.getColor(start);
const endVal = valueScale(value);
let i = 1;
let currentVal = startVal;
const stops = [];
stops.push({
color: startColor,
offset: startVal,
originalOffset: startVal,
opacity: 1
});
while (currentVal < endVal && i < this.colorDomain.length) {
const color = this.colorDomain[i];
const offset = colorValueScale(color);
if (offset <= startVal) {
i++;
continue;
}
if (offset.toFixed(4) >= (endVal - colorValueScale.bandwidth()).toFixed(4)) {
break;
}
stops.push({
color,
offset,
opacity: 1
});
currentVal = offset;
i++;
}
if (stops[stops.length - 1].offset < 100) {
stops.push({
color: endColor,
offset: endVal,
opacity: 1
});
}
if (endVal === startVal) {
stops[0].offset = 0;
stops[1].offset = 100;
}
else {
// normalize the offsets into percentages
if (stops[stops.length - 1].offset !== 100) {
for (const s of stops) {
s.offset = ((s.offset - startVal) / (endVal - startVal)) * 100;
}
}
}
return stops;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3IuaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3dpbWxhbmUvbmd4LWNoYXJ0cy9zcmMvbGliL2NvbW1vbi9jb2xvci5oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLEVBQ0wsU0FBUyxFQUVULFdBQVcsRUFFWCxZQUFZLEVBRVosYUFBYSxFQUNkLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE9BQU8sRUFBUyxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHcEQsTUFBTSxPQUFPLFdBQVc7SUFPdEIsWUFBWSxNQUFzQixFQUFFLElBQWUsRUFBRSxNQUEyQixFQUFFLFlBQWE7UUFDN0YsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7WUFDOUIsTUFBTSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQzNCLE9BQU8sRUFBRSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUM7U0FDSjtRQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNqQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUVqQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsTUFBc0IsRUFBRSxJQUFlLEVBQUUsTUFBMkI7UUFDdEYsSUFB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TSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDO2lCQUNoRTthQUNGO1NBQ0Y7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmdlIH0gZnJvbSAnZDMtYXJyYXknO1xuaW1wb3J0IHtcbiAgc2NhbGVCYW5kLFxuICBTY2FsZUxpbmVhcixcbiAgc2NhbGVMaW5lYXIsXG4gIFNjYWxlT3JkaW5hbCxcbiAgc2NhbGVPcmRpbmFsLFxuICBTY2FsZVF1YW50aWxlLFxuICBzY2FsZVF1YW50aWxlXG59IGZyb20gJ2QzLXNjYWxlJztcblxuaW1wb3J0IHsgQ29sb3IsIGNvbG9yU2V0cyB9IGZyb20gJy4uL3V0aWxzL2NvbG9yLXNldHMnO1xuaW1wb3J0IHsgU3RyaW5nT3JOdW1iZXJPckRhdGUgfSBmcm9tICcuLi9tb2RlbHMvY2hhcnQtZGF0YS5tb2RlbCc7XG5pbXBvcnQgeyBTY2FsZVR5cGUgfSBmcm9tICcuL3R5cGVzL3NjYWxlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBHcmFkaWVudCB9IGZyb20gJy4vdHlwZXMvZ3JhZGllbnQuaW50ZXJmYWNlJztcblxuZXhwb3J0IGNsYXNzIENvbG9ySGVscGVyIHtcbiAgc2NhbGU6IGFueTtcbiAgc2NhbGVUeXBlOiBTY2FsZVR5cGU7XG4gIGNvbG9yRG9tYWluOiBzdHJpbmdbXTtcbiAgZG9tYWluOiBudW1iZXJbXSB8IHN0cmluZ1tdO1xuICBjdXN0b21Db2xvcnM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihzY2hlbWU6IHN0cmluZyB8IENvbG9yLCB0eXBlOiBTY2FsZVR5cGUsIGRvbWFpbjogbnVtYmVyW10gfCBzdHJpbmdbXSwgY3VzdG9tQ29sb3JzPykge1xuICAgIGlmICh0eXBlb2Ygc2NoZW1lID09PSAnc3RyaW5nJykge1xuICAgICAgc2NoZW1lID0gY29sb3JTZXRzLmZpbmQoY3MgPT4ge1xuICAgICAgICByZXR1cm4gY3MubmFtZSA9PT0gc2NoZW1lO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuY29sb3JEb21haW4gPSBzY2hlbWUuZG9tYWluO1xuICAgIHRoaXMuc2NhbGVUeXBlID0gdHlwZTtcbiAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbjtcbiAgICB0aGlzLmN1c3RvbUNvbG9ycyA9IGN1c3RvbUNvbG9ycztcblxuICAgIHRoaXMuc2NhbGUgPSB0aGlzLmdlbmVyYXRlQ29sb3JTY2hlbWUoc2NoZW1lLCB0eXBlLCB0aGlzLmRvbWFpbik7XG4gIH1cblxuICBnZW5lcmF0ZUNvbG9yU2NoZW1lKHNjaGVtZTogc3RyaW5nIHwgQ29sb3IsIHR5cGU6IFNjYWxlVHlwZSwgZG9tYWluOiBudW1iZXJbXSB8IHN0cmluZ1tdKTogYW55IHtcbiAgICBpZiAodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHNjaGVtZSA9IGNvbG9yU2V0cy5maW5kKGNzID0+IHtcbiAgICAgICAgcmV0dXJuIGNzLm5hbWUgPT09IHNjaGVtZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCBjb2xvclNjYWxlOiBTY2FsZVF1YW50aWxlPG51bWJlcj4gfCBTY2FsZU9yZGluYWw8c3RyaW5nLCB1bmtub3duPiB8IFNjYWxlTGluZWFyPG51bWJlciwgbnVtYmVyPjtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgU2NhbGVUeXBlLlF1YW50aWxlOlxuICAgICAgICBjb2xvclNjYWxlID0gc2NhbGVRdWFudGlsZSgpXG4gICAgICAgICAgLnJhbmdlKHNjaGVtZS5kb21haW4gYXMgYW55KVxuICAgICAgICAgIC5kb21haW4oZG9tYWluIGFzIG51bWJlcltdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFNjYWxlVHlwZS5PcmRpbmFsOlxuICAgICAgICBjb2xvclNjYWxlID0gc2NhbGVPcmRpbmFsKClcbiAgICAgICAgICAucmFuZ2Uoc2NoZW1lLmRvbWFpbilcbiAgICAgICAgICAuZG9tYWluKGRvbWFpbiBhcyBzdHJpbmdbXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTY2FsZVR5cGUuTGluZWFyOlxuICAgICAgICB7XG4gICAgICAgICAgY29uc3QgY29sb3JEb21haW4gPSBbLi4uc2NoZW1lLmRvbWFpbl07XG4gICAgICAgICAgaWYgKGNvbG9yRG9tYWluLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgY29sb3JEb21haW4ucHVzaChjb2xvckRvbWFpblswXSk7XG4gICAgICAgICAgICB0aGlzLmNvbG9yRG9tYWluID0gY29sb3JEb21haW47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcG9pbnRzID0gcmFuZ2UoMCwgMSwgMS4wIC8gY29sb3JEb21haW4ubGVuZ3RoKTtcbiAgICAgICAgICBjb2xvclNjYWxlID0gc2NhbGVMaW5lYXIoKVxuICAgICAgICAgICAgLnJhbmdlKGNvbG9yRG9tYWluIGFzIGFueSlcbiAgICAgICAgICAgIC5kb21haW4ocG9pbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBjb2xvclNjYWxlO1xuICB9XG5cbiAgZ2V0Q29sb3IodmFsdWU6IFN0cmluZ09yTnVtYmVyT3JEYXRlKTogc3RyaW5nIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWYWx1ZSBjYW4gbm90IGJlIG51bGwnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2NhbGVUeXBlID09PSBTY2FsZVR5cGUuTGluZWFyKSB7XG4gICAgICBjb25zdCB2YWx1ZVNjYWxlID0gc2NhbGVMaW5lYXIoKVxuICAgICAgICAuZG9tYWluKHRoaXMuZG9tYWluIGFzIG51bWJlcltdKVxuICAgICAgICAucmFuZ2UoWzAsIDFdKTtcblxuICAgICAgcmV0dXJuIHRoaXMuc2NhbGUodmFsdWVTY2FsZSh2YWx1ZSBhcyBudW1iZXIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLmN1c3RvbUNvbG9ycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXN0b21Db2xvcnModmFsdWUpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICBsZXQgZm91bmQ6IGFueTsgLy8gdG9kbyB0eXBlIGN1c3RvbUNvbG9yc1xuICAgICAgaWYgKHRoaXMuY3VzdG9tQ29sb3JzICYmIHRoaXMuY3VzdG9tQ29sb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm91bmQgPSB0aGlzLmN1c3RvbUNvbG9ycy5maW5kKG1hcHBpbmcgPT4ge1xuICAgICAgICAgIHJldHVybiBtYXBwaW5nLm5hbWUudG9Mb3dlckNhc2UoKSA9PT0gZm9ybWF0dGVkVmFsdWUudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICByZXR1cm4gZm91bmQudmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5zY2FsZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0TGluZWFyR3JhZGllbnRTdG9wcyh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nLCBzdGFydD86IG51bWJlciB8IHN0cmluZyk6IEdyYWRpZW50W10ge1xuICAgIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzdGFydCA9IHRoaXMuZG9tYWluWzBdO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZVNjYWxlID0gc2NhbGVMaW5lYXIoKVxuICAgICAgLmRvbWFpbih0aGlzLmRvbWFpbiBhcyBudW1iZXJbXSlcbiAgICAgIC5yYW5nZShbMCwgMV0pO1xuXG4gICAgY29uc3QgY29sb3JWYWx1ZVNjYWxlID0gc2NhbGVCYW5kKCkuZG9tYWluKHRoaXMuY29sb3JEb21haW4pLnJhbmdlKFswLCAxXSk7XG5cbiAgICBjb25zdCBlbmRDb2xvciA9IHRoaXMuZ2V0Q29sb3IodmFsdWUpO1xuXG4gICAgLy8gZ2VuZXJhdGUgdGhlIHN0b3BzXG4gICAgY29uc3Qgc3RhcnRWYWwgPSB2YWx1ZVNjYWxlKHN0YXJ0IGFzIG51bWJlcik7XG4gICAgY29uc3Qgc3RhcnRDb2xvciA9IHRoaXMuZ2V0Q29sb3Ioc3RhcnQpO1xuXG4gICAgY29uc3QgZW5kVmFsID0gdmFsdWVTY2FsZSh2YWx1ZSBhcyBudW1iZXIpO1xuICAgIGxldCBpID0gMTtcbiAgICBsZXQgY3VycmVudFZhbCA9IHN0YXJ0VmFsO1xuICAgIGNvbnN0IHN0b3BzOiBHcmFkaWVudFtdID0gW107XG5cbiAgICBzdG9wcy5wdXNoKHtcbiAgICAgIGNvbG9yOiBzdGFydENvbG9yLFxuICAgICAgb2Zmc2V0OiBzdGFydFZhbCxcbiAgICAgIG9yaWdpbmFsT2Zmc2V0OiBzdGFydFZhbCxcbiAgICAgIG9wYWNpdHk6IDFcbiAgICB9KTtcblxuICAgIHdoaWxlIChjdXJyZW50VmFsIDwgZW5kVmFsICYmIGkgPCB0aGlzLmNvbG9yRG9tYWluLmxlbmd0aCkge1xuICAgICAgY29uc3QgY29sb3IgPSB0aGlzLmNvbG9yRG9tYWluW2ldO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gY29sb3JWYWx1ZVNjYWxlKGNvbG9yKTtcbiAgICAgIGlmIChvZmZzZXQgPD0gc3RhcnRWYWwpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9mZnNldC50b0ZpeGVkKDQpID49IChlbmRWYWwgLSBjb2xvclZhbHVlU2NhbGUuYmFuZHdpZHRoKCkpLnRvRml4ZWQoNCkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHN0b3BzLnB1c2goe1xuICAgICAgICBjb2xvcixcbiAgICAgICAgb2Zmc2V0LFxuICAgICAgICBvcGFjaXR5OiAxXG4gICAgICB9KTtcbiAgICAgIGN1cnJlbnRWYWwgPSBvZmZzZXQ7XG4gICAgICBpKys7XG4gICAgfVxuXG4gICAgaWYgKHN0b3BzW3N0b3BzLmxlbmd0aCAtIDFdLm9mZnNldCA8IDEwMCkge1xuICAgICAgc3RvcHMucHVzaCh7XG4gICAgICAgIGNvbG9yOiBlbmRDb2xvcixcbiAgICAgICAgb2Zmc2V0OiBlbmRWYWwsXG4gICAgICAgIG9wYWNpdHk6IDFcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChlbmRWYWwgPT09IHN0YXJ0VmFsKSB7XG4gICAgICBzdG9wc1swXS5vZmZzZXQgPSAwO1xuICAgICAgc3RvcHNbMV0ub2Zmc2V0ID0gMTAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3JtYWxpemUgdGhlIG9mZnNldHMgaW50byBwZXJjZW50YWdlc1xuICAgICAgaWYgKHN0b3BzW3N0b3BzLmxlbmd0aCAtIDFdLm9mZnNldCAhPT0gMTAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgcyBvZiBzdG9wcykge1xuICAgICAgICAgIHMub2Zmc2V0ID0gKChzLm9mZnNldCAtIHN0YXJ0VmFsKSAvIChlbmRWYWwgLSBzdGFydFZhbCkpICogMTAwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0b3BzO1xuICB9XG59XG4iXX0=