Skip to content

Commit 8c926f4

Browse files
authored
Merge branch 'master' into chore/logo-width
2 parents 62e1d43 + 88029e2 commit 8c926f4

File tree

91 files changed

+1089
-430
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1089
-430
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,5 @@ release.json
108108
messages.mo
109109

110110
docker/requirements-local.txt
111+
112+
cache/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ A modern, enterprise-ready business intelligence web application.
4747

4848
## Why Superset?
4949

50-
Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams.
50+
Superset is a modern data exploration and data visualization platform. Superset can replace or augment proprietary business intelligence tools for many teams. Superset integrates well with a variety of data sources.
5151

5252
Superset provides:
5353

UPDATING.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ assists people when migrating to a new version.
3030
### Breaking Changes
3131

3232
- [19049](https://github.com/apache/superset/pull/19049): APP_ICON_WIDTH has been removed from the config. Superset should now be able to handle different logo sizes without having to explicitly set an APP_ICON_WIDTH. This might affect the size of existing custom logos as the UI will now resize them according to the specified space of maximum 148px and not according to the value of APP_ICON_WIDTH.
33+
- [19274](https://github.com/apache/superset/pull/19274): The `PUBLIC_ROLE_LIKE_GAMMA` config key has been removed, set `PUBLIC_ROLE_LIKE` = "Gamma" to have the same functionality.
34+
- [19273](https://github.com/apache/superset/pull/19273): The `SUPERSET_CELERY_WORKERS` and `SUPERSET_WORKERS` config keys has been removed. Configure celery directly using `CELERY_CONFIG` on Superset
3335
- [19231](https://github.com/apache/superset/pull/19231): The `ENABLE_REACT_CRUD_VIEWS` feature flag has been removed (permanently enabled). Any deployments which had set this flag to false will need to verify that the React views support their use case.
3436
- [17556](https://github.com/apache/superset/pull/17556): Bumps mysqlclient from v1 to v2
3537
- [19113](https://github.com/apache/superset/pull/19113): The `ENABLE_JAVASCRIPT_CONTROLS` setting has moved from app config to a feature flag. Any deployments who overrode this setting will now need to override the feature flag from here onward.
@@ -38,10 +40,13 @@ assists people when migrating to a new version.
3840
- [17984](https://github.com/apache/superset/pull/17984): Default Flask SECRET_KEY has changed for security reasons. You should always override with your own secret. Set `PREVIOUS_SECRET_KEY` (ex: PREVIOUS_SECRET_KEY = "\2\1thisismyscretkey\1\2\\e\\y\\y\\h") with your previous key and use `superset re-encrypt-secrets` to rotate you current secrets
3941
- [15254](https://github.com/apache/superset/pull/15254): Previously `QUERY_COST_FORMATTERS_BY_ENGINE`, `SQL_VALIDATORS_BY_ENGINE` and `SCHEDULED_QUERIES` were expected to be defined in the feature flag dictionary in the `config.py` file. These should now be defined as a top-level config, with the feature flag dictionary being reserved for boolean only values.
4042
- [17539](https://github.com/apache/superset/pull/17539): all Superset CLI commands (init, load_examples and etc) require setting the FLASK_APP environment variable (which is set by default when `.flaskenv` is loaded)
41-
- [18970](https://github.com/apache/superset/pull/18970): Changes feature flag for the legacy datasource editor (DISABLE_LEGACY_DATASOURCE_EDITOR) in config.py to True, thus disabling the feature from being shown in the client.
43+
- [18970](https://github.com/apache/superset/pull/18970): Changes feature
44+
flag for the legacy datasource editor (DISABLE_LEGACY_DATASOURCE_EDITOR) in config.py to True, thus disabling the feature from being shown in the client.
45+
- [19083](https://github.com/apache/superset/pull/19083): Updates the mutator function in the config file to take a sql argument and a list of kwargs. Any `SQL_QUERY_MUTATOR` config function overrides will need to be updated to match the new set of params. It is advised regardless of the dictionary args that you list in your function arguments, to keep **kwargs as the last argument to allow for any new kwargs to be passed in.
4246
- [19017](https://github.com/apache/superset/pull/19017): Removes Python 3.7 support.
4347
- [19142](https://github.com/apache/superset/pull/19142): Changes feature flag for versioned export(VERSIONED_EXPORT) to be true.
4448
- [19107](https://github.com/apache/superset/pull/19107): Feature flag `SQLLAB_BACKEND_PERSISTENCE` is now on by default, which enables persisting SQL Lab tabs in the backend instead of the browser's `localStorage`.
49+
- [19262](https://github.com/apache/superset/pull/19262): As per SIPs 11 and 68, the native NoSQL Druid connector is deprecated as of 2.0 and will no longer be supported. Druid is still supported through SQLAlchemy via pydruid.
4550

4651
### Potential Downtime
4752

superset-frontend/package-lock.json

Lines changed: 20 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

superset-frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
"rison": "^0.1.1",
197197
"scroll-into-view-if-needed": "^2.2.28",
198198
"shortid": "^2.2.6",
199+
"tinycolor2": "^1.4.2",
199200
"urijs": "^1.19.8",
200201
"use-immer": "^0.6.0",
201202
"use-query-params": "^1.1.9",
@@ -261,6 +262,7 @@
261262
"@types/rison": "0.0.6",
262263
"@types/shortid": "^0.0.29",
263264
"@types/sinon": "^9.0.5",
265+
"@types/tinycolor2": "^1.4.3",
264266
"@types/yargs": "12 - 15",
265267
"@typescript-eslint/eslint-plugin": "^5.3.0",
266268
"@typescript-eslint/parser": "^5.3.0",

superset-frontend/packages/superset-ui-chart-controls/src/shared-controls/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ const linear_color_scheme: SharedControlConfig<'ColorSchemeControl'> = {
205205
renderTrigger: true,
206206
schemes: () => sequentialSchemeRegistry.getMap(),
207207
isLinear: true,
208+
mapStateToProps: state => ({
209+
dashboardId: state?.form_data?.dashboardId,
210+
}),
208211
};
209212

210213
const secondary_metric: SharedControlConfig<'MetricsControl'> = {

superset-frontend/packages/superset-ui-core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@types/math-expression-evaluator": "^1.2.1",
4343
"@types/rison": "0.0.6",
4444
"@types/seedrandom": "^2.4.28",
45+
"@types/tinycolor2": "^1.4.3",
4546
"@types/fetch-mock": "^7.3.3",
4647
"@types/enzyme": "^3.10.5",
4748
"@types/prop-types": "^15.7.2",

superset-frontend/packages/superset-ui-core/src/color/CategoricalColorScale.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ import { scaleOrdinal, ScaleOrdinal } from 'd3-scale';
2222
import { ExtensibleFunction } from '../models';
2323
import { ColorsLookup } from './types';
2424
import stringifyAndTrim from './stringifyAndTrim';
25+
import getSharedLabelColor from './SharedLabelColorSingleton';
2526

2627
// Use type augmentation to correct the fact that
2728
// an instance of CategoricalScale is also a function
28-
2929
interface CategoricalColorScale {
30-
(x: { toString(): string }): string;
30+
(x: { toString(): string }, y?: number): string;
3131
}
3232

3333
class CategoricalColorScale extends ExtensibleFunction {
@@ -46,7 +46,7 @@ class CategoricalColorScale extends ExtensibleFunction {
4646
* (usually CategoricalColorNamespace) and supersede this.forcedColors
4747
*/
4848
constructor(colors: string[], parentForcedColors?: ColorsLookup) {
49-
super((value: string) => this.getColor(value));
49+
super((value: string, sliceId?: number) => this.getColor(value, sliceId));
5050

5151
this.colors = colors;
5252
this.scale = scaleOrdinal<{ toString(): string }, string>();
@@ -55,20 +55,27 @@ class CategoricalColorScale extends ExtensibleFunction {
5555
this.forcedColors = {};
5656
}
5757

58-
getColor(value?: string) {
58+
getColor(value?: string, sliceId?: number) {
5959
const cleanedValue = stringifyAndTrim(value);
60+
const sharedLabelColor = getSharedLabelColor();
61+
6062
const parentColor =
6163
this.parentForcedColors && this.parentForcedColors[cleanedValue];
6264
if (parentColor) {
65+
sharedLabelColor.addSlice(cleanedValue, parentColor, sliceId);
6366
return parentColor;
6467
}
6568

6669
const forcedColor = this.forcedColors[cleanedValue];
6770
if (forcedColor) {
71+
sharedLabelColor.addSlice(cleanedValue, forcedColor, sliceId);
6872
return forcedColor;
6973
}
7074

71-
return this.scale(cleanedValue);
75+
const color = this.scale(cleanedValue);
76+
sharedLabelColor.addSlice(cleanedValue, color, sliceId);
77+
78+
return color;
7279
}
7380

7481
/**
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import tinycolor from 'tinycolor2';
21+
import { CategoricalColorNamespace } from '.';
22+
import makeSingleton from '../utils/makeSingleton';
23+
24+
export class SharedLabelColor {
25+
sliceLabelColorMap: Record<number, Record<string, string | undefined>>;
26+
27+
constructor() {
28+
// { sliceId1: { label1: color1 }, sliceId2: { label2: color2 } }
29+
this.sliceLabelColorMap = {};
30+
}
31+
32+
getColorMap(
33+
colorNamespace?: string,
34+
colorScheme?: string,
35+
updateColorScheme?: boolean,
36+
) {
37+
if (colorScheme) {
38+
const categoricalNamespace =
39+
CategoricalColorNamespace.getNamespace(colorNamespace);
40+
const colors = categoricalNamespace.getScale(colorScheme).range();
41+
const sharedLabels = this.getSharedLabels();
42+
const generatedColors: tinycolor.Instance[] = [];
43+
let sharedLabelMap;
44+
45+
if (sharedLabels.length) {
46+
const multiple = Math.ceil(sharedLabels.length / colors.length);
47+
const ext = 5;
48+
const analogousColors = colors.map(color => {
49+
const result = tinycolor(color).analogous(multiple + ext);
50+
return result.slice(ext);
51+
});
52+
53+
// [[A, AA, AAA], [B, BB, BBB]] => [A, B, AA, BB, AAA, BBB]
54+
while (analogousColors[analogousColors.length - 1]?.length) {
55+
analogousColors.forEach(colors =>
56+
generatedColors.push(colors.shift() as tinycolor.Instance),
57+
);
58+
}
59+
sharedLabelMap = sharedLabels.reduce(
60+
(res, label, index) => ({
61+
...res,
62+
[label.toString()]: generatedColors[index]?.toHexString(),
63+
}),
64+
{},
65+
);
66+
}
67+
68+
const labelMap = Object.keys(this.sliceLabelColorMap).reduce(
69+
(res, sliceId) => {
70+
const colorScale = categoricalNamespace.getScale(colorScheme);
71+
return {
72+
...res,
73+
...Object.keys(this.sliceLabelColorMap[sliceId]).reduce(
74+
(res, label) => ({
75+
...res,
76+
[label]: updateColorScheme
77+
? colorScale(label)
78+
: this.sliceLabelColorMap[sliceId][label],
79+
}),
80+
{},
81+
),
82+
};
83+
},
84+
{},
85+
);
86+
87+
return {
88+
...labelMap,
89+
...sharedLabelMap,
90+
};
91+
}
92+
return undefined;
93+
}
94+
95+
addSlice(label: string, color: string, sliceId?: number) {
96+
if (!sliceId) return;
97+
this.sliceLabelColorMap[sliceId] = {
98+
...this.sliceLabelColorMap[sliceId],
99+
[label]: color,
100+
};
101+
}
102+
103+
removeSlice(sliceId: number) {
104+
delete this.sliceLabelColorMap[sliceId];
105+
}
106+
107+
clear() {
108+
this.sliceLabelColorMap = {};
109+
}
110+
111+
getSharedLabels() {
112+
const tempLabels = new Set<string>();
113+
const result = new Set<string>();
114+
Object.keys(this.sliceLabelColorMap).forEach(sliceId => {
115+
const colorMap = this.sliceLabelColorMap[sliceId];
116+
Object.keys(colorMap).forEach(label => {
117+
if (tempLabels.has(label) && !result.has(label)) {
118+
result.add(label);
119+
} else {
120+
tempLabels.add(label);
121+
}
122+
});
123+
});
124+
return [...result];
125+
}
126+
}
127+
128+
const getInstance = makeSingleton(SharedLabelColor);
129+
130+
export default getInstance;

superset-frontend/packages/superset-ui-core/src/color/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,9 @@ export * from './SequentialScheme';
3232
export { default as ColorSchemeRegistry } from './ColorSchemeRegistry';
3333
export * from './colorSchemes';
3434
export * from './utils';
35+
export {
36+
default as getSharedLabelColor,
37+
SharedLabelColor,
38+
} from './SharedLabelColorSingleton';
3539

3640
export const BRAND_COLOR = '#00A699';

0 commit comments

Comments
 (0)