[reviewable] Integrate @superset-ui/{core,color,chart} modules (#6234)

* Add d3 micro packages

* Replace d3 imports with specific modules import

* Define d3 colors

* import specific d3 submodules instead of entire d3

* update function name

* move function location and fix small bug

* Move primary color to control

* remove colorscalefactory usage

* remove unused d3

* fix unit test

* fix color picker

* use @superset-ui/color

* update package version

* remove files that are extracted

* replace all references

* fix two files

* Revert some changes to split to another PR

* remove adaptor

* Address Christine's comment

* remove d3 v3 from calendar

* remove d3.scale.threshold

* Get rid of colorScalerFactory and revise hexToRGB

* fix color cleaning

* fix lint
This commit is contained in:
Krist Wongsuphasawat
2018-11-11 10:07:05 -08:00
committed by Chris Williams
parent 841d5e6338
commit a7b52da6ce
129 changed files with 227 additions and 4324 deletions

View File

@@ -1,261 +0,0 @@
import Registry from '../../../src/modules/Registry';
describe('Registry', () => {
it('exists', () => {
expect(Registry !== undefined).toBe(true);
});
describe('new Registry(name)', () => {
it('can create a new registry when name is not given', () => {
const registry = new Registry();
expect(registry).toBeInstanceOf(Registry);
});
it('can create a new registry when name is given', () => {
const registry = new Registry('abc');
expect(registry).toBeInstanceOf(Registry);
expect(registry.name).toBe('abc');
});
});
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();
registry.registerValue('a', 'testValue');
expect(registry.has('a')).toBe(true);
registry.registerLoader('b', () => 'testValue2');
expect(registry.has('b')).toBe(true);
});
it('returns false if an item with the given key does not exist', () => {
const registry = new Registry();
expect(registry.has('a')).toBe(false);
});
});
describe('.registerValue(key, value)', () => {
it('registers the given value with the given key', () => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
expect(registry.has('a')).toBe(true);
expect(registry.get('a')).toBe('testValue');
});
it('returns the registry itself', () => {
const registry = new Registry();
expect(registry.registerValue('a', 'testValue')).toBe(registry);
});
});
describe('.registerLoader(key, loader)', () => {
it('registers the given loader with the given key', () => {
const registry = new Registry();
registry.registerLoader('a', () => 'testValue');
expect(registry.has('a')).toBe(true);
expect(registry.get('a')).toBe('testValue');
});
it('returns the registry itself', () => {
const registry = new Registry();
expect(registry.registerLoader('a', () => 'testValue')).toBe(registry);
});
});
describe('.get(key)', () => {
it('given the key, returns the value if the item is a value', () => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
expect(registry.get('a')).toBe('testValue');
});
it(
'given the key, returns the result of the loader function if the item is a loader',
() => {
const registry = new Registry();
registry.registerLoader('b', () => 'testValue2');
expect(registry.get('b')).toBe('testValue2');
},
);
it('returns null if the item with specified key does not exist', () => {
const registry = new Registry();
expect(registry.get('a')).toBeNull();
});
it(
'If the key was registered multiple times, returns the most recent item.',
() => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
expect(registry.get('a')).toBe('testValue');
registry.registerLoader('a', () => 'newValue');
expect(registry.get('a')).toBe('newValue');
},
);
});
describe('.getAsPromise(key)', () => {
it(
'given the key, returns a promise of item value if the item is a value',
() => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
return registry.getAsPromise('a').then((value) => {
expect(value).toBe('testValue');
});
},
);
it(
'given the key, returns a promise of result of the loader function if the item is a loader ',
() => {
const registry = new Registry();
registry.registerLoader('a', () => 'testValue');
return registry.getAsPromise('a').then((value) => {
expect(value).toBe('testValue');
});
},
);
it(
'returns a rejected promise if the item with specified key does not exist',
() => {
const registry = new Registry();
return registry.getAsPromise('a').then(null, (err) => {
expect(err).toBe('Item with key "a" is not registered.');
});
},
);
it(
'If the key was registered multiple times, returns a promise of the most recent item.',
() => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
const promise1 = registry.getAsPromise('a').then((value) => {
expect(value).toBe('testValue');
});
registry.registerLoader('a', () => 'newValue');
const promise2 = registry.getAsPromise('a').then((value) => {
expect(value).toBe('newValue');
});
return Promise.all([promise1, promise2]);
},
);
});
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();
registry.registerValue('a', 'testValue');
registry.registerLoader('b', () => 'test2');
expect(registry.keys()).toEqual(['a', 'b']);
});
});
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();
registry.registerValue('a', 'test1');
registry.registerLoader('b', () => 'test2');
expect(registry.entries()).toEqual([
{ key: 'a', value: 'test1' },
{ key: 'b', value: 'test2' },
]);
});
});
describe('.entriesAsPromise()', () => {
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.entriesAsPromise().then((entries) => {
expect(entries).toEqual([
{ key: 'a', value: 'test1' },
{ key: 'b', value: 'test2' },
{ key: 'c', value: 'test3' },
]);
});
});
});
describe('.remove(key)', () => {
it('removes the item with given key', () => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
registry.remove('a');
expect(registry.get('a')).toBeNull();
});
it('does not throw error if the key does not exist', () => {
const registry = new Registry();
expect(() => registry.remove('a')).not.toThrowError();
});
it('returns itself', () => {
const registry = new Registry();
registry.registerValue('a', 'testValue');
expect(registry.remove('a')).toBe(registry);
});
});
});

