This is an automated email from the ASF dual-hosted git repository.
ccwilliams pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git
The following commit(s) were added to refs/heads/master by this push:
new b9257b2 [Refactor] Extend color scheme management to sequential
schemes (#6150)
b9257b2 is described below
commit b9257b2a09ba1e80dd73ce8cb344115f38f875ab
Author: Krist Wongsuphasawat <[email protected]>
AuthorDate: Mon Oct 22 16:17:14 2018 -0700
[Refactor] Extend color scheme management to sequential schemes (#6150)
* refactor color scheme
* Update data structure
* Update color scheme files
* wip
* convert all sequential schemes
* Update how color schemes are managed. Extend it for sequential schemes
* extract color setup into separate file
* Update imports
* update imports
* Add new functions to Registry
* Update ColorSchemeManager to extends Registry and update unit tests
* Add test for Registry
* Rename ColorSchemeManager to ColorSchemeRegistry
* Fix unit tests
* Update API
* Fix imports
* Add label field
* Fix reference to colors
* update SequentialScheme contructor
* Fix controls
* rename manager to registry
* Split sequential schemes into multiple files
* update sequential color labels
* add values and valuesAsPromise()
* use .values()
---
.../explore/components/ColorPickerControl_spec.jsx | 9 +-
.../explore/components/ColorScheme_spec.jsx | 4 +-
.../javascripts/modules/ColorSchemeManager_spec.js | 139 ------
.../spec/javascripts/modules/Registry_spec.js | 70 +++
.../{ => colors}/CategoricalColorNameSpace_spec.js | 16 +-
.../{ => colors}/CategoricalColorScale_spec.js | 2 +-
.../modules/colors/ColorSchemeRegistry_spec.js | 64 +++
superset/assets/src/common.js | 13 +-
.../src/dashboard/reducers/getInitialState.js | 2 +-
.../components/controls/AnnotationLayer.jsx | 7 +-
.../components/controls/ColorPickerControl.jsx | 11 +-
.../components/controls/ColorSchemeControl.jsx | 2 +-
superset/assets/src/explore/controls.jsx | 63 +--
superset/assets/src/modules/ColorSchemeManager.js | 86 ----
superset/assets/src/modules/Registry.js | 32 ++
superset/assets/src/modules/colorSchemes/airbnb.js | 25 -
.../assets/src/modules/colorSchemes/categorical.js | 42 --
superset/assets/src/modules/colorSchemes/lyft.js | 14 -
.../assets/src/modules/colorSchemes/sequential.js | 433 -----------------
superset/assets/src/modules/colors.js | 4 +-
.../{ => colors}/CategoricalColorNamespace.js | 6 +-
.../modules/{ => colors}/CategoricalColorScale.js | 2 +-
.../assets/src/modules/colors/CategoricalScheme.js | 3 +
.../colors/CategoricalSchemeRegistrySingleton.js | 8 +
superset/assets/src/modules/colors/ColorScheme.js | 15 +
.../src/modules/colors/ColorSchemeRegistry.js | 36 ++
.../assets/src/modules/colors/SequentialScheme.js | 9 +
.../colors/SequentialSchemeRegistrySingleton.js | 8 +
.../colors/colorSchemes/categorical/airbnb.js | 32 ++
.../modules/colors/colorSchemes/categorical/d3.js | 23 +
.../colors/colorSchemes/categorical/google.js | 46 ++
.../colors/colorSchemes/categorical/lyft.js | 21 +
.../colors/colorSchemes/sequential/common.js | 121 +++++
.../modules/colors/colorSchemes/sequential/d3.js | 510 +++++++++++++++++++++
superset/assets/src/setup/setupColors.js | 26 ++
superset/assets/src/visualizations/Chord/Chord.js | 2 +-
.../src/visualizations/Histogram/Histogram.jsx | 2 +-
.../src/visualizations/Partition/Partition.js | 2 +-
superset/assets/src/visualizations/Rose/Rose.js | 2 +-
.../assets/src/visualizations/Sankey/Sankey.js | 2 +-
.../assets/src/visualizations/Sunburst/Sunburst.js | 2 +-
.../assets/src/visualizations/Treemap/Treemap.js | 2 +-
.../deckgl/CategoricalDeckGLContainer.jsx | 4 +-
superset/assets/src/visualizations/nvd3/NVD3Vis.js | 2 +-
.../src/visualizations/wordcloud/WordCloud.js | 2 +-
45 files changed, 1090 insertions(+), 836 deletions(-)
diff --git
a/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
b/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
index 70f00aa..ca814ee 100644
---
a/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
+++
b/superset/assets/spec/javascripts/explore/components/ColorPickerControl_spec.jsx
@@ -7,7 +7,8 @@ import { SketchPicker } from 'react-color';
import ColorPickerControl from
'../../../../src/explore/components/controls/ColorPickerControl';
import ControlHeader from '../../../../src/explore/components/ControlHeader';
-import { registerScheme } from '../../../../src/modules/ColorSchemeManager';
+import getCategoricalSchemeRegistry from
'../../../../src/modules/colors/CategoricalSchemeRegistrySingleton';
+import CategoricalScheme from
'../../../../src/modules/colors/CategoricalScheme';
const defaultProps = {
value: { },
@@ -17,7 +18,11 @@ describe('ColorPickerControl', () => {
let wrapper;
let inst;
beforeEach(() => {
- registerScheme('test', ['red', 'green', 'blue'])
+ getCategoricalSchemeRegistry()
+ .registerValue('test', new CategoricalScheme({
+ name: 'test',
+ colors: ['red', 'green', 'blue'],
+ }))
.setDefaultSchemeName('test');
wrapper = shallow(<ColorPickerControl {...defaultProps} />);
inst = wrapper.instance();
diff --git
a/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
b/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
index 5cf2be2..995bb59 100644
--- a/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
+++ b/superset/assets/spec/javascripts/explore/components/ColorScheme_spec.jsx
@@ -5,10 +5,10 @@ import { Creatable } from 'react-select';
import ColorSchemeControl from
'../../../../src/explore/components/controls/ColorSchemeControl';
-import { getAllSchemes } from '../../../../src/modules/ColorSchemeManager';
+import getCategoricalSchemeRegistry from
'../../../../src/modules/colors/CategoricalSchemeRegistrySingleton';
const defaultProps = {
- options: Object.keys(getAllSchemes()).map(s => ([s, s])),
+ options: getCategoricalSchemeRegistry().keys().map(s => ([s, s])),
};
describe('ColorSchemeControl', () => {
diff --git
a/superset/assets/spec/javascripts/modules/ColorSchemeManager_spec.js
b/superset/assets/spec/javascripts/modules/ColorSchemeManager_spec.js
deleted file mode 100644
index 2f3fe33..0000000
--- a/superset/assets/spec/javascripts/modules/ColorSchemeManager_spec.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import ColorSchemeManager, {
- getInstance,
- getScheme,
- getAllSchemes,
- getDefaultSchemeName,
- setDefaultSchemeName,
- registerScheme,
- registerMultipleSchemes,
-} from '../../../src/modules/ColorSchemeManager';
-
-describe('ColorSchemeManager', () => {
- beforeEach(() => {
- const m = getInstance();
- m.clearScheme();
- m.registerScheme('test', ['red', 'green', 'blue']);
- m.registerScheme('test2', ['orange', 'yellow', 'pink']);
- m.setDefaultSchemeName('test');
- });
- it('The class constructor cannot be accessed directly', () => {
- expect(typeof ColorSchemeManager).not.toBe('Function');
- });
- describe('static getInstance()', () => {
- it('returns a singleton instance', () => {
- const m1 = getInstance();
- const m2 = getInstance();
- expect(m1).toBeDefined();
- expect(m1).toBe(m2);
- });
- });
- describe('.getScheme()', () => {
- it('.getScheme() returns default color scheme', () => {
- const scheme = getInstance().getScheme();
- expect(scheme).toEqual(['red', 'green', 'blue']);
- });
- it('.getScheme(name) returns color scheme with specified name', () => {
- const scheme = getInstance().getScheme('test2');
- expect(scheme).toEqual(['orange', 'yellow', 'pink']);
- });
- });
- describe('.getAllSchemes()', () => {
- it('returns all registered schemes', () => {
- const schemes = getInstance().getAllSchemes();
- expect(schemes).toEqual({
- test: ['red', 'green', 'blue'],
- test2: ['orange', 'yellow', 'pink'],
- });
- });
- });
- describe('.getDefaultSchemeName()', () => {
- it('returns default scheme name', () => {
- const name = getInstance().getDefaultSchemeName();
- expect(name).toBe('test');
- });
- });
- describe('.setDefaultSchemeName()', () => {
- it('set default scheme name', () => {
- getInstance().setDefaultSchemeName('test2');
- const name = getInstance().getDefaultSchemeName();
- expect(name).toBe('test2');
- getInstance().setDefaultSchemeName('test');
- });
- it('returns the ColorSchemeManager instance', () => {
- const instance = getInstance().setDefaultSchemeName('test');
- expect(instance).toBe(getInstance());
- });
- });
- describe('.registerScheme(name, colors)', () => {
- it('sets schemename and color', () => {
- getInstance().registerScheme('test3', ['cyan', 'magenta']);
- const scheme = getInstance().getScheme('test3');
- expect(scheme).toEqual(['cyan', 'magenta']);
- });
- it('returns the ColorSchemeManager instance', () => {
- const instance = getInstance().registerScheme('test3', ['cyan',
'magenta']);
- expect(instance).toBe(getInstance());
- });
- });
- describe('.registerMultipleSchemes(object)', () => {
- it('sets multiple schemes at once', () => {
- getInstance().registerMultipleSchemes({
- test4: ['cyan', 'magenta'],
- test5: ['brown', 'purple'],
- });
- const scheme1 = getInstance().getScheme('test4');
- expect(scheme1).toEqual(['cyan', 'magenta']);
- const scheme2 = getInstance().getScheme('test5');
- expect(scheme2).toEqual(['brown', 'purple']);
- });
- it('returns the ColorSchemeManager instance', () => {
- const instance = getInstance().registerMultipleSchemes({
- test4: ['cyan', 'magenta'],
- test5: ['brown', 'purple'],
- });
- expect(instance).toBe(getInstance());
- });
- });
- describe('static getScheme()', () => {
- it('is equivalent to getInstance().getScheme()', () => {
- expect(getInstance().getScheme()).toBe(getScheme());
- });
- });
- describe('static getAllSchemes()', () => {
- it('is equivalent to getInstance().getAllSchemes()', () => {
- expect(getInstance().getAllSchemes()).toBe(getAllSchemes());
- });
- });
- describe('static getDefaultSchemeName()', () => {
- it('is equivalent to getInstance().getDefaultSchemeName()', () => {
-
expect(getInstance().getDefaultSchemeName()).toBe(getDefaultSchemeName());
- });
- });
- describe('static setDefaultSchemeName()', () => {
- it('is equivalent to getInstance().setDefaultSchemeName()', () => {
- setDefaultSchemeName('test2');
- const name = getInstance().getDefaultSchemeName();
- expect(name).toBe('test2');
- setDefaultSchemeName('test');
- });
- });
- describe('static registerScheme()', () => {
- it('is equivalent to getInstance().registerScheme()', () => {
- registerScheme('test3', ['cyan', 'magenta']);
- const scheme = getInstance().getScheme('test3');
- expect(scheme).toEqual(['cyan', 'magenta']);
- });
- });
- describe('static registerMultipleSchemes()', () => {
- it('is equivalent to getInstance().registerMultipleSchemes()', () => {
- registerMultipleSchemes({
- test4: ['cyan', 'magenta'],
- test5: ['brown', 'purple'],
- });
- const scheme1 = getInstance().getScheme('test4');
- expect(scheme1).toEqual(['cyan', 'magenta']);
- const scheme2 = getInstance().getScheme('test5');
- expect(scheme2).toEqual(['brown', 'purple']);
- });
- });
-});
diff --git a/superset/assets/spec/javascripts/modules/Registry_spec.js
b/superset/assets/spec/javascripts/modules/Registry_spec.js
index 5eb5791..111a614 100644
--- a/superset/assets/spec/javascripts/modules/Registry_spec.js
+++ b/superset/assets/spec/javascripts/modules/Registry_spec.js
@@ -17,6 +17,20 @@ describe('Registry', () => {
});
});
+ describe('.clear()', () => {
+ it('clears all registered items', () => {
+ const registry = new Registry();
+ registry.registerValue('a', 'testValue');
+ registry.clear();
+ expect(Object.keys(registry.items)).toHaveLength(0);
+ expect(Object.keys(registry.promises)).toHaveLength(0);
+ });
+ it('returns the registry itself', () => {
+ const registry = new Registry();
+ expect(registry.clear()).toBe(registry);
+ });
+ });
+
describe('.has(key)', () => {
it('returns true if an item with the given key exists', () => {
const registry = new Registry();
@@ -134,6 +148,34 @@ describe('Registry', () => {
);
});
+ describe('.getMap()', () => {
+ it('returns key-value map as plain object', () => {
+ const registry = new Registry();
+ registry.registerValue('a', 'cat');
+ registry.registerLoader('b', () => 'dog');
+ expect(registry.getMap()).toEqual({
+ a: 'cat',
+ b: 'dog',
+ });
+ });
+ });
+
+ describe('.getMapAsPromise()', () => {
+ it('returns a promise of key-value map', () => {
+ const registry = new Registry();
+ registry.registerValue('a', 'test1');
+ registry.registerLoader('b', () => 'test2');
+ registry.registerLoader('c', () => Promise.resolve('test3'));
+ return registry.getMapAsPromise().then((map) => {
+ expect(map).toEqual({
+ a: 'test1',
+ b: 'test2',
+ c: 'test3',
+ });
+ });
+ });
+ });
+
describe('.keys()', () => {
it('returns an array of keys', () => {
const registry = new Registry();
@@ -143,6 +185,34 @@ describe('Registry', () => {
});
});
+ describe('.values()', () => {
+ it('returns an array of values', () => {
+ const registry = new Registry();
+ registry.registerValue('a', 'test1');
+ registry.registerLoader('b', () => 'test2');
+ expect(registry.values()).toEqual([
+ 'test1',
+ 'test2',
+ ]);
+ });
+ });
+
+ describe('.valuesAsPromise()', () => {
+ it('returns a Promise of an array { key, value }', () => {
+ const registry = new Registry();
+ registry.registerValue('a', 'test1');
+ registry.registerLoader('b', () => 'test2');
+ registry.registerLoader('c', () => Promise.resolve('test3'));
+ return registry.valuesAsPromise().then((entries) => {
+ expect(entries).toEqual([
+ 'test1',
+ 'test2',
+ 'test3',
+ ]);
+ });
+ });
+ });
+
describe('.entries()', () => {
it('returns an array of { key, value }', () => {
const registry = new Registry();
diff --git
a/superset/assets/spec/javascripts/modules/CategoricalColorNameSpace_spec.js
b/superset/assets/spec/javascripts/modules/colors/CategoricalColorNameSpace_spec.js
similarity index 90%
rename from
superset/assets/spec/javascripts/modules/CategoricalColorNameSpace_spec.js
rename to
superset/assets/spec/javascripts/modules/colors/CategoricalColorNameSpace_spec.js
index 0be4996..8ff952a 100644
--- a/superset/assets/spec/javascripts/modules/CategoricalColorNameSpace_spec.js
+++
b/superset/assets/spec/javascripts/modules/colors/CategoricalColorNameSpace_spec.js
@@ -3,13 +3,21 @@ import CategoricalColorNamespace, {
getScale,
getColor,
DEFAULT_NAMESPACE,
-} from '../../../src/modules/CategoricalColorNamespace';
-import { registerScheme } from '../../../src/modules/ColorSchemeManager';
+} from '../../../../src/modules/colors/CategoricalColorNamespace';
+import getCategoricalSchemeRegistry from
'../../../../src/modules/colors/CategoricalSchemeRegistrySingleton';
+import CategoricalScheme from
'../../../../src/modules/colors/CategoricalScheme';
describe('CategoricalColorNamespace', () => {
beforeAll(() => {
- registerScheme('testColors', ['red', 'green', 'blue']);
- registerScheme('testColors2', ['red', 'green', 'blue']);
+ getCategoricalSchemeRegistry()
+ .registerValue('testColors', new CategoricalScheme({
+ name: 'testColors',
+ colors: ['red', 'green', 'blue'],
+ }))
+ .registerValue('testColors2', new CategoricalScheme({
+ name: 'testColors2',
+ colors: ['red', 'green', 'blue'],
+ }));
});
it('The class constructor cannot be accessed directly', () => {
expect(typeof CategoricalColorNamespace).not.toBe('Function');
diff --git
a/superset/assets/spec/javascripts/modules/CategoricalColorScale_spec.js
b/superset/assets/spec/javascripts/modules/colors/CategoricalColorScale_spec.js
similarity index 97%
rename from
superset/assets/spec/javascripts/modules/CategoricalColorScale_spec.js
rename to
superset/assets/spec/javascripts/modules/colors/CategoricalColorScale_spec.js
index 5cbf6e6..32a455d 100644
--- a/superset/assets/spec/javascripts/modules/CategoricalColorScale_spec.js
+++
b/superset/assets/spec/javascripts/modules/colors/CategoricalColorScale_spec.js
@@ -1,4 +1,4 @@
-import CategoricalColorScale from '../../../src/modules/CategoricalColorScale';
+import CategoricalColorScale from
'../../../../src/modules/colors/CategoricalColorScale';
describe('CategoricalColorScale', () => {
it('exists', () => {
diff --git
a/superset/assets/spec/javascripts/modules/colors/ColorSchemeRegistry_spec.js
b/superset/assets/spec/javascripts/modules/colors/ColorSchemeRegistry_spec.js
new file mode 100644
index 0000000..94f6c89
--- /dev/null
+++
b/superset/assets/spec/javascripts/modules/colors/ColorSchemeRegistry_spec.js
@@ -0,0 +1,64 @@
+import ColorSchemeRegistry from
'../../../../src/modules/colors/ColorSchemeRegistry';
+import CategoricalScheme from
'../../../../src/modules/colors/CategoricalScheme';
+
+describe('ColorSchemeRegistry', () => {
+ const registry = new ColorSchemeRegistry();
+ const SCHEME1 = new CategoricalScheme({
+ name: 'test',
+ colors: ['red', 'green', 'blue'],
+ });
+ const SCHEME2 = new CategoricalScheme({
+ name: 'test2',
+ colors: ['orange', 'yellow', 'pink'],
+ });
+ const SCHEME3 = new CategoricalScheme({
+ name: 'test3',
+ colors: ['cyan', 'magenta'],
+ });
+
+ beforeEach(() => {
+ registry.clear();
+ registry.registerValue('test', SCHEME1);
+ registry.registerValue('test2', SCHEME2);
+ registry.setDefaultSchemeName('test');
+ });
+ describe('.get()', () => {
+ it('.get() returns default color scheme', () => {
+ const scheme = registry.get();
+ expect(scheme).toEqual(SCHEME1);
+ });
+ it('.get(name) returns color scheme with specified name', () => {
+ const scheme = registry.get('test2');
+ expect(scheme).toEqual(SCHEME2);
+ });
+ });
+ describe('.getDefaultSchemeName()', () => {
+ it('returns default scheme name', () => {
+ const name = registry.getDefaultSchemeName();
+ expect(name).toBe('test');
+ });
+ });
+ describe('.setDefaultSchemeName()', () => {
+ it('set default scheme name', () => {
+ registry.setDefaultSchemeName('test2');
+ const name = registry.getDefaultSchemeName();
+ expect(name).toBe('test2');
+ registry.setDefaultSchemeName('test');
+ });
+ it('returns the ColorSchemeRegistry instance', () => {
+ const instance = registry.setDefaultSchemeName('test');
+ expect(instance).toBe(registry);
+ });
+ });
+ describe('.registerValue(name, colors)', () => {
+ it('sets schemename and color', () => {
+ registry.registerValue('test3', SCHEME3);
+ const scheme = registry.get('test3');
+ expect(scheme).toEqual(SCHEME3);
+ });
+ it('returns the ColorSchemeRegistry instance', () => {
+ const instance = registry.registerValue('test3', SCHEME3);
+ expect(instance).toBe(registry);
+ });
+ });
+});
diff --git a/superset/assets/src/common.js b/superset/assets/src/common.js
index f479d22..f4f6621 100644
--- a/superset/assets/src/common.js
+++ b/superset/assets/src/common.js
@@ -2,12 +2,8 @@
import $ from 'jquery';
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
import { SupersetClient } from '@superset-ui/core';
-
-import airbnb from './modules/colorSchemes/airbnb';
-import categoricalSchemes from './modules/colorSchemes/categorical';
-import lyft from './modules/colorSchemes/lyft';
-import { getInstance } from './modules/ColorSchemeManager';
import { toggleCheckbox } from './modules/utils';
+import setupColors from './setup/setupColors';
$(document).ready(function () {
$(':checkbox[data-checkbox-api-prefix]').change(function () {
@@ -28,12 +24,7 @@ $(document).ready(function () {
});
});
-// Register color schemes
-getInstance()
- .registerScheme('bnbColors', airbnb.bnbColors)
- .registerMultipleSchemes(categoricalSchemes)
- .registerScheme('lyftColors', lyft.lyftColors)
- .setDefaultSchemeName('bnbColors');
+setupColors();
export function appSetup() {
// A set of hacks to allow apps to run within a FAB template
diff --git a/superset/assets/src/dashboard/reducers/getInitialState.js
b/superset/assets/src/dashboard/reducers/getInitialState.js
index 523db9f..c3b9dfd 100644
--- a/superset/assets/src/dashboard/reducers/getInitialState.js
+++ b/superset/assets/src/dashboard/reducers/getInitialState.js
@@ -18,7 +18,7 @@ import {
CHART_TYPE,
ROW_TYPE,
} from '../util/componentTypes';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
export default function(bootstrapData) {
const { user_id, datasources, common, editMode } = bootstrapData;
diff --git
a/superset/assets/src/explore/components/controls/AnnotationLayer.jsx
b/superset/assets/src/explore/components/controls/AnnotationLayer.jsx
index cbf17a1..5fd580b 100644
--- a/superset/assets/src/explore/components/controls/AnnotationLayer.jsx
+++ b/superset/assets/src/explore/components/controls/AnnotationLayer.jsx
@@ -25,7 +25,7 @@ import { nonEmpty } from '../../validators';
import vizTypes from '../../visTypes';
import { t } from '../../../locales';
-import { getScheme } from '../../../modules/ColorSchemeManager';
+import getCategoricalSchemeRegistry from
'../../../modules/colors/CategoricalSchemeRegistrySingleton';
const AUTOMATIC_COLOR = '';
@@ -484,7 +484,10 @@ export default class AnnotationLayer extends
React.PureComponent {
renderDisplayConfiguration() {
const { color, opacity, style, width, showMarkers, hideLine,
annotationType } = this.state;
- const colorScheme = [...getScheme(this.props.colorScheme)];
+ const colorScheme = getCategoricalSchemeRegistry()
+ .get(this.props.colorScheme)
+ .colors
+ .concat();
if (
color &&
color !== AUTOMATIC_COLOR &&
diff --git
a/superset/assets/src/explore/components/controls/ColorPickerControl.jsx
b/superset/assets/src/explore/components/controls/ColorPickerControl.jsx
index 55d7ce4..2c631c1 100644
--- a/superset/assets/src/explore/components/controls/ColorPickerControl.jsx
+++ b/superset/assets/src/explore/components/controls/ColorPickerControl.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { OverlayTrigger, Popover } from 'react-bootstrap';
import { SketchPicker } from 'react-color';
import ControlHeader from '../ControlHeader';
-import { getScheme } from '../../../modules/ColorSchemeManager';
+import getCategoricalSchemeRegistry from
'../../../modules/colors/CategoricalSchemeRegistrySingleton';
const propTypes = {
onChange: PropTypes.func,
@@ -53,14 +53,19 @@ export default class ColorPickerControl extends
React.Component {
this.props.onChange(col.rgb);
}
renderPopover() {
+ const presetColors = getCategoricalSchemeRegistry()
+ .get()
+ .colors
+ .filter((s, i) => i < 7);
return (
<Popover id="filter-popover" className="color-popover">
<SketchPicker
color={this.props.value}
onChange={this.onChange}
- presetColors={getScheme().filter((s, i) => i < 7)}
+ presetColors={presetColors}
/>
- </Popover>);
+ </Popover>
+ );
}
render() {
const c = this.props.value || { r: 0, g: 0, b: 0, a: 0 };
diff --git
a/superset/assets/src/explore/components/controls/ColorSchemeControl.jsx
b/superset/assets/src/explore/components/controls/ColorSchemeControl.jsx
index f09125d..5d9ad46 100644
--- a/superset/assets/src/explore/components/controls/ColorSchemeControl.jsx
+++ b/superset/assets/src/explore/components/controls/ColorSchemeControl.jsx
@@ -49,7 +49,7 @@ export default class ColorSchemeControl extends
React.PureComponent {
renderOption(key) {
const { schemes } = this.props;
const schemeLookup = isFunction(schemes) ? schemes() : schemes;
- const currentScheme = schemeLookup[key.value || defaultProps.value];
+ const currentScheme = schemeLookup[key.value || defaultProps.value].colors;
let colors = currentScheme;
if (this.props.isLinear) {
diff --git a/superset/assets/src/explore/controls.jsx
b/superset/assets/src/explore/controls.jsx
index 67f21ac..05e4f54 100644
--- a/superset/assets/src/explore/controls.jsx
+++ b/superset/assets/src/explore/controls.jsx
@@ -50,8 +50,11 @@ import { defaultViewport } from '../modules/geo';
import ColumnOption from '../components/ColumnOption';
import OptionDescription from '../components/OptionDescription';
import { t } from '../locales';
-import { getAllSchemes } from '../modules/ColorSchemeManager';
-import sequentialSchemes from '../modules/colorSchemes/sequential';
+import getCategoricalSchemeRegistry from
'../modules/colors/CategoricalSchemeRegistrySingleton';
+import getSequentialSchemeRegistry from
'../modules/colors/SequentialSchemeRegistrySingleton';
+
+const categoricalSchemeRegistry = getCategoricalSchemeRegistry();
+const sequentialSchemeRegistry = getSequentialSchemeRegistry();
const D3_FORMAT_DOCS = 'D3 format syntax: https://github.com/d3/d3-format';
@@ -323,58 +326,14 @@ export const controls = {
linear_color_scheme: {
type: 'ColorSchemeControl',
label: t('Linear Color Scheme'),
- choices: [
- ['fire', 'fire'],
- ['white_black', 'white/black'],
- ['black_white', 'black/white'],
- ['dark_blue', 'light/dark blue'],
- ['pink_grey', 'pink/white/grey'],
- ['greens', 'greens'],
- ['purples', 'purples'],
- ['oranges', 'oranges'],
- ['blue_white_yellow', 'blue/white/yellow'],
- ['red_yellow_blue', 'red/yellowish/blue'],
- ['brown_white_green', 'brown/white/green'],
- ['purple_white_green', 'purple/white/green'],
- ['schemeBrBG', 'brown/green'],
- ['schemePRGn', 'purple/green'],
- ['schemePiYG', 'pink/green'],
- ['schemePuOr', 'purple/orange'],
- ['schemeRdBu', 'red/blue'],
- ['schemeRdGy', 'red/gray/black'],
- ['schemeRdYlBu', 'red/yellow/blue'],
- ['schemeRdYlGn', 'red/yellow/green'],
- ['schemeSpectral', 'rainbow'],
- ['schemeBlues', 'd3/blues'],
- ['schemeGreens', 'd3/greens'],
- ['schemeGrays', 'd3/grays'],
- ['schemeOranges', 'd3/oranges'],
- ['schemePurples', 'd3/purples'],
- ['schemeReds', 'd3/reds'],
- ['schemeViridis', 'd3/purple/blue/green/yellow'],
- ['schemeInferno', 'd3/purple/red/orange/yellow'],
- ['schemeMagma', 'd3/purple/pink/peach'],
- ['schemeWarm', 'd3/warm/purple/pink/yellow/green'],
- ['schemeCool', 'd3/cool/blue/green'],
- ['schemeCubehelixDefault', 'd3/black/green/brown/pink/blue'],
- ['schemeBuGn', 'd3/blue/green'],
- ['schemeBuPu', 'd3/blue/purple'],
- ['schemeGnBu', 'd3/green/blue'],
- ['schemeOrRd', 'd3/orange/red'],
- ['schemePuBuGn', 'd3/purple/blue/green'],
- ['schemePuBu', 'd3/purple/blue'],
- ['schemePuRd', 'd3/purple/red'],
- ['schemeRdPu', 'd3/red/purple'],
- ['schemeYlGnBu', 'd3/yellow/green/blue'],
- ['schemeYlGn', 'd3/yellow/green'],
- ['schemeYlOrBr', 'd3/yellow/brown'],
- ['schemeYlOrRd', 'd3/yellow/orange/red'],
- ],
+ choices: () => sequentialSchemeRegistry
+ .values()
+ .map(value => [value.name, value.label]),
default: 'blue_white_yellow',
clearable: false,
description: '',
renderTrigger: true,
- schemes: sequentialSchemes,
+ schemes: () => sequentialSchemeRegistry.getMap(),
isLinear: true,
},
@@ -1965,9 +1924,9 @@ export const controls = {
label: t('Color Scheme'),
default: 'bnbColors',
renderTrigger: true,
- choices: () => Object.keys(getAllSchemes()).map(s => ([s, s])),
+ choices: () => categoricalSchemeRegistry.keys().map(s => ([s, s])),
description: t('The color scheme for rendering chart'),
- schemes: () => getAllSchemes(),
+ schemes: () => categoricalSchemeRegistry.getMap(),
},
significance_level: {
diff --git a/superset/assets/src/modules/ColorSchemeManager.js
b/superset/assets/src/modules/ColorSchemeManager.js
deleted file mode 100644
index 9d21d26..0000000
--- a/superset/assets/src/modules/ColorSchemeManager.js
+++ /dev/null
@@ -1,86 +0,0 @@
-class ColorSchemeManager {
- constructor() {
- this.schemes = {};
- this.defaultSchemeName = undefined;
- }
-
- clearScheme() {
- this.schemes = {};
- return this;
- }
-
- getScheme(schemeName) {
- return this.schemes[schemeName || this.defaultSchemeName];
- }
-
- getAllSchemes() {
- return this.schemes;
- }
-
- getDefaultSchemeName() {
- return this.defaultSchemeName;
- }
-
- setDefaultSchemeName(schemeName) {
- this.defaultSchemeName = schemeName;
- return this;
- }
-
- registerScheme(schemeName, colors) {
- this.schemes[schemeName] = colors;
- // If there is no default, set as default
- if (!this.defaultSchemeName) {
- this.defaultSchemeName = schemeName;
- }
- return this;
- }
-
- registerMultipleSchemes(multipleSchemes) {
- Object.assign(this.schemes, multipleSchemes);
- // If there is no default, set the first scheme as default
- const keys = Object.keys(multipleSchemes);
- if (!this.defaultSchemeName && keys.length > 0) {
- this.defaultSchemeName = keys[0];
- }
- return this;
- }
-}
-
-let singleton;
-
-export function getInstance() {
- if (!singleton) {
- singleton = new ColorSchemeManager();
- }
- return singleton;
-}
-
-const staticFunctions =
Object.getOwnPropertyNames(ColorSchemeManager.prototype)
- .filter(fn => fn !== 'constructor')
- .reduce((all, fn) => {
- const functions = all;
- functions[fn] = function (...args) {
- return getInstance()[fn](...args);
- };
- return functions;
- }, { getInstance });
-
-const {
- clearScheme,
- getScheme,
- getAllSchemes,
- getDefaultSchemeName,
- setDefaultSchemeName,
- registerScheme,
- registerMultipleSchemes,
-} = staticFunctions;
-
-export {
- clearScheme,
- getScheme,
- getAllSchemes,
- getDefaultSchemeName,
- setDefaultSchemeName,
- registerScheme,
- registerMultipleSchemes,
-};
diff --git a/superset/assets/src/modules/Registry.js
b/superset/assets/src/modules/Registry.js
index f39a0c5..3b9ef44 100644
--- a/superset/assets/src/modules/Registry.js
+++ b/superset/assets/src/modules/Registry.js
@@ -5,6 +5,12 @@ export default class Registry {
this.promises = {};
}
+ clear() {
+ this.items = {};
+ this.promises = {};
+ return this;
+ }
+
has(key) {
const item = this.items[key];
return item !== null && item !== undefined;
@@ -44,10 +50,36 @@ export default class Registry {
return Promise.reject(`Item with key "${key}" is not registered.`);
}
+ getMap() {
+ return this.keys().reduce((prev, key) => {
+ const map = prev;
+ map[key] = this.get(key);
+ return map;
+ }, {});
+ }
+
+ getMapAsPromise() {
+ const keys = this.keys();
+ return Promise.all(keys.map(key => this.getAsPromise(key)))
+ .then(values => values.reduce((prev, value, i) => {
+ const map = prev;
+ map[keys[i]] = value;
+ return map;
+ }, {}));
+ }
+
keys() {
return Object.keys(this.items);
}
+ values() {
+ return this.keys().map(key => this.get(key));
+ }
+
+ valuesAsPromise() {
+ return Promise.all(this.keys().map(key => this.getAsPromise(key)));
+ }
+
entries() {
return this.keys().map(key => ({
key,
diff --git a/superset/assets/src/modules/colorSchemes/airbnb.js
b/superset/assets/src/modules/colorSchemes/airbnb.js
deleted file mode 100644
index d26a923..0000000
--- a/superset/assets/src/modules/colorSchemes/airbnb.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default {
- bnbColors: [
- '#ff5a5f', // rausch
- '#7b0051', // hackb
- '#007A87', // kazan
- '#00d1c1', // babu
- '#8ce071', // lima
- '#ffb400', // beach
- '#b4a76c', // barol
- '#ff8083',
- '#cc0086',
- '#00a1b3',
- '#00ffeb',
- '#bbedab',
- '#ffd266',
- '#cbc29a',
- '#ff3339',
- '#ff1ab1',
- '#005c66',
- '#00b3a5',
- '#55d12e',
- '#b37e00',
- '#988b4e',
- ],
-};
diff --git a/superset/assets/src/modules/colorSchemes/categorical.js
b/superset/assets/src/modules/colorSchemes/categorical.js
deleted file mode 100644
index 946d14a..0000000
--- a/superset/assets/src/modules/colorSchemes/categorical.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import d3 from 'd3';
-
-export default {
- d3Category10: d3.scale.category10().range(),
- d3Category20: d3.scale.category20().range(),
- d3Category20b: d3.scale.category20b().range(),
- d3Category20c: d3.scale.category20c().range(),
- googleCategory10c: [
- '#3366cc',
- '#dc3912',
- '#ff9900',
- '#109618',
- '#990099',
- '#0099c6',
- '#dd4477',
- '#66aa00',
- '#b82e2e',
- '#316395',
- ],
- googleCategory20c: [
- '#3366cc',
- '#dc3912',
- '#ff9900',
- '#109618',
- '#990099',
- '#0099c6',
- '#dd4477',
- '#66aa00',
- '#b82e2e',
- '#316395',
- '#994499',
- '#22aa99',
- '#aaaa11',
- '#6633cc',
- '#e67300',
- '#8b0707',
- '#651067',
- '#329262',
- '#5574a6',
- '#3b3eac',
- ],
-};
diff --git a/superset/assets/src/modules/colorSchemes/lyft.js
b/superset/assets/src/modules/colorSchemes/lyft.js
deleted file mode 100644
index cd94121..0000000
--- a/superset/assets/src/modules/colorSchemes/lyft.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export default {
- lyftColors: [
- '#EA0B8C',
- '#6C838E',
- '#29ABE2',
- '#33D9C1',
- '#9DACB9',
- '#7560AA',
- '#2D5584',
- '#831C4A',
- '#333D47',
- '#AC2077',
- ],
-};
diff --git a/superset/assets/src/modules/colorSchemes/sequential.js
b/superset/assets/src/modules/colorSchemes/sequential.js
deleted file mode 100644
index 6970ed4..0000000
--- a/superset/assets/src/modules/colorSchemes/sequential.js
+++ /dev/null
@@ -1,433 +0,0 @@
-export default {
- blue_white_yellow: [
- '#00d1c1',
- 'white',
- '#ffb400',
- ],
- fire: [
- 'white',
- 'yellow',
- 'red',
- 'black',
- ],
- white_black: [
- 'white',
- 'black',
- ],
- black_white: [
- 'black',
- 'white',
- ],
- dark_blue: [
- '#EBF5F8',
- '#6BB1CC',
- '#357E9B',
- '#1B4150',
- '#092935',
- ],
- pink_grey: [
- '#E70B81',
- '#FAFAFA',
- '#666666',
- ],
- greens: [
- '#ffffcc',
- '#78c679',
- '#006837',
- ],
- purples: [
- '#f2f0f7',
- '#9e9ac8',
- '#54278f',
- ],
- oranges: [
- '#fef0d9',
- '#fc8d59',
- '#b30000',
- ],
- red_yellow_blue: [
- '#d7191c',
- '#fdae61',
- '#ffffbf',
- '#abd9e9',
- '#2c7bb6',
- ],
- brown_white_green: [
- '#a6611a',
- '#dfc27d',
- '#f5f5f5',
- '#80cdc1',
- '#018571',
- ],
- purple_white_green: [
- '#7b3294',
- '#c2a5cf',
- '#f7f7f7',
- '#a6dba0',
- '#008837',
- ],
- schemeBrBG: [
- '#543005',
- '#8c510a',
- '#bf812d',
- '#dfc27d',
- '#f6e8c3',
- '#c7eae5',
- '#80cdc1',
- '#35978f',
- '#01665e',
- '#003c30',
- ],
- schemePRGn: [
- '#40004b',
- '#762a83',
- '#9970ab',
- '#c2a5cf',
- '#e7d4e8',
- '#d9f0d3',
- '#a6dba0',
- '#5aae61',
- '#1b7837',
- '#00441b',
- ],
- schemePiYG: [
- '#8e0152',
- '#c51b7d',
- '#de77ae',
- '#f1b6da',
- '#fde0ef',
- '#e6f5d0',
- '#b8e186',
- '#7fbc41',
- '#4d9221',
- '#276419',
- ],
- schemePuOr: [
- '#2d004b',
- '#542788',
- '#8073ac',
- '#b2abd2',
- '#d8daeb',
- '#fee0b6',
- '#fdb863',
- '#e08214',
- '#b35806',
- '#7f3b08',
- ],
- schemeRdBu: [
- '#67001f',
- '#b2182b',
- '#d6604d',
- '#f4a582',
- '#fddbc7',
- '#d1e5f0',
- '#92c5de',
- '#4393c3',
- '#2166ac',
- '#053061',
- ],
- schemeRdGy: [
- '#67001f',
- '#b2182b',
- '#d6604d',
- '#f4a582',
- '#fddbc7',
- '#e0e0e0',
- '#bababa',
- '#878787',
- '#4d4d4d',
- '#1a1a1a',
- ],
- schemeRdYlBu: [
- '#a50026',
- '#d73027',
- '#f46d43',
- '#fdae61',
- '#fee090',
- '#e0f3f8',
- '#abd9e9',
- '#74add1',
- '#4575b4',
- '#313695',
- ],
- schemeRdYlGn: [
- '#a50026',
- '#d73027',
- '#f46d43',
- '#fdae61',
- '#fee08b',
- '#d9ef8b',
- '#a6d96a',
- '#66bd63',
- '#1a9850',
- '#006837',
- ],
- schemeSpectral: [
- '#9e0142',
- '#d53e4f',
- '#f46d43',
- '#fdae61',
- '#fee08b',
- '#e6f598',
- '#abdda4',
- '#66c2a5',
- '#3288bd',
- '#5e4fa2',
- ],
- schemeBlues: [
- '#b5d4e9',
- '#93c3df',
- '#6daed5',
- '#4b97c9',
- '#2f7ebc',
- '#1864aa',
- '#0a4a90',
- '#08306b',
- ],
- schemeGreens: [
- '#b7e2b1',
- '#97d494',
- '#73c378',
- '#4daf62',
- '#2f984f',
- '#157f3b',
- '#036429',
- '#00441b',
- ],
- schemeGrays: [
- '#cecece',
- '#b4b4b4',
- '#979797',
- '#7a7a7a',
- '#5f5f5f',
- '#404040',
- '#1e1e1e',
- '#000000',
- ],
- schemeOranges: [
- '#fdc28c',
- '#fda762',
- '#fb8d3d',
- '#f2701d',
- '#e25609',
- '#c44103',
- '#9f3303',
- '#7f2704',
- ],
- schemePurples: [
- '#cecee5',
- '#b6b5d8',
- '#9e9bc9',
- '#8782bc',
- '#7363ac',
- '#61409b',
- '#501f8c',
- '#3f007d',
- ],
- schemeReds: [
- '#fcaa8e',
- '#fc8a6b',
- '#f9694c',
- '#ef4533',
- '#d92723',
- '#bb151a',
- '#970b13',
- '#67000d',
- ],
- schemeViridis: [
- '#482475',
- '#414487',
- '#355f8d',
- '#2a788e',
- '#21918c',
- '#22a884',
- '#44bf70',
- '#7ad151',
- '#bddf26',
- '#fde725',
- ],
- schemeInferno: [
- '#160b39',
- '#420a68',
- '#6a176e',
- '#932667',
- '#bc3754',
- '#dd513a',
- '#f37819',
- '#fca50a',
- '#f6d746',
- '#fcffa4',
- ],
- schemeMagma: [
- '#140e36',
- '#3b0f70',
- '#641a80',
- '#8c2981',
- '#b73779',
- '#de4968',
- '#f7705c',
- '#fe9f6d',
- '#fecf92',
- '#fcfdbf',
- ],
- schemeWarm: [
- '#963db3',
- '#bf3caf',
- '#e4419d',
- '#fe4b83',
- '#ff5e63',
- '#ff7847',
- '#fb9633',
- '#e2b72f',
- '#c6d63c',
- '#aff05b',
- ],
- schemeCool: [
- '#6054c8',
- '#4c6edb',
- '#368ce1',
- '#23abd8',
- '#1ac7c2',
- '#1ddfa3',
- '#30ef82',
- '#52f667',
- '#7ff658',
- '#aff05b',
- ],
- schemeCubehelixDefault: [
- '#1a1530',
- '#163d4e',
- '#1f6642',
- '#54792f',
- '#a07949',
- '#d07e93',
- '#cf9cda',
- '#c1caf3',
- '#d2eeef',
- '#ffffff',
- ],
- schemeBuGn: [
- '#b7e4da',
- '#8fd3c1',
- '#68c2a3',
- '#49b17f',
- '#2f9959',
- '#157f3c',
- '#036429',
- '#00441b',
- ],
- schemeBuPu: [
- '#b2cae1',
- '#9cb3d5',
- '#8f95c6',
- '#8c74b5',
- '#8952a5',
- '#852d8f',
- '#730f71',
- '#4d004b',
- ],
- schemeGnBu: [
- '#bde5bf',
- '#9ed9bb',
- '#7bcbc4',
- '#58b7cd',
- '#399cc6',
- '#1d7eb7',
- '#0b60a1',
- '#084081',
- ],
- schemeOrRd: [
- '#fdca94',
- '#fdb07a',
- '#fa8e5d',
- '#f16c49',
- '#e04530',
- '#c81d13',
- '#a70403',
- '#7f0000',
- ],
- schemePuBuGn: [
- '#bec9e2',
- '#98b9d9',
- '#69a8cf',
- '#4096c0',
- '#19879f',
- '#037877',
- '#016353',
- '#014636',
- ],
- schemePuBu: [
- '#bfc9e2',
- '#9bb9d9',
- '#72a8cf',
- '#4394c3',
- '#1a7db6',
- '#0667a1',
- '#045281',
- '#023858',
- ],
- schemePuRd: [
- '#d0aad2',
- '#d08ac2',
- '#dd63ae',
- '#e33890',
- '#d71c6c',
- '#b70b4f',
- '#8f023a',
- '#67001f',
- ],
- schemeRdPu: [
- '#fbb5bc',
- '#f993b0',
- '#f369a3',
- '#e03e98',
- '#c01788',
- '#99037c',
- '#700174',
- '#49006a',
- ],
- schemeYlGnBu: [
- '#d5eeb3',
- '#a9ddb7',
- '#73c9bd',
- '#45b4c2',
- '#2897bf',
- '#2073b2',
- '#234ea0',
- '#1c3185',
- '#081d58',
- ],
- schemeYlGn: [
- '#e4f4ac',
- '#c7e89b',
- '#a2d88a',
- '#78c578',
- '#4eaf63',
- '#2f944e',
- '#15793f',
- '#036034',
- '#004529',
- ],
- schemeYlOrBr: [
- '#feeaa1',
- '#fed676',
- '#feba4a',
- '#fb992c',
- '#ee7918',
- '#d85b0a',
- '#b74304',
- '#8f3204',
- '#662506',
- ],
- schemeYlOrRd: [
- '#fee087',
- '#fec965',
- '#feab4b',
- '#fd893c',
- '#fa5c2e',
- '#ec3023',
- '#d31121',
- '#af0225',
- '#800026',
- ],
-};
diff --git a/superset/assets/src/modules/colors.js
b/superset/assets/src/modules/colors.js
index 8e86d46..19cd351 100644
--- a/superset/assets/src/modules/colors.js
+++ b/superset/assets/src/modules/colors.js
@@ -1,5 +1,5 @@
import d3 from 'd3';
-import sequentialSchemes from './colorSchemes/sequential';
+import getSequentialSchemeRegistry from
'./colors/SequentialSchemeRegistrySingleton';
export const BRAND_COLOR = '#00A699';
export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 };
@@ -18,7 +18,7 @@ export const colorScalerFactory = function (colors, data,
accessor, extents, out
// Returns a linear scaler our of an array of color
if (!Array.isArray(colors)) {
/* eslint no-param-reassign: 0 */
- colors = sequentialSchemes[colors];
+ colors = getSequentialSchemeRegistry().get(colors).colors;
}
let ext = [0, 1];
if (extents) {
diff --git a/superset/assets/src/modules/CategoricalColorNamespace.js
b/superset/assets/src/modules/colors/CategoricalColorNamespace.js
similarity index 85%
rename from superset/assets/src/modules/CategoricalColorNamespace.js
rename to superset/assets/src/modules/colors/CategoricalColorNamespace.js
index d022bb2..ea5ea93 100644
--- a/superset/assets/src/modules/CategoricalColorNamespace.js
+++ b/superset/assets/src/modules/colors/CategoricalColorNamespace.js
@@ -1,5 +1,5 @@
import CategoricalColorScale from './CategoricalColorScale';
-import { getScheme, getDefaultSchemeName } from './ColorSchemeManager';
+import getCategoricalSchemeRegistry from
'./CategoricalSchemeRegistrySingleton';
class CategoricalColorNamespace {
constructor(name) {
@@ -9,13 +9,13 @@ class CategoricalColorNamespace {
}
getScale(schemeName) {
- const name = schemeName || getDefaultSchemeName();
+ const name = schemeName ||
getCategoricalSchemeRegistry().getDefaultSchemeName();
const scale = this.scales[name];
if (scale) {
return scale;
}
const newScale = new CategoricalColorScale(
- getScheme(name),
+ getCategoricalSchemeRegistry().get(name).colors,
this.forcedItems,
);
this.scales[name] = newScale;
diff --git a/superset/assets/src/modules/CategoricalColorScale.js
b/superset/assets/src/modules/colors/CategoricalColorScale.js
similarity index 96%
rename from superset/assets/src/modules/CategoricalColorScale.js
rename to superset/assets/src/modules/colors/CategoricalColorScale.js
index eab70d2..69d8ab2 100644
--- a/superset/assets/src/modules/CategoricalColorScale.js
+++ b/superset/assets/src/modules/colors/CategoricalColorScale.js
@@ -1,4 +1,4 @@
-import { TIME_SHIFT_PATTERN } from '../utils/common';
+import { TIME_SHIFT_PATTERN } from '../../utils/common';
export function cleanValue(value) {
// for superset series that should have the same color
diff --git a/superset/assets/src/modules/colors/CategoricalScheme.js
b/superset/assets/src/modules/colors/CategoricalScheme.js
new file mode 100644
index 0000000..c70ee58
--- /dev/null
+++ b/superset/assets/src/modules/colors/CategoricalScheme.js
@@ -0,0 +1,3 @@
+import ColorScheme from './ColorScheme';
+
+export default class CategoricalScheme extends ColorScheme {}
diff --git
a/superset/assets/src/modules/colors/CategoricalSchemeRegistrySingleton.js
b/superset/assets/src/modules/colors/CategoricalSchemeRegistrySingleton.js
new file mode 100644
index 0000000..5417180
--- /dev/null
+++ b/superset/assets/src/modules/colors/CategoricalSchemeRegistrySingleton.js
@@ -0,0 +1,8 @@
+import ColorSchemeRegistry from './ColorSchemeRegistry';
+import makeSingleton from '../../utils/makeSingleton';
+
+class CategoricalSchemeRegistry extends ColorSchemeRegistry {}
+
+const getInstance = makeSingleton(CategoricalSchemeRegistry);
+
+export default getInstance;
diff --git a/superset/assets/src/modules/colors/ColorScheme.js
b/superset/assets/src/modules/colors/ColorScheme.js
new file mode 100644
index 0000000..91936a0
--- /dev/null
+++ b/superset/assets/src/modules/colors/ColorScheme.js
@@ -0,0 +1,15 @@
+import isRequired from '../../utils/isRequired';
+
+export default class ColorScheme {
+ constructor({
+ name = isRequired('name'),
+ label,
+ colors = isRequired('colors'),
+ description = '',
+ }) {
+ this.name = name;
+ this.label = label || name;
+ this.colors = colors;
+ this.description = description;
+ }
+}
diff --git a/superset/assets/src/modules/colors/ColorSchemeRegistry.js
b/superset/assets/src/modules/colors/ColorSchemeRegistry.js
new file mode 100644
index 0000000..59d798d
--- /dev/null
+++ b/superset/assets/src/modules/colors/ColorSchemeRegistry.js
@@ -0,0 +1,36 @@
+import Registry from '../Registry';
+
+class ColorSchemeRegistry extends Registry {
+ getDefaultSchemeName() {
+ return this.defaultSchemeName;
+ }
+
+ setDefaultSchemeName(schemeName) {
+ this.defaultSchemeName = schemeName;
+ return this;
+ }
+
+ get(schemeName) {
+ return super.get(schemeName || this.defaultSchemeName);
+ }
+
+ registerValue(schemeName, colors) {
+ super.registerValue(schemeName, colors);
+ // If there is no default, set as default
+ if (!this.defaultSchemeName) {
+ this.defaultSchemeName = schemeName;
+ }
+ return this;
+ }
+
+ registerLoader(schemeName, loader) {
+ super.registerLoader(schemeName, loader);
+ // If there is no default, set as default
+ if (!this.defaultSchemeName) {
+ this.defaultSchemeName = schemeName;
+ }
+ return this;
+ }
+}
+
+export default ColorSchemeRegistry;
diff --git a/superset/assets/src/modules/colors/SequentialScheme.js
b/superset/assets/src/modules/colors/SequentialScheme.js
new file mode 100644
index 0000000..27ad849
--- /dev/null
+++ b/superset/assets/src/modules/colors/SequentialScheme.js
@@ -0,0 +1,9 @@
+import ColorScheme from './ColorScheme';
+
+export default class SequentialScheme extends ColorScheme {
+ constructor(input) {
+ super(input);
+ const { isDiverging = false } = input;
+ this.isDiverging = isDiverging;
+ }
+}
diff --git
a/superset/assets/src/modules/colors/SequentialSchemeRegistrySingleton.js
b/superset/assets/src/modules/colors/SequentialSchemeRegistrySingleton.js
new file mode 100644
index 0000000..6ba5202
--- /dev/null
+++ b/superset/assets/src/modules/colors/SequentialSchemeRegistrySingleton.js
@@ -0,0 +1,8 @@
+import ColorSchemeRegistry from './ColorSchemeRegistry';
+import makeSingleton from '../../utils/makeSingleton';
+
+class SequentialSchemeRegistry extends ColorSchemeRegistry {}
+
+const getInstance = makeSingleton(SequentialSchemeRegistry);
+
+export default getInstance;
diff --git
a/superset/assets/src/modules/colors/colorSchemes/categorical/airbnb.js
b/superset/assets/src/modules/colors/colorSchemes/categorical/airbnb.js
new file mode 100644
index 0000000..2047624
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/categorical/airbnb.js
@@ -0,0 +1,32 @@
+import CategoricalScheme from '../../CategoricalScheme';
+
+const schemes = [
+ {
+ name: 'bnbColors',
+ colors: [
+ '#ff5a5f', // rausch
+ '#7b0051', // hackb
+ '#007A87', // kazan
+ '#00d1c1', // babu
+ '#8ce071', // lima
+ '#ffb400', // beach
+ '#b4a76c', // barol
+ '#ff8083',
+ '#cc0086',
+ '#00a1b3',
+ '#00ffeb',
+ '#bbedab',
+ '#ffd266',
+ '#cbc29a',
+ '#ff3339',
+ '#ff1ab1',
+ '#005c66',
+ '#00b3a5',
+ '#55d12e',
+ '#b37e00',
+ '#988b4e',
+ ],
+ },
+].map(s => new CategoricalScheme(s));
+
+export default schemes;
diff --git a/superset/assets/src/modules/colors/colorSchemes/categorical/d3.js
b/superset/assets/src/modules/colors/colorSchemes/categorical/d3.js
new file mode 100644
index 0000000..deac97a
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/categorical/d3.js
@@ -0,0 +1,23 @@
+import d3 from 'd3';
+import CategoricalScheme from '../../CategoricalScheme';
+
+const schemes = [
+ {
+ name: 'd3Category10',
+ colors: d3.scale.category10().range(),
+ },
+ {
+ name: 'd3Category20',
+ colors: d3.scale.category20().range(),
+ },
+ {
+ name: 'd3Category20b',
+ colors: d3.scale.category20b().range(),
+ },
+ {
+ name: 'd3Category20c',
+ colors: d3.scale.category20c().range(),
+ },
+].map(s => new CategoricalScheme(s));
+
+export default schemes;
diff --git
a/superset/assets/src/modules/colors/colorSchemes/categorical/google.js
b/superset/assets/src/modules/colors/colorSchemes/categorical/google.js
new file mode 100644
index 0000000..b4195db
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/categorical/google.js
@@ -0,0 +1,46 @@
+import CategoricalScheme from '../../CategoricalScheme';
+
+const schemes = [
+ {
+ name: 'googleCategory10c',
+ colors: [
+ '#3366cc',
+ '#dc3912',
+ '#ff9900',
+ '#109618',
+ '#990099',
+ '#0099c6',
+ '#dd4477',
+ '#66aa00',
+ '#b82e2e',
+ '#316395',
+ ],
+ },
+ {
+ name: 'googleCategory20c',
+ colors: [
+ '#3366cc',
+ '#dc3912',
+ '#ff9900',
+ '#109618',
+ '#990099',
+ '#0099c6',
+ '#dd4477',
+ '#66aa00',
+ '#b82e2e',
+ '#316395',
+ '#994499',
+ '#22aa99',
+ '#aaaa11',
+ '#6633cc',
+ '#e67300',
+ '#8b0707',
+ '#651067',
+ '#329262',
+ '#5574a6',
+ '#3b3eac',
+ ],
+ },
+].map(s => new CategoricalScheme(s));
+
+export default schemes;
diff --git
a/superset/assets/src/modules/colors/colorSchemes/categorical/lyft.js
b/superset/assets/src/modules/colors/colorSchemes/categorical/lyft.js
new file mode 100644
index 0000000..cb81cbb
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/categorical/lyft.js
@@ -0,0 +1,21 @@
+import CategoricalScheme from '../../CategoricalScheme';
+
+const schemes = [
+ {
+ name: 'lyftColors',
+ colors: [
+ '#EA0B8C',
+ '#6C838E',
+ '#29ABE2',
+ '#33D9C1',
+ '#9DACB9',
+ '#7560AA',
+ '#2D5584',
+ '#831C4A',
+ '#333D47',
+ '#AC2077',
+ ],
+ },
+].map(s => new CategoricalScheme(s));
+
+export default schemes;
diff --git
a/superset/assets/src/modules/colors/colorSchemes/sequential/common.js
b/superset/assets/src/modules/colors/colorSchemes/sequential/common.js
new file mode 100644
index 0000000..b5c4a24
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/sequential/common.js
@@ -0,0 +1,121 @@
+import SequentialScheme from '../../SequentialScheme';
+
+const schemes = [
+ {
+ name: 'blue_white_yellow',
+ label: 'blue/white/yellow',
+ colors: [
+ '#00d1c1',
+ 'white',
+ '#ffb400',
+ ],
+ },
+ {
+ name: 'fire',
+ colors: [
+ 'white',
+ 'yellow',
+ 'red',
+ 'black',
+ ],
+ },
+ {
+ name: 'white_black',
+ label: 'white/black',
+ colors: [
+ 'white',
+ 'black',
+ ],
+ },
+ {
+ name: 'black_white',
+ label: 'black/white',
+ colors: [
+ 'black',
+ 'white',
+ ],
+ },
+ {
+ name: 'dark_blue',
+ label: 'dark blues',
+ colors: [
+ '#EBF5F8',
+ '#6BB1CC',
+ '#357E9B',
+ '#1B4150',
+ '#092935',
+ ],
+ },
+ {
+ name: 'pink_grey',
+ label: 'pink/grey',
+ colors: [
+ '#E70B81',
+ '#FAFAFA',
+ '#666666',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'greens',
+ colors: [
+ '#ffffcc',
+ '#78c679',
+ '#006837',
+ ],
+ },
+ {
+ name: 'purples',
+ colors: [
+ '#f2f0f7',
+ '#9e9ac8',
+ '#54278f',
+ ],
+ },
+ {
+ name: 'oranges',
+ colors: [
+ '#fef0d9',
+ '#fc8d59',
+ '#b30000',
+ ],
+ },
+ {
+ name: 'red_yellow_blue',
+ label: 'red/yellow/blue',
+ colors: [
+ '#d7191c',
+ '#fdae61',
+ '#ffffbf',
+ '#abd9e9',
+ '#2c7bb6',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'brown_white_green',
+ label: 'brown/white/green',
+ colors: [
+ '#a6611a',
+ '#dfc27d',
+ '#f5f5f5',
+ '#80cdc1',
+ '#018571',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'purple_white_green',
+ label: 'purple/white/green',
+ colors: [
+ '#7b3294',
+ '#c2a5cf',
+ '#f7f7f7',
+ '#a6dba0',
+ '#008837',
+ ],
+ isDiverging: true,
+ },
+].map(s => new SequentialScheme(s));
+
+export default schemes;
diff --git a/superset/assets/src/modules/colors/colorSchemes/sequential/d3.js
b/superset/assets/src/modules/colors/colorSchemes/sequential/d3.js
new file mode 100644
index 0000000..e811b63
--- /dev/null
+++ b/superset/assets/src/modules/colors/colorSchemes/sequential/d3.js
@@ -0,0 +1,510 @@
+import SequentialScheme from '../../SequentialScheme';
+
+const schemes = [
+ {
+ name: 'schemeBrBG',
+ label: 'brown/green',
+ colors: [
+ '#543005',
+ '#8c510a',
+ '#bf812d',
+ '#dfc27d',
+ '#f6e8c3',
+ '#c7eae5',
+ '#80cdc1',
+ '#35978f',
+ '#01665e',
+ '#003c30',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemePRGn',
+ label: 'purple/green',
+ colors: [
+ '#40004b',
+ '#762a83',
+ '#9970ab',
+ '#c2a5cf',
+ '#e7d4e8',
+ '#d9f0d3',
+ '#a6dba0',
+ '#5aae61',
+ '#1b7837',
+ '#00441b',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemePiYG',
+ label: 'pink/green',
+ colors: [
+ '#8e0152',
+ '#c51b7d',
+ '#de77ae',
+ '#f1b6da',
+ '#fde0ef',
+ '#e6f5d0',
+ '#b8e186',
+ '#7fbc41',
+ '#4d9221',
+ '#276419',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemePuOr',
+ label: 'purple/orange',
+ colors: [
+ '#2d004b',
+ '#542788',
+ '#8073ac',
+ '#b2abd2',
+ '#d8daeb',
+ '#fee0b6',
+ '#fdb863',
+ '#e08214',
+ '#b35806',
+ '#7f3b08',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemeRdBu',
+ label: 'red/blue',
+ colors: [
+ '#67001f',
+ '#b2182b',
+ '#d6604d',
+ '#f4a582',
+ '#fddbc7',
+ '#d1e5f0',
+ '#92c5de',
+ '#4393c3',
+ '#2166ac',
+ '#053061',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemeRdGy',
+ label: 'red/gray/black',
+ colors: [
+ '#67001f',
+ '#b2182b',
+ '#d6604d',
+ '#f4a582',
+ '#fddbc7',
+ '#e0e0e0',
+ '#bababa',
+ '#878787',
+ '#4d4d4d',
+ '#1a1a1a',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemeRdYlBu',
+ label: 'red/yellow/blue',
+ colors: [
+ '#a50026',
+ '#d73027',
+ '#f46d43',
+ '#fdae61',
+ '#fee090',
+ '#e0f3f8',
+ '#abd9e9',
+ '#74add1',
+ '#4575b4',
+ '#313695',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemeRdYlGn',
+ label: 'red/yellow/green',
+ colors: [
+ '#a50026',
+ '#d73027',
+ '#f46d43',
+ '#fdae61',
+ '#fee08b',
+ '#d9ef8b',
+ '#a6d96a',
+ '#66bd63',
+ '#1a9850',
+ '#006837',
+ ],
+ isDiverging: true,
+ },
+ {
+ name: 'schemeSpectral',
+ label: 'rainbow',
+ colors: [
+ '#9e0142',
+ '#d53e4f',
+ '#f46d43',
+ '#fdae61',
+ '#fee08b',
+ '#e6f598',
+ '#abdda4',
+ '#66c2a5',
+ '#3288bd',
+ '#5e4fa2',
+ ],
+ },
+ {
+ name: 'schemeBlues',
+ label: 'blues',
+ colors: [
+ '#b5d4e9',
+ '#93c3df',
+ '#6daed5',
+ '#4b97c9',
+ '#2f7ebc',
+ '#1864aa',
+ '#0a4a90',
+ '#08306b',
+ ],
+ },
+ {
+ name: 'schemeGreens',
+ label: 'greens',
+ colors: [
+ '#b7e2b1',
+ '#97d494',
+ '#73c378',
+ '#4daf62',
+ '#2f984f',
+ '#157f3b',
+ '#036429',
+ '#00441b',
+ ],
+ },
+ {
+ name: 'schemeGrays',
+ label: 'grays',
+ colors: [
+ '#cecece',
+ '#b4b4b4',
+ '#979797',
+ '#7a7a7a',
+ '#5f5f5f',
+ '#404040',
+ '#1e1e1e',
+ '#000000',
+ ],
+ },
+ {
+ name: 'schemeOranges',
+ label: 'oranges',
+ colors: [
+ '#fdc28c',
+ '#fda762',
+ '#fb8d3d',
+ '#f2701d',
+ '#e25609',
+ '#c44103',
+ '#9f3303',
+ '#7f2704',
+ ],
+ },
+ {
+ name: 'schemePurples',
+ label: 'purples',
+ colors: [
+ '#cecee5',
+ '#b6b5d8',
+ '#9e9bc9',
+ '#8782bc',
+ '#7363ac',
+ '#61409b',
+ '#501f8c',
+ '#3f007d',
+ ],
+ },
+ {
+ name: 'schemeReds',
+ label: 'reds',
+ colors: [
+ '#fcaa8e',
+ '#fc8a6b',
+ '#f9694c',
+ '#ef4533',
+ '#d92723',
+ '#bb151a',
+ '#970b13',
+ '#67000d',
+ ],
+ },
+ {
+ name: 'schemeViridis',
+ label: 'Viridis',
+ colors: [
+ '#482475',
+ '#414487',
+ '#355f8d',
+ '#2a788e',
+ '#21918c',
+ '#22a884',
+ '#44bf70',
+ '#7ad151',
+ '#bddf26',
+ '#fde725',
+ ],
+ },
+ {
+ name: 'schemeInferno',
+ label: 'Inferno',
+ colors: [
+ '#160b39',
+ '#420a68',
+ '#6a176e',
+ '#932667',
+ '#bc3754',
+ '#dd513a',
+ '#f37819',
+ '#fca50a',
+ '#f6d746',
+ '#fcffa4',
+ ],
+ },
+ {
+ name: 'schemeMagma',
+ label: 'Magma',
+ colors: [
+ '#140e36',
+ '#3b0f70',
+ '#641a80',
+ '#8c2981',
+ '#b73779',
+ '#de4968',
+ '#f7705c',
+ '#fe9f6d',
+ '#fecf92',
+ '#fcfdbf',
+ ],
+ },
+ {
+ name: 'schemeWarm',
+ label: 'Warm',
+ colors: [
+ '#963db3',
+ '#bf3caf',
+ '#e4419d',
+ '#fe4b83',
+ '#ff5e63',
+ '#ff7847',
+ '#fb9633',
+ '#e2b72f',
+ '#c6d63c',
+ '#aff05b',
+ ],
+ },
+ {
+ name: 'schemeCool',
+ label: 'Cool',
+ colors: [
+ '#6054c8',
+ '#4c6edb',
+ '#368ce1',
+ '#23abd8',
+ '#1ac7c2',
+ '#1ddfa3',
+ '#30ef82',
+ '#52f667',
+ '#7ff658',
+ '#aff05b',
+ ],
+ },
+ {
+ name: 'schemeCubehelixDefault',
+ label: 'Cube Helix',
+ colors: [
+ '#1a1530',
+ '#163d4e',
+ '#1f6642',
+ '#54792f',
+ '#a07949',
+ '#d07e93',
+ '#cf9cda',
+ '#c1caf3',
+ '#d2eeef',
+ '#ffffff',
+ ],
+ },
+ {
+ name: 'schemeBuGn',
+ label: 'blue/green',
+ colors: [
+ '#b7e4da',
+ '#8fd3c1',
+ '#68c2a3',
+ '#49b17f',
+ '#2f9959',
+ '#157f3c',
+ '#036429',
+ '#00441b',
+ ],
+ },
+ {
+ name: 'schemeBuPu',
+ label: 'blue/purple',
+ colors: [
+ '#b2cae1',
+ '#9cb3d5',
+ '#8f95c6',
+ '#8c74b5',
+ '#8952a5',
+ '#852d8f',
+ '#730f71',
+ '#4d004b',
+ ],
+ },
+ {
+ name: 'schemeGnBu',
+ label: 'green/blue',
+ colors: [
+ '#bde5bf',
+ '#9ed9bb',
+ '#7bcbc4',
+ '#58b7cd',
+ '#399cc6',
+ '#1d7eb7',
+ '#0b60a1',
+ '#084081',
+ ],
+ },
+ {
+ name: 'schemeOrRd',
+ label: 'orange/red',
+ colors: [
+ '#fdca94',
+ '#fdb07a',
+ '#fa8e5d',
+ '#f16c49',
+ '#e04530',
+ '#c81d13',
+ '#a70403',
+ '#7f0000',
+ ],
+ },
+ {
+ name: 'schemePuBuGn',
+ label: 'purple/blue/green',
+ colors: [
+ '#bec9e2',
+ '#98b9d9',
+ '#69a8cf',
+ '#4096c0',
+ '#19879f',
+ '#037877',
+ '#016353',
+ '#014636',
+ ],
+ },
+ {
+ name: 'schemePuBu',
+ label: 'purple/blue',
+ colors: [
+ '#bfc9e2',
+ '#9bb9d9',
+ '#72a8cf',
+ '#4394c3',
+ '#1a7db6',
+ '#0667a1',
+ '#045281',
+ '#023858',
+ ],
+ },
+ {
+ name: 'schemePuRd',
+ label: 'purple/red',
+ colors: [
+ '#d0aad2',
+ '#d08ac2',
+ '#dd63ae',
+ '#e33890',
+ '#d71c6c',
+ '#b70b4f',
+ '#8f023a',
+ '#67001f',
+ ],
+ },
+ {
+ name: 'schemeRdPu',
+ label: 'red/purple',
+ colors: [
+ '#fbb5bc',
+ '#f993b0',
+ '#f369a3',
+ '#e03e98',
+ '#c01788',
+ '#99037c',
+ '#700174',
+ '#49006a',
+ ],
+ },
+ {
+ name: 'schemeYlGnBu',
+ label: 'yellow/green/blue',
+ colors: [
+ '#d5eeb3',
+ '#a9ddb7',
+ '#73c9bd',
+ '#45b4c2',
+ '#2897bf',
+ '#2073b2',
+ '#234ea0',
+ '#1c3185',
+ '#081d58',
+ ],
+ },
+ {
+ name: 'schemeYlGn',
+ label: 'yellow/green',
+ colors: [
+ '#e4f4ac',
+ '#c7e89b',
+ '#a2d88a',
+ '#78c578',
+ '#4eaf63',
+ '#2f944e',
+ '#15793f',
+ '#036034',
+ '#004529',
+ ],
+ },
+ {
+ name: 'schemeYlOrBr',
+ label: 'yellow/orange/brown',
+ colors: [
+ '#feeaa1',
+ '#fed676',
+ '#feba4a',
+ '#fb992c',
+ '#ee7918',
+ '#d85b0a',
+ '#b74304',
+ '#8f3204',
+ '#662506',
+ ],
+ },
+ {
+ name: 'schemeYlOrRd',
+ label: 'yellow/orange/red',
+ colors: [
+ '#fee087',
+ '#fec965',
+ '#feab4b',
+ '#fd893c',
+ '#fa5c2e',
+ '#ec3023',
+ '#d31121',
+ '#af0225',
+ '#800026',
+ ],
+ },
+].map(s => new SequentialScheme(s));
+
+export default schemes;
diff --git a/superset/assets/src/setup/setupColors.js
b/superset/assets/src/setup/setupColors.js
new file mode 100644
index 0000000..e51ea3d
--- /dev/null
+++ b/superset/assets/src/setup/setupColors.js
@@ -0,0 +1,26 @@
+import airbnb from '../modules/colors/colorSchemes/categorical/airbnb';
+import categoricalD3 from '../modules/colors/colorSchemes/categorical/d3';
+import google from '../modules/colors/colorSchemes/categorical/google';
+import lyft from '../modules/colors/colorSchemes/categorical/lyft';
+import sequentialCommon from
'../modules/colors/colorSchemes/sequential/common';
+import sequentialD3 from '../modules/colors/colorSchemes/sequential/d3';
+import getCategoricalSchemeRegistry from
'../modules/colors/CategoricalSchemeRegistrySingleton';
+import getSequentialSchemeRegistry from
'../modules/colors/SequentialSchemeRegistrySingleton';
+
+export default function setupColors() {
+ // Register color schemes
+ const categoricalSchemeRegistry = getCategoricalSchemeRegistry();
+ [airbnb, categoricalD3, google, lyft].forEach((group) => {
+ group.forEach((scheme) => {
+ categoricalSchemeRegistry.registerValue(scheme.name, scheme);
+ });
+ });
+ categoricalSchemeRegistry.setDefaultSchemeName('bnbColors');
+
+ const sequentialSchemeRegistry = getSequentialSchemeRegistry();
+ [sequentialCommon, sequentialD3].forEach((group) => {
+ group.forEach((scheme) => {
+ sequentialSchemeRegistry.registerValue(scheme.name, scheme);
+ });
+ });
+}
diff --git a/superset/assets/src/visualizations/Chord/Chord.js
b/superset/assets/src/visualizations/Chord/Chord.js
index cb5ae6d..e650262 100644
--- a/superset/assets/src/visualizations/Chord/Chord.js
+++ b/superset/assets/src/visualizations/Chord/Chord.js
@@ -1,7 +1,7 @@
/* eslint-disable no-param-reassign */
import d3 from 'd3';
import PropTypes from 'prop-types';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import './Chord.css';
const propTypes = {
diff --git a/superset/assets/src/visualizations/Histogram/Histogram.jsx
b/superset/assets/src/visualizations/Histogram/Histogram.jsx
index 34540bb..0b896d7 100644
--- a/superset/assets/src/visualizations/Histogram/Histogram.jsx
+++ b/superset/assets/src/visualizations/Histogram/Histogram.jsx
@@ -5,7 +5,7 @@ import { chartTheme } from '@data-ui/theme';
import { LegendOrdinal } from '@vx/legend';
import { scaleOrdinal } from '@vx/scale';
import WithLegend from '../WithLegend';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
const propTypes = {
className: PropTypes.string,
diff --git a/superset/assets/src/visualizations/Partition/Partition.js
b/superset/assets/src/visualizations/Partition/Partition.js
index 9093d55..03b4df0 100644
--- a/superset/assets/src/visualizations/Partition/Partition.js
+++ b/superset/assets/src/visualizations/Partition/Partition.js
@@ -2,7 +2,7 @@
import d3 from 'd3';
import PropTypes from 'prop-types';
import { hierarchy } from 'd3-hierarchy';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import { d3TimeFormatPreset } from '../../modules/utils';
import './Partition.css';
diff --git a/superset/assets/src/visualizations/Rose/Rose.js
b/superset/assets/src/visualizations/Rose/Rose.js
index 3c76d8f..2d48c5b 100644
--- a/superset/assets/src/visualizations/Rose/Rose.js
+++ b/superset/assets/src/visualizations/Rose/Rose.js
@@ -2,7 +2,7 @@
import d3 from 'd3';
import PropTypes from 'prop-types';
import nv from 'nvd3';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import { d3TimeFormatPreset } from '../../modules/utils';
import './Rose.css';
diff --git a/superset/assets/src/visualizations/Sankey/Sankey.js
b/superset/assets/src/visualizations/Sankey/Sankey.js
index 0efca77..405f1b5 100644
--- a/superset/assets/src/visualizations/Sankey/Sankey.js
+++ b/superset/assets/src/visualizations/Sankey/Sankey.js
@@ -2,7 +2,7 @@
import d3 from 'd3';
import PropTypes from 'prop-types';
import { sankey as d3Sankey } from 'd3-sankey';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import './Sankey.css';
const propTypes = {
diff --git a/superset/assets/src/visualizations/Sunburst/Sunburst.js
b/superset/assets/src/visualizations/Sunburst/Sunburst.js
index f557d8d..3cd9512 100644
--- a/superset/assets/src/visualizations/Sunburst/Sunburst.js
+++ b/superset/assets/src/visualizations/Sunburst/Sunburst.js
@@ -1,7 +1,7 @@
/* eslint-disable no-param-reassign */
import d3 from 'd3';
import PropTypes from 'prop-types';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import { wrapSvgText } from '../../modules/utils';
import './Sunburst.css';
diff --git a/superset/assets/src/visualizations/Treemap/Treemap.js
b/superset/assets/src/visualizations/Treemap/Treemap.js
index 3596357..0ceef27 100644
--- a/superset/assets/src/visualizations/Treemap/Treemap.js
+++ b/superset/assets/src/visualizations/Treemap/Treemap.js
@@ -1,7 +1,7 @@
/* eslint-disable no-shadow, no-param-reassign */
import d3 from 'd3';
import PropTypes from 'prop-types';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import './Treemap.css';
// Declare PropTypes for recursive data structures
diff --git
a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
index dd42017..49e37af 100644
--- a/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
+++ b/superset/assets/src/visualizations/deckgl/CategoricalDeckGLContainer.jsx
@@ -2,11 +2,9 @@
import React from 'react';
import PropTypes from 'prop-types';
-
import AnimatableDeckGLContainer from './AnimatableDeckGLContainer';
import Legend from '../Legend';
-
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
import { hexToRGB } from '../../modules/colors';
import { getPlaySliderParams } from '../../modules/time';
import sandboxedEval from '../../modules/sandbox';
diff --git a/superset/assets/src/visualizations/nvd3/NVD3Vis.js
b/superset/assets/src/visualizations/nvd3/NVD3Vis.js
index 5000731..9ffe468 100644
--- a/superset/assets/src/visualizations/nvd3/NVD3Vis.js
+++ b/superset/assets/src/visualizations/nvd3/NVD3Vis.js
@@ -8,7 +8,7 @@ import 'nvd3/build/nv.d3.min.css';
import { t } from '../../locales';
import AnnotationTypes, { applyNativeColumns } from
'../../modules/AnnotationTypes';
-import { getScale, getColor } from '../../modules/CategoricalColorNamespace';
+import { getScale, getColor } from
'../../modules/colors/CategoricalColorNamespace';
import { formatDateVerbose } from '../../modules/dates';
import { d3TimeFormatPreset, d3FormatPreset } from '../../modules/utils';
import { isTruthy } from '../../utils/common';
diff --git a/superset/assets/src/visualizations/wordcloud/WordCloud.js
b/superset/assets/src/visualizations/wordcloud/WordCloud.js
index 2b91665..a165b01 100644
--- a/superset/assets/src/visualizations/wordcloud/WordCloud.js
+++ b/superset/assets/src/visualizations/wordcloud/WordCloud.js
@@ -1,7 +1,7 @@
import d3 from 'd3';
import PropTypes from 'prop-types';
import cloudLayout from 'd3-cloud';
-import { getScale } from '../../modules/CategoricalColorNamespace';
+import { getScale } from '../../modules/colors/CategoricalColorNamespace';
const ROTATION = {
square: () => Math.floor((Math.random() * 2)) * 90,