parent
c14bf22836
commit
4e87720515
@ -0,0 +1,40 @@
|
|||||||
|
import {range} from 'd3-array';
|
||||||
|
import {scaleThreshold} from 'd3-scale';
|
||||||
|
import {gePalette, NULL_COLOR} from './utils';
|
||||||
|
|
||||||
|
const N_BINS = 5;
|
||||||
|
|
||||||
|
export default function colorBinsStyle ({ breaks, colors, nulltColor = NULL_COLOR }) {
|
||||||
|
let domain;
|
||||||
|
if (Array.isArray(breaks)) {
|
||||||
|
domain = breaks;
|
||||||
|
} else {
|
||||||
|
const {stats, method, bins = N_BINS} = breaks;
|
||||||
|
|
||||||
|
if (method === 'quantiles') {
|
||||||
|
const minQuantile = parseInt(Object.keys(stats.quantiles[0]), 10);
|
||||||
|
const maxQuantile = parseInt(Object.keys(stats.quantiles[stats.quantiles.length - 1]), 10);
|
||||||
|
if (bins < minQuantile || bins > maxQuantile) {
|
||||||
|
throw new Error(
|
||||||
|
`Invalid bins value. It shoud be between ${minQuantile} and ${maxQuantile}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const quantiles = stats.quantiles.find(d => d.hasOwnProperty(bins));
|
||||||
|
domain = quantiles[bins];
|
||||||
|
} else {
|
||||||
|
const {min, max} = stats;
|
||||||
|
const step = (max - min) / bins;
|
||||||
|
domain = range(min + step, max, step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const palette = typeof colors === 'string' ? gePalette(colors, domain.length + 1) : colors;
|
||||||
|
|
||||||
|
const color = scaleThreshold()
|
||||||
|
.domain(domain)
|
||||||
|
.range(palette);
|
||||||
|
|
||||||
|
return d => {
|
||||||
|
return d === (undefined || null) ? nulltColor : color(d);
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
import {gePalette, NULL_COLOR} from './utils';
|
||||||
|
|
||||||
|
const OTHERS_COLOR = [119, 119, 119];
|
||||||
|
const TOP = 10;
|
||||||
|
|
||||||
|
export default function colorCategoriesStyle ({
|
||||||
|
categories,
|
||||||
|
colors,
|
||||||
|
nulltColor = NULL_COLOR,
|
||||||
|
othersColor = OTHERS_COLOR
|
||||||
|
}) {
|
||||||
|
let categoryList;
|
||||||
|
const colorsByCategory = {};
|
||||||
|
|
||||||
|
if (Array.isArray(categories)) {
|
||||||
|
categoryList = categories;
|
||||||
|
} else {
|
||||||
|
const {stats, top = TOP} = categories;
|
||||||
|
categoryList = stats.categories.map(c => c.category).slice(0, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
const palette = typeof colors === 'string' ? gePalette(colors, categoryList.length) : colors;
|
||||||
|
|
||||||
|
for (const [i, c] of categoryList.entries()) {
|
||||||
|
colorsByCategory[c] = palette[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return d => {
|
||||||
|
return d === (undefined || null) ? nulltColor : colorsByCategory[d] || othersColor;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
import * as cartoColors from 'cartocolor';
|
||||||
|
|
||||||
|
export const NULL_COLOR = [204, 204, 204];
|
||||||
|
|
||||||
|
export function gePalette (name, numCategories) {
|
||||||
|
const palette = cartoColors[name];
|
||||||
|
let paletteIndex = numCategories;
|
||||||
|
|
||||||
|
if (!palette) {
|
||||||
|
throw new Error(`Palette ${name} is not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const palettesColorVariants = Object.keys(palette)
|
||||||
|
.filter(p => p !== 'tags')
|
||||||
|
.map(Number);
|
||||||
|
|
||||||
|
const longestPaletteIndex = Math.max(...palettesColorVariants);
|
||||||
|
const smallestPaletteIndex = Math.min(...palettesColorVariants);
|
||||||
|
|
||||||
|
if (!Number.isInteger(numCategories) || numCategories > longestPaletteIndex) {
|
||||||
|
paletteIndex = longestPaletteIndex;
|
||||||
|
} else if (numCategories < smallestPaletteIndex) {
|
||||||
|
paletteIndex = smallestPaletteIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const colors = palette[paletteIndex];
|
||||||
|
|
||||||
|
if (palette.tags && palette.tags.includes('qualitative')) {
|
||||||
|
colors.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors.map(c => hexToRgb(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
function hexToRgb (hex) {
|
||||||
|
// Evaluate #ABC
|
||||||
|
let result = /^#?([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(hex);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return [
|
||||||
|
parseInt(result[1] + result[1], 16),
|
||||||
|
parseInt(result[2] + result[2], 16),
|
||||||
|
parseInt(result[3] + result[3], 16),
|
||||||
|
255
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate #ABCD
|
||||||
|
result = /^#?([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(hex);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return [
|
||||||
|
parseInt(result[1] + result[1], 16),
|
||||||
|
parseInt(result[2] + result[2], 16),
|
||||||
|
parseInt(result[3] + result[3], 16),
|
||||||
|
parseInt(result[4] + result[4], 16)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate #ABCDEF
|
||||||
|
result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16), 255];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate #ABCDEFAF
|
||||||
|
result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return [
|
||||||
|
parseInt(result[1], 16),
|
||||||
|
parseInt(result[2], 16),
|
||||||
|
parseInt(result[3], 16),
|
||||||
|
parseInt(result[4], 16)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Error parsing hexadecimal color: ${hex}`);
|
||||||
|
}
|
Loading…
Reference in new issue