View File

@@ -1,160 +0,0 @@
import CategoricalColorNamespace, {
getNamespace,
getScale,
getColor,
DEFAULT_NAMESPACE,
} from '../../../../src/modules/colors/CategoricalColorNamespace';
import getCategoricalSchemeRegistry from '../../../../src/modules/colors/CategoricalSchemeRegistrySingleton';
import CategoricalScheme from '../../../../src/modules/colors/CategoricalScheme';
describe('CategoricalColorNamespace', () => {
beforeAll(() => {
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');
});
describe('static getNamespace()', () => {
it('returns default namespace if name is not specified', () => {
const namespace = getNamespace();
expect(namespace !== undefined).toBe(true);
expect(namespace.name).toBe(DEFAULT_NAMESPACE);
});
it('returns namespace with specified name', () => {
const namespace = getNamespace('myNamespace');
expect(namespace !== undefined).toBe(true);
expect(namespace.name).toBe('myNamespace');
});
it('returns existing instance if the name already exists', () => {
const ns1 = getNamespace('myNamespace');
const ns2 = getNamespace('myNamespace');
expect(ns1).toBe(ns2);
const ns3 = getNamespace();
const ns4 = getNamespace();
expect(ns3).toBe(ns4);
});
});
describe('.getScale()', () => {
it('returns a CategoricalColorScale from given scheme name', () => {
const namespace = getNamespace('test-get-scale1');
const scale = namespace.getScale('testColors');
expect(scale).toBeDefined();
expect(scale.getColor('dog')).toBeDefined();
});
it(
'returns same scale if the scale with that name already exists in this namespace',
() => {
const namespace = getNamespace('test-get-scale2');
const scale1 = namespace.getScale('testColors');
const scale2 = namespace.getScale('testColors2');
const scale3 = namespace.getScale('testColors2');
const scale4 = namespace.getScale('testColors');
expect(scale1).toBe(scale4);
expect(scale2).toBe(scale3);
},
);
});
describe('.setColor()', () => {
it(
'overwrites color for all CategoricalColorScales in this namespace',
() => {
const namespace = getNamespace('test-set-scale1');
namespace.setColor('dog', 'black');
const scale = namespace.getScale('testColors');
expect(scale.getColor('dog')).toBe('black');
expect(scale.getColor('boy')).not.toBe('black');
},
);
it('can override forcedColors in each scale', () => {
const namespace = getNamespace('test-set-scale2');
namespace.setColor('dog', 'black');
const scale = namespace.getScale('testColors');
scale.setColor('dog', 'pink');
expect(scale.getColor('dog')).toBe('black');
expect(scale.getColor('boy')).not.toBe('black');
});
it('does not affect scales in other namespaces', () => {
const ns1 = getNamespace('test-set-scale3.1');
ns1.setColor('dog', 'black');
const scale1 = ns1.getScale('testColors');
const ns2 = getNamespace('test-set-scale3.2');
const scale2 = ns2.getScale('testColors');
expect(scale1.getColor('dog')).toBe('black');
expect(scale2.getColor('dog')).not.toBe('black');
});
it('returns the namespace instance', () => {
const ns1 = getNamespace('test-set-scale3.1');
const ns2 = ns1.setColor('dog', 'black');
expect(ns1).toBe(ns2);
});
});
describe('static getScale()', () => {
it(
'getScale() returns a CategoricalColorScale with default scheme in default namespace',
() => {
const scale = getScale();
expect(scale).toBeDefined();
const scale2 = getNamespace().getScale();
expect(scale).toBe(scale2);
},
);
it(
'getScale(scheme) returns a CategoricalColorScale with specified scheme in default namespace',
() => {
const scale = getScale('testColors');
expect(scale).toBeDefined();
const scale2 = getNamespace().getScale('testColors');
expect(scale).toBe(scale2);
},
);
it(
'getScale(scheme, namespace) returns a CategoricalColorScale with specified scheme in specified namespace',
() => {
const scale = getScale('testColors', 'test-getScale');
expect(scale).toBeDefined();
const scale2 = getNamespace('test-getScale').getScale('testColors');
expect(scale).toBe(scale2);
},
);
});
describe('static getColor()', () => {
it(
'getColor(value) returns a color from default scheme in default namespace',
() => {
const value = 'dog';
const color = getColor(value);
const color2 = getNamespace().getScale().getColor(value);
expect(color).toBe(color2);
},
);
it(
'getColor(value, scheme) returns a color from specified scheme in default namespace',
() => {
const value = 'dog';
const scheme = 'testColors';
const color = getColor(value, scheme);
const color2 = getNamespace().getScale(scheme).getColor(value);
expect(color).toBe(color2);
},
);
it(
'getColor(value, scheme, namespace) returns a color from specified scheme in specified namespace',
() => {
const value = 'dog';
const scheme = 'testColors';
const namespace = 'test-getColor';
const color = getColor(value, scheme, namespace);
const color2 = getNamespace(namespace).getScale(scheme).getColor(value);
expect(color).toBe(color2);
},
);
});
});

