/** @license * * Colour Palette Generator script. * Copyright (c) 2014 Google Inc. * * Licensed 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. * * Furthermore, ColorBrewer colour schemes are covered by the following: * * Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and * The Pennsylvania State University. * * Licensed 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. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1. Redistributions as source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: "This product includes color * specifications and designs developed by Cynthia Brewer * (http://colorbrewer.org/)." Alternately, this acknowledgment may appear * in the software itself, if and wherever such third-party * acknowledgments normally appear. * * 4. The name "ColorBrewer" must not be used to endorse or promote products * derived from this software without prior written permission. For written * permission, please contact Cynthia Brewer at cbrewer@psu.edu. * * 5. Products derived from this software may not be called "ColorBrewer", * nor may "ColorBrewer" appear in their name, without prior written * permission of Cynthia Brewer. * * Furthermore, Solarized colour schemes are covered by the following: * * Copyright (c) 2011 Ethan Schoonover * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 'use strict'; var palette = (function() { var proto = Array.prototype; var slice = function(arr, opt_begin, opt_end) { return proto.slice.apply(arr, proto.slice.call(arguments, 1)); }; var extend = function(arr, arr2) { return proto.push.apply(arr, arr2); }; var function_type = typeof function() {}; var INF = 1000000000; // As far as we're concerned, that's infinity. ;) /** * Generate a colour palette from given scheme. * * If scheme argument is not a function it is passed to palettes.listSchemes * function (along with the number argument). This may result in an array * of more than one available scheme. If that is the case, scheme at * opt_index position is taken. * * This allows using different palettes for different data without having to * name the schemes specifically, for example: * * palette_for_foo = palette('sequential', 10, 0); * palette_for_bar = palette('sequential', 10, 1); * palette_for_baz = palette('sequential', 10, 2); * * @param {!palette.SchemeType|string|palette.Palette} scheme Scheme to * generate palette for. Either a function constructed with * palette.Scheme object, or anything that palette.listSchemes accepts * as name argument. * @param {number} number Number of colours to return. If negative, absolute * value is taken and colours will be returned in reverse order. * @param {number=} opt_index If scheme is a name of a group or an array and * results in more than one scheme, index of the scheme to use. The * index wraps around. * @param {...*} varargs Additional arguments to pass to palette or colour * generator (if the chosen scheme uses those). * @return {Array} Array of abs(number) 'RRGGBB' strings or null if * no matching scheme was found. */ var palette = function(scheme, number, opt_index, varargs) { number |= 0; if (number == 0) { return []; } if (typeof scheme !== function_type) { var arr = palette.listSchemes( /** @type {string|palette.Palette} */ (scheme), number); if (!arr.length) { return null; } scheme = arr[(opt_index || 0) % arr.length]; } var args = slice(arguments, 2); args[0] = number; return scheme.apply(scheme, args); }; /** * Returns a callable colour scheme object. * * Just after being created, the scheme has no colour palettes and no way of * generating any, thus generate method will return null. To turn scheme * into a useful object, addPalette, addPalettes or setColorFunction methods * need to be used. * * To generate a colour palette with given number colours using function * returned by this method, just call it with desired number of colours. * * Since this function *returns* a callable object, it must *not* be used * with the new operator. * * @param {string} name Name of the scheme. * @param {string|!Array=} opt_groups A group name or list of * groups the scheme should be categorised under. Three typical groups * to use are 'qualitative', 'sequential' and 'diverging', but any * groups may be created. * @return {!palette.SchemeType} A colour palette generator function, which * in addition has methods and properties like a regular object. Think * of it as a callable object. */ palette.Scheme = function(name, opt_groups) { /** * A map from a number to a colour palettes with given number of colours. * @type {!Object} */ var palettes = {}; /** * The biggest palette in palettes map. * @type {number} */ var palettes_max = 0; /** * The smallest palette in palettes map. * @type {number} */ var palettes_min = INF; var makeGenerator = function() { if (arguments.length <= 1) { return self.color_func.bind(self); } else { var args = slice(arguments); return function(x) { args[0] = x; return self.color_func.apply(self, args); }; } }; /** * Generate a colour palette from the scheme. * * If there was a palette added with addPalette (or addPalettes) with * enough colours, that palette will be used. Otherwise, if colour * function has been set using setColorFunction method, that function will * be used to generate the palette. Otherwise null is returned. * * @param {number} number Number of colours to return. If negative, * absolute value is taken and colours will be returned in reverse * order. * @param {...*} varargs Additional arguments to pass to palette or colour * generator (if the chosen scheme uses those). */ var self = function(number, varargs) { number |= 0; if (!number) { return []; } var _number = number; number = Math.abs(number); if (number <= palettes_max) { for (var i = Math.max(number, palettes_min); !(i in palettes); ++i) { /* nop */ } var colors = palettes[i]; if (i > number) { var take_head = 'shrinking_takes_head' in colors ? colors.shrinking_takes_head : self.shrinking_takes_head; if (take_head) { colors = colors.slice(0, number); i = number; } else { return palette.generate( function(x) { return colors[Math.round(x)]; }, _number, 0, colors.length - 1); } } colors = colors.slice(); if (_number < 0) { colors.reverse(); } return colors; } else if (self.color_func) { return palette.generate(makeGenerator.apply(self, arguments), _number, 0, 1, self.color_func_cyclic); } else { return null; } }; /** * The name of the palette. * @type {string} */ self.scheme_name = name; /** * A list of groups the palette belongs to. * @type {!Array} */ self.groups = opt_groups ? typeof opt_groups === 'string' ? [opt_groups] : opt_groups : []; /** * The biggest palette this scheme can generate. * @type {number} */ self.max = 0; /** * The biggest palette this scheme can generate that is colour-blind * friendly. * @type {number} */ self.cbf_max = INF; /** * Adds a colour palette to the colour scheme. * * @param {palette.Palette} palette An array of 'RRGGBB' strings * representing the palette to add. * @param {boolean=} opt_is_cbf Whether the palette is colourblind friendly. */ self.addPalette = function(palette, opt_is_cbf) { var len = palette.length; if (len) { palettes[len] = palette; palettes_min = Math.min(palettes_min, len); palettes_max = Math.max(palettes_max, len); self.max = Math.max(self.max, len); if (!opt_is_cbf && len != 1) { self.cbf_max = Math.min(self.cbf_max, len - 1); } } }; /** * Adds number of colour palettes to the colour scheme. * * @param {palette.PalettesList} palettes A map or an array of colour * palettes to add. If map, i.e. object, is used, properties should * use integer property names. * @param {number=} opt_max Size of the biggest palette in palettes set. * If not set, palettes must have a length property which will be used. * @param {number=} opt_cbf_max Size of the biggest palette which is still * colourblind friendly. 1 by default. */ self.addPalettes = function(palettes, opt_max, opt_cbf_max) { opt_max = opt_max || palettes.length; for (var i = 0; i < opt_max; ++i) { if (i in palettes) { self.addPalette(palettes[i], true); } } self.cbf_max = Math.min(self.cbf_max, opt_cbf_max || 1); }; /** * Enable shrinking palettes taking head of the list of colours. * * When user requests n-colour palette but the smallest palette added with * addPalette (or addPalettes) is m-colour one (where n < m), n colours * across the palette will be returned. For example: * var ex = palette.Scheme('ex'); * ex.addPalette(['000000', 'bcbcbc', 'ffffff']); * var pal = ex(2); * // pal == ['000000', 'ffffff'] * * This works for palettes where the distance between colours is * correlated to distance in the palette array, which is true in gradients * such as the one above. * * To turn this feature off shrinkByTakingHead can be set to true either * for all palettes in the scheme (if opt_idx is not given) or for palette * with given number of colours only. In general, setting the option for * given palette overwrites whatever has been set for the scheme. The * default, as described above, is false. * * Alternatively, the feature can be enabled by setting shrinking_takes_head * property for the palette Array or the scheme object. * * For example, all of the below give equivalent results: * var pal = ['ff0000', '00ff00', '0000ff']; * * var ex = palette.Scheme('ex'); * ex.addPalette(pal); // ex(2) == ['ff0000', '0000ff'] * ex.shrinkByTakingHead(true); // ex(2) == ['ff0000', '00ff00'] * * ex = palette.Scheme('ex'); * ex.addPalette(pal); // ex(2) == ['ff0000', '0000ff'] * ex.shrinkByTakingHead(true, 3); // ex(2) == ['ff0000', '00ff00'] * * ex = palette.Scheme('ex'); * ex.addPalette(pal); * ex.addPalette(pal); // ex(2) == ['ff0000', '0000ff'] * pal.shrinking_takes_head = true; // ex(2) == ['ff0000', '00ff00'] * * @param {boolean} enabled Whether to enable or disable the “shrinking * takes head” feature. It is disabled by default. * @param {number=} opt_idx If given, the “shrinking takes head” option * for palette with given number of colours is set. If such palette * does not exist, nothing happens. */ self.shrinkByTakingHead = function(enabled, opt_idx) { if (opt_idx !== void(0)) { if (opt_idx in palettes) { palettes[opt_idx].shrinking_takes_head = !!enabled; } } else { self.shrinking_takes_head = !!enabled; } }; /** * Sets a colour generation function of the colour scheme. * * The function must accept a singe number argument whose value can be from * 0.0 to 1.0, and return a colour as an 'RRGGBB' string. This function * will be used when generating palettes, i.e. if 11-colour palette is * requested, this function will be called with arguments 0.0, 0.1, …, 1.0. * * If the palette generated by the function is colourblind friendly, * opt_is_cbf should be set to true. * * In some cases, it is not desirable to reach 1.0 when generating * a palette. This happens for hue-rainbows where the 0–1 range corresponds * to a 0°–360° range in hues, and since hue at 0° is the same as at 360°, * it's desired to stop short the end of the range when generating * a palette. To accomplish this, opt_cyclic should be set to true. * * @param {palette.ColorFunction} func A colour generator function. * @param {boolean=} opt_is_cbf Whether palette generate with the function * is colour-blind friendly. * @param {boolean=} opt_cyclic Whether colour at 0.0 is the same as the * one at 1.0. */ self.setColorFunction = function(func, opt_is_cbf, opt_cyclic) { self.color_func = func; self.color_func_cyclic = !!opt_cyclic; self.max = INF; if (!opt_is_cbf && self.cbf_max === INF) { self.cbf_max = 1; } }; self.color = function(x, varargs) { if (self.color_func) { return self.color_func.apply(this, arguments); } else { return null; } }; return self; }; /** * Creates a new palette.Scheme and initialises it by calling addPalettes * method with the rest of the arguments. * * @param {string} name Name of the scheme. * @param {string|!Array} groups A group name or list of group * names the scheme belongs to. * @param {!Object|!Array} * palettes A map or an array of colour palettes to add. If map, i.e. * object, is used, properties should use integer property names. * @param {number=} opt_max Size of the biggest palette in palettes set. * If not set, palettes must have a length property which will be used. * @param {number=} opt_cbf_max Size of the biggest palette which is still * colourblind friendly. 1 by default. * @return {!palette.SchemeType} A colour palette generator function, which * in addition has methods and properties like a regular object. Think * of it as a callable object. */ palette.Scheme.fromPalettes = function(name, groups, palettes, opt_max, opt_cbf_max) { var scheme = palette.Scheme(name, groups); scheme.addPalettes.apply(scheme, slice(arguments, 2)); return scheme; }; /** * Creates a new palette.Scheme and initialises it by calling * setColorFunction method with the rest of the arguments. * * @param {string} name Name of the scheme. * @param {string|!Array} groups A group name or list of group * names the scheme belongs to. * @param {palette.ColorFunction} func A colour generator function. * @param {boolean=} opt_is_cbf Whether palette generate with the function * is colour-blind friendly. * @param {boolean=} opt_cyclic Whether colour at 0.0 is the same as the * one at 1.0. * @return {!palette.SchemeType} A colour palette generator function, which * in addition has methods and properties like a regular object. Think * of it as a callable object. */ palette.Scheme.withColorFunction = function(name, groups, func, opt_is_cbf, opt_cyclic) { var scheme = palette.Scheme(name, groups); scheme.setColorFunction.apply(scheme, slice(arguments, 2)); return scheme; }; /** * A map of registered schemes. Maps a scheme or group name to a list of * scheme objects. Property name is either 'n-' for single scheme * names or 'g-' for scheme group names. * * @type {!Object>} */ var registered_schemes = {}; /** * Registers a new colour scheme. * * @param {!palette.SchemeType} scheme The scheme to add. */ palette.register = function(scheme) { registered_schemes['n-' + scheme.scheme_name] = [scheme]; scheme.groups.forEach(function(g) { (registered_schemes['g-' + g] = registered_schemes['g-' + g] || []).push(scheme); }); (registered_schemes['g-all'] = registered_schemes['g-all'] || []).push(scheme); }; /** * List all schemes that match given name and number of colours. * * name argument can be either a string or an array of strings. In the * former case, the function acts as if the argument was an array with name * as a single argument (i.e. “palette.listSchemes('foo')” is exactly the same * as “palette.listSchemes(['foo'])”). * * Each name can be either name of a palette (e.g. 'tol-sq' for Paul Tol's * sequential palette), or a name of a group (e.g. 'sequential' for all * sequential palettes). Name can therefore map to a single scheme or * several schemes. * * Furthermore, name can be suffixed with '-cbf' to indicate that only * schemes that are colourblind friendly should be returned. For example, * 'rainbow' returns a HSV rainbow scheme, but because it is not colourblind * friendly, 'rainbow-cbf' returns no schemes. * * Some schemes may produce colourblind friendly palettes for some number of * colours. For example ColorBrewer's Dark2 scheme is colourblind friendly * if no more than 3 colours are generated. If opt_number is not specified, * 'qualitative-cbf' will include 'cb-Dark2' but if opt_number is given as, * say, 5 it won't. * * Name can also be 'all' which will return all registered schemes. * Naturally, 'all-cbf' will return all colourblind friendly schemes. * * Schemes are added to the library using palette.register. Schemes are * created using palette.Scheme function. By default, the following schemes * are available: * * Name Description * -------------- ----------------------------------------------------- * tol Paul Tol's qualitative scheme, cbf, max 12 colours. * tol-dv Paul Tol's diverging scheme, cbf. * tol-sq Paul Tol's sequential scheme, cbf. * tol-rainbow Paul Tol's qualitative scheme, cbf. * * rainbow A rainbow palette. * * cb-YlGn ColorBrewer sequential schemes. * cb-YlGnBu * cb-GnBu * cb-BuGn * cb-PuBuGn * cb-PuBu * cb-BuPu * cb-RdPu * cb-PuRd * cb-OrRd * cb-YlOrRd * cb-YlOrBr * cb-Purples * cb-Blues * cb-Greens * cb-Oranges * cb-Reds * cb-Greys * * cb-PuOr ColorBrewer diverging schemes. * cb-BrBG * cb-PRGn * cb-PiYG * cb-RdBu * cb-RdGy * cb-RdYlBu * cb-Spectral * cb-RdYlGn * * cb-Accent ColorBrewer qualitative schemes. * cb-Dark2 * cb-Paired * cb-Pastel1 * cb-Pastel2 * cb-Set1 * cb-Set2 * cb-Set3 * * sol-base Solarized base colours. * sol-accent Solarized accent colours. * * The following groups are also available by default: * * Name Description * -------------- ----------------------------------------------------- * all All registered schemes. * sequential All sequential schemes. * diverging All diverging schemes. * qualitative All qualitative schemes. * cb-sequential All ColorBrewer sequential schemes. * cb-diverging All ColorBrewer diverging schemes. * cb-qualitative All ColorBrewer qualitative schemes. * * You can read more about Paul Tol's palettes at http://www.sron.nl/~pault/. * You can read more about ColorBrewer at http://colorbrewer2.org. * * @param {string|!Array} name A name of a colour scheme, of * a group of colour schemes, or an array of any of those. * @param {number=} opt_number When requesting only colourblind friendly * schemes, number of colours the scheme must provide generating such * that the palette is still colourblind friendly. 2 by default. * @return {!Array} An array of colour scheme objects * matching the criteria. Sorted by scheme name. */ palette.listSchemes = function(name, opt_number) { if (!opt_number) { opt_number = 2; } else if (opt_number < 0) { opt_number = -opt_number; } var ret = []; (typeof name === 'string' ? [name] : name).forEach(function(n) { var cbf = n.substring(n.length - 4) === '-cbf'; if (cbf) { n = n.substring(0, n.length - 4); } var schemes = registered_schemes['g-' + n] || registered_schemes['n-' + n] || []; for (var i = 0, scheme; (scheme = schemes[i]); ++i) { if ((cbf ? scheme.cbf : scheme.max) >= opt_number) { ret.push(scheme); } } }); ret.sort(function(a, b) { return a.scheme_name >= b.scheme_name ? a.scheme_name > b.scheme_name ? 1 : 0 : -1; }); return ret; }; /** * Generates a palette using given colour generating function. * * The color_func callback must accept a singe number argument whose value * can vary from 0.0 to 1.0 (or in general from opt_start to opt_end), and * return a colour as an 'RRGGBB' string. This function will be used when * generating palettes, i.e. if 11-colour palette is requested, this * function will be called with arguments 0.0, 0.1, …, 1.0. * * In some cases, it is not desirable to reach 1.0 when generating * a palette. This happens for hue-rainbows where the 0–1 range corresponds * to a 0°–360° range in hues, and since hue at 0° is the same as at 360°, * it's desired to stop short the end of the range when generating * a palette. To accomplish this, opt_cyclic should be set to true. * * opt_start and opt_end may be used to change the range the colour * generation function is called with. opt_end may be less than opt_start * which will case to traverse the range in reverse. Another way to reverse * the palette is requesting negative number of colours. The two methods do * not always lead to the same results (especially if opt_cyclic is set). * * @param {palette.ColorFunction} color_func A colours generating callback * function. * @param {number} number Number of colours to generate in the palette. If * number is negative, colours in the palette will be reversed. If only * one colour is requested, colour at opt_start will be returned. * @param {number=} opt_start Optional starting point for the palette * generation function. Zero by default. * @param {number=} opt_end Optional ending point for the palette generation * function. One by default. * @param {boolean=} opt_cyclic If true, function will assume colour at * point opt_start is the same as one at opt_end. * @return {palette.Palette} An array of 'RRGGBB' colours. */ palette.generate = function(color_func, number, opt_start, opt_end, opt_cyclic) { if (Math.abs(number) < 1) { return []; } opt_start = opt_start === void(0) ? 0 : opt_start; opt_end = opt_end === void(0) ? 1 : opt_end; if (Math.abs(number) < 2) { return [color_func(opt_start)]; } var i = Math.abs(number); var x = opt_start; var ret = []; var step = (opt_end - opt_start) / (opt_cyclic ? i : (i - 1)); for (; --i >= 0; x += step) { ret.push(color_func(x)); } if (number < 0) { ret.reverse(); } return ret; }; /** * Clamps value to [0, 1] range. * @param {number} v Number to limit value of. * @return {number} If v is inside of [0, 1] range returns v, otherwise * returns 0 or 1 depending which side of the range v is closer to. */ var clamp = function(v) { return v > 0 ? (v < 1 ? v : 1) : 0; }; /** * Converts r, g, b triple into RRGGBB hex representation. * @param {number} r Red value of the colour in the range [0, 1]. * @param {number} g Green value of the colour in the range [0, 1]. * @param {number} b Blue value of the colour in the range [0, 1]. * @return {string} A lower-case RRGGBB representation of the colour. */ palette.rgbColor = function(r, g, b) { return [r, g, b].map(function(v) { v = Number(Math.round(clamp(v) * 255)).toString(16); return v.length == 1 ? '0' + v : v; }).join(''); }; /** * Converts a linear r, g, b triple into RRGGBB hex representation. * @param {number} r Linear red value of the colour in the range [0, 1]. * @param {number} g Linear green value of the colour in the range [0, 1]. * @param {number} b Linear blue value of the colour in the range [0, 1]. * @return {string} A lower-case RRGGBB representation of the colour. */ palette.linearRgbColor = function(r, g, b) { // http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html return [r, g, b].map(function(v) { v = clamp(v); if (v <= 0.0031308) { v = 12.92 * v; } else { v = 1.055 * Math.pow(v, 1 / 2.4) - 0.055; } v = Number(Math.round(v * 255)).toString(16); return v.length == 1 ? '0' + v : v; }).join(''); }; /** * Converts an HSV colours to RRGGBB hex representation. * @param {number} h Hue in the range [0, 1]. * @param {number=} opt_s Saturation in the range [0, 1]. One by default. * @param {number=} opt_v Value in the range [0, 1]. One by default. * @return {string} An RRGGBB representation of the colour. */ palette.hsvColor = function(h, opt_s, opt_v) { h *= 6; var s = opt_s === void(0) ? 1 : clamp(opt_s); var v = opt_v === void(0) ? 1 : clamp(opt_v); var x = v * (1 - s * Math.abs(h % 2 - 1)); var m = v * (1 - s); switch (Math.floor(h) % 6) { case 0: return palette.rgbColor(v, x, m); case 1: return palette.rgbColor(x, v, m); case 2: return palette.rgbColor(m, v, x); case 3: return palette.rgbColor(m, x, v); case 4: return palette.rgbColor(x, m, v); default: return palette.rgbColor(v, m, x); } }; palette.register(palette.Scheme.withColorFunction( 'rainbow', 'qualitative', palette.hsvColor, false, true)); return palette; })(); /** @typedef {function(number): string} */ palette.ColorFunction; /** @typedef {!Array} */ palette.Palette; /** @typedef {!Object|!Array} */ palette.PalettesList; /** * @typedef { * function(number, ...?): Array| * { * scheme_name: string, * groups: !Array, * max: number, * cbf_max: number, * addPalette: function(!Array, boolean=), * addPalettes: function(palette.PalettesList, number=, number=), * shrinkByTakingHead: function(boolean, number=), * setColorFunction: function(palette.ColorFunction, boolean=, boolean=), * color: function(number, ...?): ?string}} */ palette.SchemeType; /* mpn65 palette start here. ************************************************/ /* The ‘mpn65’ palette is designed for systems which show many graphs which don’t have custom colour palettes chosen by humans or if number of necessary colours isn’t know a priori. */ (function() { var scheme = palette.Scheme.fromPalettes('mpn65', 'qualitative', [[ 'ff0029', '377eb8', '66a61e', '984ea3', '00d2d5', 'ff7f00', 'af8d00', '7f80cd', 'b3e900', 'c42e60', 'a65628', 'f781bf', '8dd3c7', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'fccde5', 'bc80bd', 'ffed6f', 'c4eaff', 'cf8c00', '1b9e77', 'd95f02', 'e7298a', 'e6ab02', 'a6761d', '0097ff', '00d067', '000000', '252525', '525252', '737373', '969696', 'bdbdbd', 'f43600', '4ba93b', '5779bb', '927acc', '97ee3f', 'bf3947', '9f5b00', 'f48758', '8caed6', 'f2b94f', 'eff26e', 'e43872', 'd9b100', '9d7a00', '698cff', 'd9d9d9', '00d27e', 'd06800', '009f82', 'c49200', 'cbe8ff', 'fecddf', 'c27eb6', '8cd2ce', 'c4b8d9', 'f883b0', 'a49100', 'f48800', '27d0df', 'a04a9b' ]]); scheme.shrinkByTakingHead(true); palette.register(scheme); })(); /* Paul Tol's schemes start here. *******************************************/ /* See http://www.sron.nl/~pault/ */ (function() { var rgb = palette.rgbColor; /** * Calculates value of a polynomial at given point. * For example, poly(x, 1, 2, 3) calculates value of “1 + 2*x + 3*X²”. * @param {number} x Value to calculate polynomial for. * @param {...number} varargs Coefficients of the polynomial specified in * the order of rising powers of x including constant as the first * variable argument. */ var poly = function(x, varargs) { var i = arguments.length - 1, n = arguments[i]; while (i > 1) { n = n * x + arguments[--i]; } return n; }; /** * Calculate approximate value of error function with maximum error of 0.0005. * See . * @param {number} x Argument of the error function. * @return {number} Value of error function for x. */ var erf = function(x) { // https://en.wikipedia.org/wiki/Error_function#Approximation_with_elementary_functions // This produces a maximum error of 0.0005 which is more then we need. In // the worst case, that error is multiplied by four and then divided by two // before being multiplied by 255, so in the end, the error is multiplied by // 510 which produces 0.255 which is less than a single colour step. var y = poly(Math.abs(x), 1, 0.278393, 0.230389, 0.000972, 0.078108); y *= y; // y^2 y *= y; // y^4 y = 1 - 1 / y; return x < 0 ? -y : y; }; palette.register(palette.Scheme.fromPalettes('tol', 'qualitative', [ ['4477aa'], ['4477aa', 'cc6677'], ['4477aa', 'ddcc77', 'cc6677'], ['4477aa', '117733', 'ddcc77', 'cc6677'], ['332288', '88ccee', '117733', 'ddcc77', 'cc6677'], ['332288', '88ccee', '117733', 'ddcc77', 'cc6677', 'aa4499'], ['332288', '88ccee', '44aa99', '117733', 'ddcc77', 'cc6677', 'aa4499'], ['332288', '88ccee', '44aa99', '117733', '999933', 'ddcc77', 'cc6677', 'aa4499'], ['332288', '88ccee', '44aa99', '117733', '999933', 'ddcc77', 'cc6677', '882255', 'aa4499'], ['332288', '88ccee', '44aa99', '117733', '999933', 'ddcc77', '661100', 'cc6677', '882255', 'aa4499'], ['332288', '6699cc', '88ccee', '44aa99', '117733', '999933', 'ddcc77', '661100', 'cc6677', '882255', 'aa4499'], ['332288', '6699cc', '88ccee', '44aa99', '117733', '999933', 'ddcc77', '661100', 'cc6677', 'aa4466', '882255', 'aa4499'] ], 12, 12)); /** * Calculates a colour along Paul Tol's sequential colours axis. * See figure 7 and equation 1. * @param {number} x Position of the colour on the axis in the [0, 1] range. * @return {string} An RRGGBB representation of the colour. */ palette.tolSequentialColor = function(x) { return rgb(1 - 0.392 * (1 + erf((x - 0.869) / 0.255)), 1.021 - 0.456 * (1 + erf((x - 0.527) / 0.376)), 1 - 0.493 * (1 + erf((x - 0.272) / 0.309))); }; palette.register(palette.Scheme.withColorFunction( 'tol-sq', 'sequential', palette.tolSequentialColor, true)); /** * Calculates a colour along Paul Tol's diverging colours axis. * See figure 8 and equation 2. * @param {number} x Position of the colour on the axis in the [0, 1] range. * @return {string} An RRGGBB representation of the colour. */ palette.tolDivergingColor = function(x) { var g = poly(x, 0.572, 1.524, -1.811) / poly(x, 1, -0.291, 0.1574); return rgb(poly(x, 0.235, -2.13, 26.92, -65.5, 63.5, -22.36), g * g, 1 / poly(x, 1.579, -4.03, 12.92, -31.4, 48.6, -23.36)); }; palette.register(palette.Scheme.withColorFunction( 'tol-dv', 'diverging', palette.tolDivergingColor, true)); /** * Calculates a colour along Paul Tol's rainbow colours axis. * See figure 13 and equation 3. * @param {number} x Position of the colour on the axis in the [0, 1] range. * @return {string} An RRGGBB representation of the colour. */ palette.tolRainbowColor = function(x) { return rgb(poly(x, 0.472, -0.567, 4.05) / poly(x, 1, 8.72, -19.17, 14.1), poly(x, 0.108932, -1.22635, 27.284, -98.577, 163.3, -131.395, 40.634), 1 / poly(x, 1.97, 3.54, -68.5, 243, -297, 125)); }; palette.register(palette.Scheme.withColorFunction( 'tol-rainbow', 'qualitative', palette.tolRainbowColor, true)); })(); /* Solarized colour schemes start here. *************************************/ /* See http://ethanschoonover.com/solarized */ (function() { /* * Those are not really designed to be used in graphs, but we're keeping * them here in case someone cares. */ palette.register(palette.Scheme.fromPalettes('sol-base', 'sequential', [ ['002b36', '073642', '586e75', '657b83', '839496', '93a1a1', 'eee8d5', 'fdf6e3'] ], 1, 8)); palette.register(palette.Scheme.fromPalettes('sol-accent', 'qualitative', [ ['b58900', 'cb4b16', 'dc322f', 'd33682', '6c71c4', '268bd2', '2aa198', '859900'] ])); })(); /* ColorBrewer colour schemes start here. ***********************************/ /* See http://colorbrewer2.org/ */ (function() { var schemes = { YlGn: { type: 'sequential', cbf: 42, 3: ['f7fcb9', 'addd8e', '31a354'], 4: ['ffffcc', 'c2e699', '78c679', '238443'], 5: ['ffffcc', 'c2e699', '78c679', '31a354', '006837'], 6: ['ffffcc', 'd9f0a3', 'addd8e', '78c679', '31a354', '006837'], 7: ['ffffcc', 'd9f0a3', 'addd8e', '78c679', '41ab5d', '238443', '005a32'], 8: ['ffffe5', 'f7fcb9', 'd9f0a3', 'addd8e', '78c679', '41ab5d', '238443', '005a32'], 9: ['ffffe5', 'f7fcb9', 'd9f0a3', 'addd8e', '78c679', '41ab5d', '238443', '006837', '004529'] }, YlGnBu: { type: 'sequential', cbf: 42, 3: ['edf8b1', '7fcdbb', '2c7fb8'], 4: ['ffffcc', 'a1dab4', '41b6c4', '225ea8'], 5: ['ffffcc', 'a1dab4', '41b6c4', '2c7fb8', '253494'], 6: ['ffffcc', 'c7e9b4', '7fcdbb', '41b6c4', '2c7fb8', '253494'], 7: ['ffffcc', 'c7e9b4', '7fcdbb', '41b6c4', '1d91c0', '225ea8', '0c2c84'], 8: ['ffffd9', 'edf8b1', 'c7e9b4', '7fcdbb', '41b6c4', '1d91c0', '225ea8', '0c2c84'], 9: ['ffffd9', 'edf8b1', 'c7e9b4', '7fcdbb', '41b6c4', '1d91c0', '225ea8', '253494', '081d58'] }, GnBu: { type: 'sequential', cbf: 42, 3: ['e0f3db', 'a8ddb5', '43a2ca'], 4: ['f0f9e8', 'bae4bc', '7bccc4', '2b8cbe'], 5: ['f0f9e8', 'bae4bc', '7bccc4', '43a2ca', '0868ac'], 6: ['f0f9e8', 'ccebc5', 'a8ddb5', '7bccc4', '43a2ca', '0868ac'], 7: ['f0f9e8', 'ccebc5', 'a8ddb5', '7bccc4', '4eb3d3', '2b8cbe', '08589e'], 8: ['f7fcf0', 'e0f3db', 'ccebc5', 'a8ddb5', '7bccc4', '4eb3d3', '2b8cbe', '08589e'], 9: ['f7fcf0', 'e0f3db', 'ccebc5', 'a8ddb5', '7bccc4', '4eb3d3', '2b8cbe', '0868ac', '084081'] }, BuGn: { type: 'sequential', cbf: 42, 3: ['e5f5f9', '99d8c9', '2ca25f'], 4: ['edf8fb', 'b2e2e2', '66c2a4', '238b45'], 5: ['edf8fb', 'b2e2e2', '66c2a4', '2ca25f', '006d2c'], 6: ['edf8fb', 'ccece6', '99d8c9', '66c2a4', '2ca25f', '006d2c'], 7: ['edf8fb', 'ccece6', '99d8c9', '66c2a4', '41ae76', '238b45', '005824'], 8: ['f7fcfd', 'e5f5f9', 'ccece6', '99d8c9', '66c2a4', '41ae76', '238b45', '005824'], 9: ['f7fcfd', 'e5f5f9', 'ccece6', '99d8c9', '66c2a4', '41ae76', '238b45', '006d2c', '00441b'] }, PuBuGn: { type: 'sequential', cbf: 42, 3: ['ece2f0', 'a6bddb', '1c9099'], 4: ['f6eff7', 'bdc9e1', '67a9cf', '02818a'], 5: ['f6eff7', 'bdc9e1', '67a9cf', '1c9099', '016c59'], 6: ['f6eff7', 'd0d1e6', 'a6bddb', '67a9cf', '1c9099', '016c59'], 7: ['f6eff7', 'd0d1e6', 'a6bddb', '67a9cf', '3690c0', '02818a', '016450'], 8: ['fff7fb', 'ece2f0', 'd0d1e6', 'a6bddb', '67a9cf', '3690c0', '02818a', '016450'], 9: ['fff7fb', 'ece2f0', 'd0d1e6', 'a6bddb', '67a9cf', '3690c0', '02818a', '016c59', '014636'] }, PuBu: { type: 'sequential', cbf: 42, 3: ['ece7f2', 'a6bddb', '2b8cbe'], 4: ['f1eef6', 'bdc9e1', '74a9cf', '0570b0'], 5: ['f1eef6', 'bdc9e1', '74a9cf', '2b8cbe', '045a8d'], 6: ['f1eef6', 'd0d1e6', 'a6bddb', '74a9cf', '2b8cbe', '045a8d'], 7: ['f1eef6', 'd0d1e6', 'a6bddb', '74a9cf', '3690c0', '0570b0', '034e7b'], 8: ['fff7fb', 'ece7f2', 'd0d1e6', 'a6bddb', '74a9cf', '3690c0', '0570b0', '034e7b'], 9: ['fff7fb', 'ece7f2', 'd0d1e6', 'a6bddb', '74a9cf', '3690c0', '0570b0', '045a8d', '023858'] }, BuPu: { type: 'sequential', cbf: 42, 3: ['e0ecf4', '9ebcda', '8856a7'], 4: ['edf8fb', 'b3cde3', '8c96c6', '88419d'], 5: ['edf8fb', 'b3cde3', '8c96c6', '8856a7', '810f7c'], 6: ['edf8fb', 'bfd3e6', '9ebcda', '8c96c6', '8856a7', '810f7c'], 7: ['edf8fb', 'bfd3e6', '9ebcda', '8c96c6', '8c6bb1', '88419d', '6e016b'], 8: ['f7fcfd', 'e0ecf4', 'bfd3e6', '9ebcda', '8c96c6', '8c6bb1', '88419d', '6e016b'], 9: ['f7fcfd', 'e0ecf4', 'bfd3e6', '9ebcda', '8c96c6', '8c6bb1', '88419d', '810f7c', '4d004b'] }, RdPu: { type: 'sequential', cbf: 42, 3: ['fde0dd', 'fa9fb5', 'c51b8a'], 4: ['feebe2', 'fbb4b9', 'f768a1', 'ae017e'], 5: ['feebe2', 'fbb4b9', 'f768a1', 'c51b8a', '7a0177'], 6: ['feebe2', 'fcc5c0', 'fa9fb5', 'f768a1', 'c51b8a', '7a0177'], 7: ['feebe2', 'fcc5c0', 'fa9fb5', 'f768a1', 'dd3497', 'ae017e', '7a0177'], 8: ['fff7f3', 'fde0dd', 'fcc5c0', 'fa9fb5', 'f768a1', 'dd3497', 'ae017e', '7a0177'], 9: ['fff7f3', 'fde0dd', 'fcc5c0', 'fa9fb5', 'f768a1', 'dd3497', 'ae017e', '7a0177', '49006a'] }, PuRd: { type: 'sequential', cbf: 42, 3: ['e7e1ef', 'c994c7', 'dd1c77'], 4: ['f1eef6', 'd7b5d8', 'df65b0', 'ce1256'], 5: ['f1eef6', 'd7b5d8', 'df65b0', 'dd1c77', '980043'], 6: ['f1eef6', 'd4b9da', 'c994c7', 'df65b0', 'dd1c77', '980043'], 7: ['f1eef6', 'd4b9da', 'c994c7', 'df65b0', 'e7298a', 'ce1256', '91003f'], 8: ['f7f4f9', 'e7e1ef', 'd4b9da', 'c994c7', 'df65b0', 'e7298a', 'ce1256', '91003f'], 9: ['f7f4f9', 'e7e1ef', 'd4b9da', 'c994c7', 'df65b0', 'e7298a', 'ce1256', '980043', '67001f'] }, OrRd: { type: 'sequential', cbf: 42, 3: ['fee8c8', 'fdbb84', 'e34a33'], 4: ['fef0d9', 'fdcc8a', 'fc8d59', 'd7301f'], 5: ['fef0d9', 'fdcc8a', 'fc8d59', 'e34a33', 'b30000'], 6: ['fef0d9', 'fdd49e', 'fdbb84', 'fc8d59', 'e34a33', 'b30000'], 7: ['fef0d9', 'fdd49e', 'fdbb84', 'fc8d59', 'ef6548', 'd7301f', '990000'], 8: ['fff7ec', 'fee8c8', 'fdd49e', 'fdbb84', 'fc8d59', 'ef6548', 'd7301f', '990000'], 9: ['fff7ec', 'fee8c8', 'fdd49e', 'fdbb84', 'fc8d59', 'ef6548', 'd7301f', 'b30000', '7f0000'] }, YlOrRd: { type: 'sequential', cbf: 42, 3: ['ffeda0', 'feb24c', 'f03b20'], 4: ['ffffb2', 'fecc5c', 'fd8d3c', 'e31a1c'], 5: ['ffffb2', 'fecc5c', 'fd8d3c', 'f03b20', 'bd0026'], 6: ['ffffb2', 'fed976', 'feb24c', 'fd8d3c', 'f03b20', 'bd0026'], 7: ['ffffb2', 'fed976', 'feb24c', 'fd8d3c', 'fc4e2a', 'e31a1c', 'b10026'], 8: ['ffffcc', 'ffeda0', 'fed976', 'feb24c', 'fd8d3c', 'fc4e2a', 'e31a1c', 'b10026'], 9: ['ffffcc', 'ffeda0', 'fed976', 'feb24c', 'fd8d3c', 'fc4e2a', 'e31a1c', 'bd0026', '800026'] }, YlOrBr: { type: 'sequential', cbf: 42, 3: ['fff7bc', 'fec44f', 'd95f0e'], 4: ['ffffd4', 'fed98e', 'fe9929', 'cc4c02'], 5: ['ffffd4', 'fed98e', 'fe9929', 'd95f0e', '993404'], 6: ['ffffd4', 'fee391', 'fec44f', 'fe9929', 'd95f0e', '993404'], 7: ['ffffd4', 'fee391', 'fec44f', 'fe9929', 'ec7014', 'cc4c02', '8c2d04'], 8: ['ffffe5', 'fff7bc', 'fee391', 'fec44f', 'fe9929', 'ec7014', 'cc4c02', '8c2d04'], 9: ['ffffe5', 'fff7bc', 'fee391', 'fec44f', 'fe9929', 'ec7014', 'cc4c02', '993404', '662506'] }, Purples: { type: 'sequential', cbf: 42, 3: ['efedf5', 'bcbddc', '756bb1'], 4: ['f2f0f7', 'cbc9e2', '9e9ac8', '6a51a3'], 5: ['f2f0f7', 'cbc9e2', '9e9ac8', '756bb1', '54278f'], 6: ['f2f0f7', 'dadaeb', 'bcbddc', '9e9ac8', '756bb1', '54278f'], 7: ['f2f0f7', 'dadaeb', 'bcbddc', '9e9ac8', '807dba', '6a51a3', '4a1486'], 8: ['fcfbfd', 'efedf5', 'dadaeb', 'bcbddc', '9e9ac8', '807dba', '6a51a3', '4a1486'], 9: ['fcfbfd', 'efedf5', 'dadaeb', 'bcbddc', '9e9ac8', '807dba', '6a51a3', '54278f', '3f007d'] }, Blues: { type: 'sequential', cbf: 42, 3: ['deebf7', '9ecae1', '3182bd'], 4: ['eff3ff', 'bdd7e7', '6baed6', '2171b5'], 5: ['eff3ff', 'bdd7e7', '6baed6', '3182bd', '08519c'], 6: ['eff3ff', 'c6dbef', '9ecae1', '6baed6', '3182bd', '08519c'], 7: ['eff3ff', 'c6dbef', '9ecae1', '6baed6', '4292c6', '2171b5', '084594'], 8: ['f7fbff', 'deebf7', 'c6dbef', '9ecae1', '6baed6', '4292c6', '2171b5', '084594'], 9: ['f7fbff', 'deebf7', 'c6dbef', '9ecae1', '6baed6', '4292c6', '2171b5', '08519c', '08306b'] }, Greens: { type: 'sequential', cbf: 42, 3: ['e5f5e0', 'a1d99b', '31a354'], 4: ['edf8e9', 'bae4b3', '74c476', '238b45'], 5: ['edf8e9', 'bae4b3', '74c476', '31a354', '006d2c'], 6: ['edf8e9', 'c7e9c0', 'a1d99b', '74c476', '31a354', '006d2c'], 7: ['edf8e9', 'c7e9c0', 'a1d99b', '74c476', '41ab5d', '238b45', '005a32'], 8: ['f7fcf5', 'e5f5e0', 'c7e9c0', 'a1d99b', '74c476', '41ab5d', '238b45', '005a32'], 9: ['f7fcf5', 'e5f5e0', 'c7e9c0', 'a1d99b', '74c476', '41ab5d', '238b45', '006d2c', '00441b'] }, Oranges: { type: 'sequential', cbf: 42, 3: ['fee6ce', 'fdae6b', 'e6550d'], 4: ['feedde', 'fdbe85', 'fd8d3c', 'd94701'], 5: ['feedde', 'fdbe85', 'fd8d3c', 'e6550d', 'a63603'], 6: ['feedde', 'fdd0a2', 'fdae6b', 'fd8d3c', 'e6550d', 'a63603'], 7: ['feedde', 'fdd0a2', 'fdae6b', 'fd8d3c', 'f16913', 'd94801', '8c2d04'], 8: ['fff5eb', 'fee6ce', 'fdd0a2', 'fdae6b', 'fd8d3c', 'f16913', 'd94801', '8c2d04'], 9: ['fff5eb', 'fee6ce', 'fdd0a2', 'fdae6b', 'fd8d3c', 'f16913', 'd94801', 'a63603', '7f2704'] }, Reds: { type: 'sequential', cbf: 42, 3: ['fee0d2', 'fc9272', 'de2d26'], 4: ['fee5d9', 'fcae91', 'fb6a4a', 'cb181d'], 5: ['fee5d9', 'fcae91', 'fb6a4a', 'de2d26', 'a50f15'], 6: ['fee5d9', 'fcbba1', 'fc9272', 'fb6a4a', 'de2d26', 'a50f15'], 7: ['fee5d9', 'fcbba1', 'fc9272', 'fb6a4a', 'ef3b2c', 'cb181d', '99000d'], 8: ['fff5f0', 'fee0d2', 'fcbba1', 'fc9272', 'fb6a4a', 'ef3b2c', 'cb181d', '99000d'], 9: ['fff5f0', 'fee0d2', 'fcbba1', 'fc9272', 'fb6a4a', 'ef3b2c', 'cb181d', 'a50f15', '67000d'] }, Greys: { type: 'sequential', cbf: 42, 3: ['f0f0f0', 'bdbdbd', '636363'], 4: ['f7f7f7', 'cccccc', '969696', '525252'], 5: ['f7f7f7', 'cccccc', '969696', '636363', '252525'], 6: ['f7f7f7', 'd9d9d9', 'bdbdbd', '969696', '636363', '252525'], 7: ['f7f7f7', 'd9d9d9', 'bdbdbd', '969696', '737373', '525252', '252525'], 8: ['ffffff', 'f0f0f0', 'd9d9d9', 'bdbdbd', '969696', '737373', '525252', '252525'], 9: ['ffffff', 'f0f0f0', 'd9d9d9', 'bdbdbd', '969696', '737373', '525252', '252525', '000000'] }, PuOr: { type: 'diverging', cbf: 42, 3: ['f1a340', 'f7f7f7', '998ec3'], 4: ['e66101', 'fdb863', 'b2abd2', '5e3c99'], 5: ['e66101', 'fdb863', 'f7f7f7', 'b2abd2', '5e3c99'], 6: ['b35806', 'f1a340', 'fee0b6', 'd8daeb', '998ec3', '542788'], 7: ['b35806', 'f1a340', 'fee0b6', 'f7f7f7', 'd8daeb', '998ec3', '542788'], 8: ['b35806', 'e08214', 'fdb863', 'fee0b6', 'd8daeb', 'b2abd2', '8073ac', '542788'], 9: ['b35806', 'e08214', 'fdb863', 'fee0b6', 'f7f7f7', 'd8daeb', 'b2abd2', '8073ac', '542788'], 10: ['7f3b08', 'b35806', 'e08214', 'fdb863', 'fee0b6', 'd8daeb', 'b2abd2', '8073ac', '542788', '2d004b'], 11: ['7f3b08', 'b35806', 'e08214', 'fdb863', 'fee0b6', 'f7f7f7', 'd8daeb', 'b2abd2', '8073ac', '542788', '2d004b'] }, BrBG: { type: 'diverging', cbf: 42, 3: ['d8b365', 'f5f5f5', '5ab4ac'], 4: ['a6611a', 'dfc27d', '80cdc1', '018571'], 5: ['a6611a', 'dfc27d', 'f5f5f5', '80cdc1', '018571'], 6: ['8c510a', 'd8b365', 'f6e8c3', 'c7eae5', '5ab4ac', '01665e'], 7: ['8c510a', 'd8b365', 'f6e8c3', 'f5f5f5', 'c7eae5', '5ab4ac', '01665e'], 8: ['8c510a', 'bf812d', 'dfc27d', 'f6e8c3', 'c7eae5', '80cdc1', '35978f', '01665e'], 9: ['8c510a', 'bf812d', 'dfc27d', 'f6e8c3', 'f5f5f5', 'c7eae5', '80cdc1', '35978f', '01665e'], 10: ['543005', '8c510a', 'bf812d', 'dfc27d', 'f6e8c3', 'c7eae5', '80cdc1', '35978f', '01665e', '003c30'], 11: ['543005', '8c510a', 'bf812d', 'dfc27d', 'f6e8c3', 'f5f5f5', 'c7eae5', '80cdc1', '35978f', '01665e', '003c30'] }, PRGn: { type: 'diverging', cbf: 42, 3: ['af8dc3', 'f7f7f7', '7fbf7b'], 4: ['7b3294', 'c2a5cf', 'a6dba0', '008837'], 5: ['7b3294', 'c2a5cf', 'f7f7f7', 'a6dba0', '008837'], 6: ['762a83', 'af8dc3', 'e7d4e8', 'd9f0d3', '7fbf7b', '1b7837'], 7: ['762a83', 'af8dc3', 'e7d4e8', 'f7f7f7', 'd9f0d3', '7fbf7b', '1b7837'], 8: ['762a83', '9970ab', 'c2a5cf', 'e7d4e8', 'd9f0d3', 'a6dba0', '5aae61', '1b7837'], 9: ['762a83', '9970ab', 'c2a5cf', 'e7d4e8', 'f7f7f7', 'd9f0d3', 'a6dba0', '5aae61', '1b7837'], 10: ['40004b', '762a83', '9970ab', 'c2a5cf', 'e7d4e8', 'd9f0d3', 'a6dba0', '5aae61', '1b7837', '00441b'], 11: ['40004b', '762a83', '9970ab', 'c2a5cf', 'e7d4e8', 'f7f7f7', 'd9f0d3', 'a6dba0', '5aae61', '1b7837', '00441b'] }, PiYG: { type: 'diverging', cbf: 42, 3: ['e9a3c9', 'f7f7f7', 'a1d76a'], 4: ['d01c8b', 'f1b6da', 'b8e186', '4dac26'], 5: ['d01c8b', 'f1b6da', 'f7f7f7', 'b8e186', '4dac26'], 6: ['c51b7d', 'e9a3c9', 'fde0ef', 'e6f5d0', 'a1d76a', '4d9221'], 7: ['c51b7d', 'e9a3c9', 'fde0ef', 'f7f7f7', 'e6f5d0', 'a1d76a', '4d9221'], 8: ['c51b7d', 'de77ae', 'f1b6da', 'fde0ef', 'e6f5d0', 'b8e186', '7fbc41', '4d9221'], 9: ['c51b7d', 'de77ae', 'f1b6da', 'fde0ef', 'f7f7f7', 'e6f5d0', 'b8e186', '7fbc41', '4d9221'], 10: ['8e0152', 'c51b7d', 'de77ae', 'f1b6da', 'fde0ef', 'e6f5d0', 'b8e186', '7fbc41', '4d9221', '276419'], 11: ['8e0152', 'c51b7d', 'de77ae', 'f1b6da', 'fde0ef', 'f7f7f7', 'e6f5d0', 'b8e186', '7fbc41', '4d9221', '276419'] }, RdBu: { type: 'diverging', cbf: 42, 3: ['ef8a62', 'f7f7f7', '67a9cf'], 4: ['ca0020', 'f4a582', '92c5de', '0571b0'], 5: ['ca0020', 'f4a582', 'f7f7f7', '92c5de', '0571b0'], 6: ['b2182b', 'ef8a62', 'fddbc7', 'd1e5f0', '67a9cf', '2166ac'], 7: ['b2182b', 'ef8a62', 'fddbc7', 'f7f7f7', 'd1e5f0', '67a9cf', '2166ac'], 8: ['b2182b', 'd6604d', 'f4a582', 'fddbc7', 'd1e5f0', '92c5de', '4393c3', '2166ac'], 9: ['b2182b', 'd6604d', 'f4a582', 'fddbc7', 'f7f7f7', 'd1e5f0', '92c5de', '4393c3', '2166ac'], 10: ['67001f', 'b2182b', 'd6604d', 'f4a582', 'fddbc7', 'd1e5f0', '92c5de', '4393c3', '2166ac', '053061'], 11: ['67001f', 'b2182b', 'd6604d', 'f4a582', 'fddbc7', 'f7f7f7', 'd1e5f0', '92c5de', '4393c3', '2166ac', '053061'] }, RdGy: { type: 'diverging', cbf: 42, 3: ['ef8a62', 'ffffff', '999999'], 4: ['ca0020', 'f4a582', 'bababa', '404040'], 5: ['ca0020', 'f4a582', 'ffffff', 'bababa', '404040'], 6: ['b2182b', 'ef8a62', 'fddbc7', 'e0e0e0', '999999', '4d4d4d'], 7: ['b2182b', 'ef8a62', 'fddbc7', 'ffffff', 'e0e0e0', '999999', '4d4d4d'], 8: ['b2182b', 'd6604d', 'f4a582', 'fddbc7', 'e0e0e0', 'bababa', '878787', '4d4d4d'], 9: ['b2182b', 'd6604d', 'f4a582', 'fddbc7', 'ffffff', 'e0e0e0', 'bababa', '878787', '4d4d4d'], 10: ['67001f', 'b2182b', 'd6604d', 'f4a582', 'fddbc7', 'e0e0e0', 'bababa', '878787', '4d4d4d', '1a1a1a'], 11: ['67001f', 'b2182b', 'd6604d', 'f4a582', 'fddbc7', 'ffffff', 'e0e0e0', 'bababa', '878787', '4d4d4d', '1a1a1a'] }, RdYlBu: { type: 'diverging', cbf: 42, 3: ['fc8d59', 'ffffbf', '91bfdb'], 4: ['d7191c', 'fdae61', 'abd9e9', '2c7bb6'], 5: ['d7191c', 'fdae61', 'ffffbf', 'abd9e9', '2c7bb6'], 6: ['d73027', 'fc8d59', 'fee090', 'e0f3f8', '91bfdb', '4575b4'], 7: ['d73027', 'fc8d59', 'fee090', 'ffffbf', 'e0f3f8', '91bfdb', '4575b4'], 8: ['d73027', 'f46d43', 'fdae61', 'fee090', 'e0f3f8', 'abd9e9', '74add1', '4575b4'], 9: ['d73027', 'f46d43', 'fdae61', 'fee090', 'ffffbf', 'e0f3f8', 'abd9e9', '74add1', '4575b4'], 10: ['a50026', 'd73027', 'f46d43', 'fdae61', 'fee090', 'e0f3f8', 'abd9e9', '74add1', '4575b4', '313695'], 11: ['a50026', 'd73027', 'f46d43', 'fdae61', 'fee090', 'ffffbf', 'e0f3f8', 'abd9e9', '74add1', '4575b4', '313695'] }, Spectral: { type: 'diverging', cbf: 0, 3: ['fc8d59', 'ffffbf', '99d594'], 4: ['d7191c', 'fdae61', 'abdda4', '2b83ba'], 5: ['d7191c', 'fdae61', 'ffffbf', 'abdda4', '2b83ba'], 6: ['d53e4f', 'fc8d59', 'fee08b', 'e6f598', '99d594', '3288bd'], 7: ['d53e4f', 'fc8d59', 'fee08b', 'ffffbf', 'e6f598', '99d594', '3288bd'], 8: ['d53e4f', 'f46d43', 'fdae61', 'fee08b', 'e6f598', 'abdda4', '66c2a5', '3288bd'], 9: ['d53e4f', 'f46d43', 'fdae61', 'fee08b', 'ffffbf', 'e6f598', 'abdda4', '66c2a5', '3288bd'], 10: ['9e0142', 'd53e4f', 'f46d43', 'fdae61', 'fee08b', 'e6f598', 'abdda4', '66c2a5', '3288bd', '5e4fa2'], 11: ['9e0142', 'd53e4f', 'f46d43', 'fdae61', 'fee08b', 'ffffbf', 'e6f598', 'abdda4', '66c2a5', '3288bd', '5e4fa2'] }, RdYlGn: { type: 'diverging', cbf: 0, 3: ['fc8d59', 'ffffbf', '91cf60'], 4: ['d7191c', 'fdae61', 'a6d96a', '1a9641'], 5: ['d7191c', 'fdae61', 'ffffbf', 'a6d96a', '1a9641'], 6: ['d73027', 'fc8d59', 'fee08b', 'd9ef8b', '91cf60', '1a9850'], 7: ['d73027', 'fc8d59', 'fee08b', 'ffffbf', 'd9ef8b', '91cf60', '1a9850'], 8: ['d73027', 'f46d43', 'fdae61', 'fee08b', 'd9ef8b', 'a6d96a', '66bd63', '1a9850'], 9: ['d73027', 'f46d43', 'fdae61', 'fee08b', 'ffffbf', 'd9ef8b', 'a6d96a', '66bd63', '1a9850'], 10: ['a50026', 'd73027', 'f46d43', 'fdae61', 'fee08b', 'd9ef8b', 'a6d96a', '66bd63', '1a9850', '006837'], 11: ['a50026', 'd73027', 'f46d43', 'fdae61', 'fee08b', 'ffffbf', 'd9ef8b', 'a6d96a', '66bd63', '1a9850', '006837'] }, Accent: { type: 'qualitative', cbf: 0, 3: ['7fc97f', 'beaed4', 'fdc086'], 4: ['7fc97f', 'beaed4', 'fdc086', 'ffff99'], 5: ['7fc97f', 'beaed4', 'fdc086', 'ffff99', '386cb0'], 6: ['7fc97f', 'beaed4', 'fdc086', 'ffff99', '386cb0', 'f0027f'], 7: ['7fc97f', 'beaed4', 'fdc086', 'ffff99', '386cb0', 'f0027f', 'bf5b17'], 8: ['7fc97f', 'beaed4', 'fdc086', 'ffff99', '386cb0', 'f0027f', 'bf5b17', '666666'] }, Dark2: { type: 'qualitative', cbf: 3, 3: ['1b9e77', 'd95f02', '7570b3'], 4: ['1b9e77', 'd95f02', '7570b3', 'e7298a'], 5: ['1b9e77', 'd95f02', '7570b3', 'e7298a', '66a61e'], 6: ['1b9e77', 'd95f02', '7570b3', 'e7298a', '66a61e', 'e6ab02'], 7: ['1b9e77', 'd95f02', '7570b3', 'e7298a', '66a61e', 'e6ab02', 'a6761d'], 8: ['1b9e77', 'd95f02', '7570b3', 'e7298a', '66a61e', 'e6ab02', 'a6761d', '666666'] }, Paired: { type: 'qualitative', cbf: 4, 3: ['a6cee3', '1f78b4', 'b2df8a'], 4: ['a6cee3', '1f78b4', 'b2df8a', '33a02c'], 5: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99'], 6: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c'], 7: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f'], 8: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f', 'ff7f00'], 9: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f', 'ff7f00', 'cab2d6'], 10: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f', 'ff7f00', 'cab2d6', '6a3d9a'], 11: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f', 'ff7f00', 'cab2d6', '6a3d9a', 'ffff99'], 12: ['a6cee3', '1f78b4', 'b2df8a', '33a02c', 'fb9a99', 'e31a1c', 'fdbf6f', 'ff7f00', 'cab2d6', '6a3d9a', 'ffff99', 'b15928'] }, Pastel1: { type: 'qualitative', cbf: 0, 3: ['fbb4ae', 'b3cde3', 'ccebc5'], 4: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4'], 5: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4', 'fed9a6'], 6: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4', 'fed9a6', 'ffffcc'], 7: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4', 'fed9a6', 'ffffcc', 'e5d8bd'], 8: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4', 'fed9a6', 'ffffcc', 'e5d8bd', 'fddaec'], 9: ['fbb4ae', 'b3cde3', 'ccebc5', 'decbe4', 'fed9a6', 'ffffcc', 'e5d8bd', 'fddaec', 'f2f2f2'] }, Pastel2: { type: 'qualitative', cbf: 0, 3: ['b3e2cd', 'fdcdac', 'cbd5e8'], 4: ['b3e2cd', 'fdcdac', 'cbd5e8', 'f4cae4'], 5: ['b3e2cd', 'fdcdac', 'cbd5e8', 'f4cae4', 'e6f5c9'], 6: ['b3e2cd', 'fdcdac', 'cbd5e8', 'f4cae4', 'e6f5c9', 'fff2ae'], 7: ['b3e2cd', 'fdcdac', 'cbd5e8', 'f4cae4', 'e6f5c9', 'fff2ae', 'f1e2cc'], 8: ['b3e2cd', 'fdcdac', 'cbd5e8', 'f4cae4', 'e6f5c9', 'fff2ae', 'f1e2cc', 'cccccc'] }, Set1: { type: 'qualitative', cbf: 0, 3: ['e41a1c', '377eb8', '4daf4a'], 4: ['e41a1c', '377eb8', '4daf4a', '984ea3'], 5: ['e41a1c', '377eb8', '4daf4a', '984ea3', 'ff7f00'], 6: ['e41a1c', '377eb8', '4daf4a', '984ea3', 'ff7f00', 'ffff33'], 7: ['e41a1c', '377eb8', '4daf4a', '984ea3', 'ff7f00', 'ffff33', 'a65628'], 8: ['e41a1c', '377eb8', '4daf4a', '984ea3', 'ff7f00', 'ffff33', 'a65628', 'f781bf'], 9: ['e41a1c', '377eb8', '4daf4a', '984ea3', 'ff7f00', 'ffff33', 'a65628', 'f781bf', '999999'] }, Set2: { type: 'qualitative', cbf: 3, 3: ['66c2a5', 'fc8d62', '8da0cb'], 4: ['66c2a5', 'fc8d62', '8da0cb', 'e78ac3'], 5: ['66c2a5', 'fc8d62', '8da0cb', 'e78ac3', 'a6d854'], 6: ['66c2a5', 'fc8d62', '8da0cb', 'e78ac3', 'a6d854', 'ffd92f'], 7: ['66c2a5', 'fc8d62', '8da0cb', 'e78ac3', 'a6d854', 'ffd92f', 'e5c494'], 8: ['66c2a5', 'fc8d62', '8da0cb', 'e78ac3', 'a6d854', 'ffd92f', 'e5c494', 'b3b3b3'] }, Set3: { type: 'qualitative', cbf: 0, 3: ['8dd3c7', 'ffffb3', 'bebada'], 4: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072'], 5: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3'], 6: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462'], 7: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69'], 8: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69', 'fccde5'], 9: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69', 'fccde5', 'd9d9d9'], 10: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69', 'fccde5', 'd9d9d9', 'bc80bd'], 11: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69', 'fccde5', 'd9d9d9', 'bc80bd', 'ccebc5'], 12: ['8dd3c7', 'ffffb3', 'bebada', 'fb8072', '80b1d3', 'fdb462', 'b3de69', 'fccde5', 'd9d9d9', 'bc80bd', 'ccebc5', 'ffed6f'] } }; for (var name in schemes) { var scheme = schemes[name]; scheme = palette.Scheme.fromPalettes( 'cb-' + name, [scheme.type, 'cb-' + scheme.type], scheme, 12, scheme.cbf); palette.register(scheme); } })(); if(typeof module === "object" && module.exports) { module.exports = palette }