View File

@@ -1,94 +0,0 @@
import CategoricalColorScale from '../../../../src/modules/colors/CategoricalColorScale';
describe('CategoricalColorScale', () => {
it('exists', () => {
expect(CategoricalColorScale !== undefined).toBe(true);
});
describe('new CategoricalColorScale(colors, parentForcedColors)', () => {
it('can create new scale when parentForcedColors is not given', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
expect(scale).toBeInstanceOf(CategoricalColorScale);
});
it('can create new scale when parentForcedColors is given', () => {
const parentForcedColors = {};
const scale = new CategoricalColorScale(['blue', 'red', 'green'], parentForcedColors);
expect(scale).toBeInstanceOf(CategoricalColorScale);
expect(scale.parentForcedColors).toBe(parentForcedColors);
});
});
describe('.getColor(value)', () => {
it('returns same color for same value', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
const c1 = scale.getColor('pig');
const c2 = scale.getColor('horse');
const c3 = scale.getColor('pig');
scale.getColor('cow');
const c5 = scale.getColor('horse');
expect(c1).toBe(c3);
expect(c2).toBe(c5);
});
it('returns different color for consecutive items', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
const c1 = scale.getColor('pig');
const c2 = scale.getColor('horse');
const c3 = scale.getColor('cat');
expect(c1).not.toBe(c2);
expect(c2).not.toBe(c3);
expect(c3).not.toBe(c1);
});
it('recycles colors when number of items exceed available colors', () => {
const colorSet = {};
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
const colors = [
scale.getColor('pig'),
scale.getColor('horse'),
scale.getColor('cat'),
scale.getColor('cow'),
scale.getColor('donkey'),
scale.getColor('goat'),
];
colors.forEach((color) => {
if (colorSet[color]) {
colorSet[color]++;
} else {
colorSet[color] = 1;
}
});
expect(Object.keys(colorSet)).toHaveLength(3);
['blue', 'red', 'green'].forEach((color) => {
expect(colorSet[color]).toBe(2);
});
});
});
describe('.setColor(value, forcedColor)', () => {
it('overrides default color', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
scale.setColor('pig', 'pink');
expect(scale.getColor('pig')).toBe('pink');
});
it('does not override parentForcedColors', () => {
const scale1 = new CategoricalColorScale(['blue', 'red', 'green']);
scale1.setColor('pig', 'black');
const scale2 = new CategoricalColorScale(['blue', 'red', 'green'], scale1.forcedColors);
scale2.setColor('pig', 'pink');
expect(scale1.getColor('pig')).toBe('black');
expect(scale2.getColor('pig')).toBe('black');
});
it('returns the scale', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
const output = scale.setColor('pig', 'pink');
expect(scale).toBe(output);
});
});
describe('.toFunction()', () => {
it('returns a function that wraps getColor', () => {
const scale = new CategoricalColorScale(['blue', 'red', 'green']);
const colorFn = scale.toFunction();
expect(scale.getColor('pig')).toBe(colorFn('pig'));
expect(scale.getColor('cat')).toBe(colorFn('cat'));
});
});
});

View File

@@ -1,64 +0,0 @@
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);
});
});
});