mirror of https://github.com/apache/superset.git
chore: Removes hard-coded colors from the plugins - iteration 1 (#19923)
* chore: Removes hard-coded colors from the plugins - iteration 1 * Fixes lint errors * Fixes tests
This commit is contained in:
parent
d0b8b1e97d
commit
b7cff8335b
|
@ -18,17 +18,11 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { SupersetTheme } from '../../style';
|
||||
import { FallbackPropsWithDimension } from './SuperChart';
|
||||
|
||||
export type Props = FallbackPropsWithDimension;
|
||||
|
||||
const CONTAINER_STYLE = {
|
||||
backgroundColor: '#000',
|
||||
color: '#fff',
|
||||
overflow: 'auto',
|
||||
padding: 32,
|
||||
};
|
||||
|
||||
export default function FallbackComponent({
|
||||
componentStack,
|
||||
error,
|
||||
|
@ -36,7 +30,15 @@ export default function FallbackComponent({
|
|||
width,
|
||||
}: Props) {
|
||||
return (
|
||||
<div style={{ ...CONTAINER_STYLE, height, width }}>
|
||||
<div
|
||||
css={(theme: SupersetTheme) => ({
|
||||
backgroundColor: theme.colors.grayscale.dark2,
|
||||
color: theme.colors.grayscale.light5,
|
||||
overflow: 'auto',
|
||||
padding: 32,
|
||||
})}
|
||||
style={{ height, width }}
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
<b>Oops! An error occured!</b>
|
||||
|
|
|
@ -19,7 +19,12 @@
|
|||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import React from 'react';
|
||||
import { QueryFormData, ChartMetadata, ChartPlugin } from '@superset-ui/core';
|
||||
import {
|
||||
QueryFormData,
|
||||
ChartMetadata,
|
||||
ChartPlugin,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
|
||||
const DIMENSION_STYLE = {
|
||||
fontSize: 36,
|
||||
|
@ -39,31 +44,36 @@ export const TestComponent = ({
|
|||
message?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
}) => (
|
||||
<div
|
||||
className="test-component"
|
||||
style={{
|
||||
width,
|
||||
height,
|
||||
backgroundColor: '#00d1c1',
|
||||
color: '#fff',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
<div className="message" style={{ padding: 10 }}>
|
||||
{message ?? 'custom component'}
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<div
|
||||
className="test-component"
|
||||
style={{
|
||||
width,
|
||||
height,
|
||||
backgroundColor: theme.colors.primary.base,
|
||||
color: theme.colors.grayscale.light5,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
borderRadius: 8,
|
||||
}}
|
||||
>
|
||||
<div className="message" style={{ padding: 10 }}>
|
||||
{message ?? 'custom component'}
|
||||
</div>
|
||||
<div className="dimension" style={DIMENSION_STYLE}>
|
||||
{[width, height].join('x')}
|
||||
</div>
|
||||
<div className="formData" style={{ padding: 10 }}>
|
||||
<code style={{ color: theme.colors.primary.light2 }}>
|
||||
{JSON.stringify(formData)}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<div className="dimension" style={DIMENSION_STYLE}>
|
||||
{[width, height].join('x')}
|
||||
</div>
|
||||
<div className="formData" style={{ padding: 10 }}>
|
||||
<code style={{ color: '#D3F9F7' }}>{JSON.stringify(formData)}</code>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
export const ChartKeys = {
|
||||
DILIGENT: 'diligent-chart',
|
||||
|
|
|
@ -17,11 +17,16 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import React, { ReactElement, ReactNode } from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import mockConsole, { RestoreConsole } from 'jest-mock-console';
|
||||
|
||||
import { ChartProps, promiseTimeout, supersetTheme } from '@superset-ui/core';
|
||||
import {
|
||||
ChartProps,
|
||||
promiseTimeout,
|
||||
supersetTheme,
|
||||
SupersetTheme,
|
||||
ThemeProvider,
|
||||
} from '@superset-ui/core';
|
||||
import SuperChartCore from '../../../src/chart/components/SuperChartCore';
|
||||
import {
|
||||
ChartKeys,
|
||||
|
@ -30,6 +35,22 @@ import {
|
|||
SlowChartPlugin,
|
||||
} from './MockChartPlugins';
|
||||
|
||||
const Wrapper = ({
|
||||
theme,
|
||||
children,
|
||||
}: {
|
||||
theme: SupersetTheme;
|
||||
children: ReactNode;
|
||||
}) => <ThemeProvider theme={theme}>{children}</ThemeProvider>;
|
||||
|
||||
const styledMount = (component: ReactElement) =>
|
||||
mount(component, {
|
||||
wrappingComponent: Wrapper,
|
||||
wrappingComponentProps: {
|
||||
theme: supersetTheme,
|
||||
},
|
||||
});
|
||||
|
||||
describe('SuperChartCore', () => {
|
||||
const chartProps = new ChartProps();
|
||||
|
||||
|
@ -63,7 +84,7 @@ describe('SuperChartCore', () => {
|
|||
|
||||
describe('registered charts', () => {
|
||||
it('renders registered chart', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore
|
||||
chartType={ChartKeys.DILIGENT}
|
||||
chartProps={chartProps}
|
||||
|
@ -75,7 +96,9 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
});
|
||||
it('renders registered chart with lazy loading', () => {
|
||||
const wrapper = shallow(<SuperChartCore chartType={ChartKeys.LAZY} />);
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.LAZY} />,
|
||||
);
|
||||
|
||||
return promiseTimeout(() => {
|
||||
expect(wrapper.render().find('div.test-component')).toHaveLength(1);
|
||||
|
@ -84,14 +107,14 @@ describe('SuperChartCore', () => {
|
|||
it('does not render if chartType is not set', () => {
|
||||
// Suppress warning
|
||||
// @ts-ignore chartType is required
|
||||
const wrapper = shallow(<SuperChartCore />);
|
||||
const wrapper = styledMount(<SuperChartCore />);
|
||||
|
||||
return promiseTimeout(() => {
|
||||
expect(wrapper.render().children()).toHaveLength(0);
|
||||
}, 5);
|
||||
});
|
||||
it('adds id to container if specified', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.DILIGENT} id="the-chart" />,
|
||||
);
|
||||
|
||||
|
@ -100,7 +123,7 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
});
|
||||
it('adds class to container if specified', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.DILIGENT} className="the-chart" />,
|
||||
);
|
||||
|
||||
|
@ -109,7 +132,7 @@ describe('SuperChartCore', () => {
|
|||
}, 0);
|
||||
});
|
||||
it('uses overrideTransformProps when specified', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore
|
||||
chartType={ChartKeys.DILIGENT}
|
||||
overrideTransformProps={() => ({ message: 'hulk' })}
|
||||
|
@ -125,7 +148,7 @@ describe('SuperChartCore', () => {
|
|||
queriesData: [{ message: 'hulk' }],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore
|
||||
chartType={ChartKeys.DILIGENT}
|
||||
preTransformProps={() => chartPropsWithPayload}
|
||||
|
@ -138,7 +161,7 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
});
|
||||
it('uses postTransformProps when specified', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore
|
||||
chartType={ChartKeys.DILIGENT}
|
||||
postTransformProps={() => ({ message: 'hulk' })}
|
||||
|
@ -150,7 +173,7 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
});
|
||||
it('renders if chartProps is not specified', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.DILIGENT} />,
|
||||
);
|
||||
|
||||
|
@ -159,7 +182,9 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
});
|
||||
it('does not render anything while waiting for Chart code to load', () => {
|
||||
const wrapper = shallow(<SuperChartCore chartType={ChartKeys.SLOW} />);
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.SLOW} />,
|
||||
);
|
||||
|
||||
return promiseTimeout(() => {
|
||||
expect(wrapper.render().children()).toHaveLength(0);
|
||||
|
@ -167,14 +192,16 @@ describe('SuperChartCore', () => {
|
|||
});
|
||||
it('eventually renders after Chart is loaded', () => {
|
||||
// Suppress warning
|
||||
const wrapper = mount(<SuperChartCore chartType={ChartKeys.SLOW} />);
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.SLOW} />,
|
||||
);
|
||||
|
||||
return promiseTimeout(() => {
|
||||
expect(wrapper.render().find('div.test-component')).toHaveLength(1);
|
||||
}, 1500);
|
||||
});
|
||||
it('does not render if chartProps is null', () => {
|
||||
const wrapper = shallow(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType={ChartKeys.DILIGENT} chartProps={null} />,
|
||||
);
|
||||
|
||||
|
@ -186,7 +213,7 @@ describe('SuperChartCore', () => {
|
|||
|
||||
describe('unregistered charts', () => {
|
||||
it('renders error message', () => {
|
||||
const wrapper = mount(
|
||||
const wrapper = styledMount(
|
||||
<SuperChartCore chartType="4d-pie-chart" chartProps={chartProps} />,
|
||||
);
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
import React from 'react';
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
|
||||
const ThemeDecorator = storyFn => (
|
||||
<ThemeProvider theme={supersetTheme}>{storyFn()}</ThemeProvider>
|
||||
const ThemeDecorator = Story => (
|
||||
<ThemeProvider theme={supersetTheme}>{<Story />}</ThemeProvider>
|
||||
);
|
||||
|
||||
export default ThemeDecorator;
|
||||
|
|
|
@ -23,7 +23,7 @@ import { DecoratorFunction } from '@storybook/addons';
|
|||
import ResizablePanel, { Size } from './ResizablePanel';
|
||||
|
||||
export const SupersetBody = styled.div`
|
||||
background: #f5f5f5;
|
||||
background: ${({ theme }) => theme.colors.grayscale.light4};
|
||||
padding: 16px;
|
||||
min-height: 100%;
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ export const basic = () => (
|
|||
cellSize: 10,
|
||||
cellPadding: 2,
|
||||
cellRadius: 0,
|
||||
domainGranularity: 'month',
|
||||
subdomainGranularity: 'day',
|
||||
linearColorScheme: 'schemeRdYlBu',
|
||||
steps: 10,
|
||||
yAxisFormat: '.3s',
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
seedRandom,
|
||||
SuperChart,
|
||||
SequentialD3,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import CountryMapChartPlugin, {
|
||||
countries,
|
||||
|
@ -44,6 +45,7 @@ function generateData(geojson: JsonObject) {
|
|||
}
|
||||
|
||||
export const basic = function BasicCountryMapStory({ width, height }) {
|
||||
const theme = useTheme();
|
||||
const country = select('Country', Object.keys(countries!), 'france');
|
||||
const colorSchema = select<any>(
|
||||
'Color schema',
|
||||
|
@ -67,7 +69,13 @@ export const basic = function BasicCountryMapStory({ width, height }) {
|
|||
|
||||
if (!data) {
|
||||
return (
|
||||
<div style={{ color: '#aaa', textAlign: 'center', padding: 20 }}>
|
||||
<div
|
||||
style={{
|
||||
color: theme.colors.grayscale.base,
|
||||
textAlign: 'center',
|
||||
padding: 20,
|
||||
}}
|
||||
>
|
||||
Loading...
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
/* eslint-disable no-magic-numbers */
|
||||
import React from 'react';
|
||||
import { SuperChart } from '@superset-ui/core';
|
||||
import { SuperChart, useTheme } from '@superset-ui/core';
|
||||
import MapBoxChartPlugin from '@superset-ui/legacy-plugin-chart-map-box';
|
||||
import data from './data';
|
||||
import { generateData } from './data';
|
||||
|
||||
new MapBoxChartPlugin().configure({ key: 'map-box' }).register();
|
||||
|
||||
|
@ -29,27 +29,30 @@ export default {
|
|||
title: 'Legacy Chart Plugins/legacy-plugin-chart-map-box',
|
||||
};
|
||||
|
||||
export const basic = () => (
|
||||
<SuperChart
|
||||
chartType="map-box"
|
||||
width={400}
|
||||
height={400}
|
||||
queriesData={[{ data }]}
|
||||
formData={{
|
||||
allColumnsX: 'LON',
|
||||
allColumnsY: 'LAT',
|
||||
clusteringRadius: '60',
|
||||
globalOpacity: 1,
|
||||
mapboxColor: 'rgb(0, 122, 135)',
|
||||
mapboxLabel: [],
|
||||
mapboxStyle: 'mapbox://styles/mapbox/light-v9',
|
||||
pandasAggfunc: 'sum',
|
||||
pointRadius: 'Auto',
|
||||
pointRadiusUnit: 'Pixels',
|
||||
renderWhileDragging: true,
|
||||
viewportLatitude: 37.78711146014447,
|
||||
viewportLongitude: -122.37633433151713,
|
||||
viewportZoom: 10.026425338292782,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
export const Basic = () => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<SuperChart
|
||||
chartType="map-box"
|
||||
width={400}
|
||||
height={400}
|
||||
queriesData={[{ data: generateData(theme) }]}
|
||||
formData={{
|
||||
allColumnsX: 'LON',
|
||||
allColumnsY: 'LAT',
|
||||
clusteringRadius: '60',
|
||||
globalOpacity: 1,
|
||||
mapboxColor: 'rgb(0, 122, 135)',
|
||||
mapboxLabel: [],
|
||||
mapboxStyle: 'mapbox://styles/mapbox/light-v9',
|
||||
pandasAggfunc: 'sum',
|
||||
pointRadius: 'Auto',
|
||||
pointRadiusUnit: 'Pixels',
|
||||
renderWhileDragging: true,
|
||||
viewportLatitude: 37.78711146014447,
|
||||
viewportLongitude: -122.37633433151713,
|
||||
viewportZoom: 10.026425338292782,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { SupersetTheme } from '@superset-ui/core';
|
||||
|
||||
/* eslint-disable sort-keys, no-magic-numbers */
|
||||
export default {
|
||||
export const generateData = (theme: SupersetTheme) => ({
|
||||
geoJSON: {
|
||||
type: 'FeatureCollection',
|
||||
features: [
|
||||
|
@ -5538,5 +5539,5 @@ export default {
|
|||
],
|
||||
renderWhileDragging: true,
|
||||
tooltip: null,
|
||||
color: 'rgb(0, 122, 135)',
|
||||
};
|
||||
color: theme.colors.primary.base,
|
||||
});
|
||||
|
|
|
@ -38,6 +38,7 @@ export const basic = () => (
|
|||
formData={{
|
||||
maxBubbleSize: '25',
|
||||
showBubbles: true,
|
||||
colorPicker: {},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
/* eslint-disable sort-keys */
|
||||
/* eslint-disable no-magic-numbers */
|
||||
import React from 'react';
|
||||
import { SuperChart } from '@superset-ui/core';
|
||||
import { SuperChart, useTheme } from '@superset-ui/core';
|
||||
import { PathChartPlugin } from '@superset-ui/legacy-preset-chart-deckgl';
|
||||
import payload from './payload';
|
||||
import { payload } from './payload';
|
||||
import dummyDatasource from '../../../../shared/dummyDatasource';
|
||||
|
||||
new PathChartPlugin().configure({ key: 'deck_path' }).register();
|
||||
|
@ -31,51 +31,54 @@ export default {
|
|||
title: 'Legacy Chart Plugins/legacy-preset-chart-deckgl/PathChartPlugin',
|
||||
};
|
||||
|
||||
export const PathChartViz = () => (
|
||||
<SuperChart
|
||||
chartType="deck_path"
|
||||
width={400}
|
||||
height={400}
|
||||
datasource={dummyDatasource}
|
||||
queriesData={[payload]}
|
||||
formData={{
|
||||
datasource: '11__table',
|
||||
viz_type: 'deck_path',
|
||||
slice_id: 72,
|
||||
url_params: {},
|
||||
granularity_sqla: null,
|
||||
time_grain_sqla: null,
|
||||
time_range: '+:+',
|
||||
line_column: 'path_json',
|
||||
line_type: 'json',
|
||||
row_limit: 5000,
|
||||
filter_nulls: true,
|
||||
adhoc_filters: [],
|
||||
mapbox_style: 'mapbox://styles/mapbox/light-v9',
|
||||
viewport: {
|
||||
altitude: 1.5,
|
||||
bearing: 0,
|
||||
height: 1094,
|
||||
latitude: 37.73671752604488,
|
||||
longitude: -122.18885402582598,
|
||||
maxLatitude: 85.05113,
|
||||
maxPitch: 60,
|
||||
maxZoom: 20,
|
||||
minLatitude: -85.05113,
|
||||
minPitch: 0,
|
||||
minZoom: 0,
|
||||
pitch: 0,
|
||||
width: 669,
|
||||
zoom: 9.51847667620428,
|
||||
},
|
||||
color_picker: { a: 1, b: 135, g: 122, r: 0 },
|
||||
line_width: 150,
|
||||
reverse_long_lat: false,
|
||||
autozoom: true,
|
||||
js_columns: ['color'],
|
||||
js_data_mutator: '',
|
||||
js_tooltip: '',
|
||||
js_onclick_href: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
export const PathChartViz = () => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<SuperChart
|
||||
chartType="deck_path"
|
||||
width={400}
|
||||
height={400}
|
||||
datasource={dummyDatasource}
|
||||
queriesData={[payload(theme)]}
|
||||
formData={{
|
||||
datasource: '11__table',
|
||||
viz_type: 'deck_path',
|
||||
slice_id: 72,
|
||||
url_params: {},
|
||||
granularity_sqla: null,
|
||||
time_grain_sqla: null,
|
||||
time_range: '+:+',
|
||||
line_column: 'path_json',
|
||||
line_type: 'json',
|
||||
row_limit: 5000,
|
||||
filter_nulls: true,
|
||||
adhoc_filters: [],
|
||||
mapbox_style: 'mapbox://styles/mapbox/light-v9',
|
||||
viewport: {
|
||||
altitude: 1.5,
|
||||
bearing: 0,
|
||||
height: 1094,
|
||||
latitude: 37.73671752604488,
|
||||
longitude: -122.18885402582598,
|
||||
maxLatitude: 85.05113,
|
||||
maxPitch: 60,
|
||||
maxZoom: 20,
|
||||
minLatitude: -85.05113,
|
||||
minPitch: 0,
|
||||
minZoom: 0,
|
||||
pitch: 0,
|
||||
width: 669,
|
||||
zoom: 9.51847667620428,
|
||||
},
|
||||
color_picker: { a: 1, b: 135, g: 122, r: 0 },
|
||||
line_width: 150,
|
||||
reverse_long_lat: false,
|
||||
autozoom: true,
|
||||
js_columns: ['color'],
|
||||
js_data_mutator: '',
|
||||
js_tooltip: '',
|
||||
js_onclick_href: '',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
/* eslint-disable sort-keys */
|
||||
/* eslint-disable no-magic-numbers */
|
||||
export default {
|
||||
export const payload = theme => ({
|
||||
cache_key: null,
|
||||
cached_dttm: null,
|
||||
cache_timeout: 86400,
|
||||
|
@ -82,7 +82,7 @@ export default {
|
|||
data: {
|
||||
features: [
|
||||
{
|
||||
color: '#ed1c24',
|
||||
color: theme.colors.primary.base,
|
||||
path: [
|
||||
[-122.3535851, 37.9360513],
|
||||
[-122.3179784, 37.9249513],
|
||||
|
@ -109,10 +109,10 @@ export default {
|
|||
[-122.3876274, 37.5993171],
|
||||
],
|
||||
__timestamp: null,
|
||||
extraProps: { color: '#ed1c24' },
|
||||
extraProps: { color: theme.colors.primary.base },
|
||||
},
|
||||
{
|
||||
color: '#faa61a',
|
||||
color: theme.colors.warning.base,
|
||||
path: [
|
||||
[-122.353165, 37.936887],
|
||||
[-122.317269, 37.925655],
|
||||
|
@ -134,10 +134,10 @@ export default {
|
|||
[-121.9772135, 37.5567286],
|
||||
],
|
||||
__timestamp: null,
|
||||
extraProps: { color: '#faa61a' },
|
||||
extraProps: { color: theme.colors.warning.base },
|
||||
},
|
||||
{
|
||||
color: '#ffe800',
|
||||
color: theme.colors.error.base,
|
||||
path: [
|
||||
[-121.945154, 38.018914],
|
||||
[-122.024597, 38.003275],
|
||||
|
@ -167,10 +167,10 @@ export default {
|
|||
[-122.38666, 37.599787],
|
||||
],
|
||||
__timestamp: null,
|
||||
extraProps: { color: '#ffe800' },
|
||||
extraProps: { color: theme.colors.error.base },
|
||||
},
|
||||
{
|
||||
color: '#00aeef',
|
||||
color: theme.colors.success.base,
|
||||
path: [
|
||||
[-121.900367, 37.701695],
|
||||
[-121.928099, 37.699759],
|
||||
|
@ -192,10 +192,10 @@ export default {
|
|||
[-122.469081, 37.706121],
|
||||
],
|
||||
__timestamp: null,
|
||||
extraProps: { color: '#00aeef' },
|
||||
extraProps: { color: theme.colors.success.base },
|
||||
},
|
||||
{
|
||||
color: '#4db848',
|
||||
color: theme.colors.warning.base,
|
||||
path: [
|
||||
[-121.9764, 37.557355],
|
||||
[-122.017867, 37.591208],
|
||||
|
@ -218,11 +218,11 @@ export default {
|
|||
[-122.4683093, 37.705461],
|
||||
],
|
||||
__timestamp: null,
|
||||
extraProps: { color: '#4db848' },
|
||||
extraProps: { color: theme.colors.warning.base },
|
||||
},
|
||||
],
|
||||
mapboxApiKey:
|
||||
'pk.eyJ1Ijoia3Jpc3R3IiwiYSI6ImNqbGg1N242NTFlczczdnBhazViMjgzZ2sifQ.lUneM-o3NucXN189EYyXxQ',
|
||||
metricLabels: [],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
|
|
@ -54,7 +54,7 @@ export const basic = ({ width, height }) => (
|
|||
formData={{
|
||||
encoding: {
|
||||
color: {
|
||||
value: '#0097e6',
|
||||
field: 'name',
|
||||
},
|
||||
fontSize: {
|
||||
field: 'sum__num',
|
||||
|
@ -120,7 +120,7 @@ export const encodesFontByFirstLetter = ({ width, height }) => (
|
|||
formData={{
|
||||
encoding: {
|
||||
color: {
|
||||
value: '#8c7ae6',
|
||||
field: 'name',
|
||||
},
|
||||
fontFamily: {
|
||||
field: 'name[0]',
|
||||
|
|
|
@ -18,80 +18,83 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { SuperChart } from '@superset-ui/core';
|
||||
import { SuperChart, useTheme } from '@superset-ui/core';
|
||||
import data from '../data/data2';
|
||||
import { LINE_PLUGIN_TYPE } from '../constants';
|
||||
import dummyDatasource from '../../../../../shared/dummyDatasource';
|
||||
|
||||
export default () => (
|
||||
<SuperChart
|
||||
key="line1"
|
||||
chartType={LINE_PLUGIN_TYPE}
|
||||
width={400}
|
||||
height={400}
|
||||
datasource={dummyDatasource}
|
||||
queriesData={[{ data }]}
|
||||
formData={{
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'x',
|
||||
type: 'temporal',
|
||||
format: '%Y',
|
||||
scale: {
|
||||
type: 'time',
|
||||
export default () => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<SuperChart
|
||||
key="line1"
|
||||
chartType={LINE_PLUGIN_TYPE}
|
||||
width={400}
|
||||
height={400}
|
||||
datasource={dummyDatasource}
|
||||
queriesData={[{ data }]}
|
||||
formData={{
|
||||
encoding: {
|
||||
x: {
|
||||
field: 'x',
|
||||
type: 'temporal',
|
||||
format: '%Y',
|
||||
scale: {
|
||||
type: 'time',
|
||||
},
|
||||
axis: {
|
||||
orient: 'bottom',
|
||||
title: 'Time',
|
||||
},
|
||||
},
|
||||
axis: {
|
||||
orient: 'bottom',
|
||||
title: 'Time',
|
||||
y: {
|
||||
field: 'y',
|
||||
type: 'quantitative',
|
||||
scale: {
|
||||
type: 'linear',
|
||||
},
|
||||
axis: {
|
||||
orient: 'left',
|
||||
title: 'Score',
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
value: theme.colors.success.base,
|
||||
type: 'nominal',
|
||||
scale: false,
|
||||
},
|
||||
fill: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [true, false],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
strokeDasharray: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [null, '4 4'],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
strokeWidth: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [3, 1.5],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
},
|
||||
y: {
|
||||
field: 'y',
|
||||
type: 'quantitative',
|
||||
scale: {
|
||||
type: 'linear',
|
||||
},
|
||||
axis: {
|
||||
orient: 'left',
|
||||
title: 'Score',
|
||||
},
|
||||
},
|
||||
stroke: {
|
||||
value: '#1abc9c',
|
||||
type: 'nominal',
|
||||
scale: false,
|
||||
},
|
||||
fill: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [true, false],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
strokeDasharray: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [null, '4 4'],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
strokeWidth: {
|
||||
field: 'snapshot',
|
||||
type: 'nominal',
|
||||
scale: {
|
||||
type: 'ordinal',
|
||||
domain: ['Current', 'Last year'],
|
||||
range: [3, 1.5],
|
||||
},
|
||||
legend: false,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -50,6 +50,7 @@ const propTypes = {
|
|||
timeFormatter: PropTypes.func,
|
||||
valueFormatter: PropTypes.func,
|
||||
verboseMap: PropTypes.object,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
function Calendar(element, props) {
|
||||
|
@ -69,6 +70,7 @@ function Calendar(element, props) {
|
|||
timeFormatter,
|
||||
valueFormatter,
|
||||
verboseMap,
|
||||
theme,
|
||||
} = props;
|
||||
|
||||
const container = d3Select(element)
|
||||
|
@ -120,7 +122,7 @@ function Calendar(element, props) {
|
|||
colorScale,
|
||||
min: legendColors[0],
|
||||
max: legendColors[legendColors.length - 1],
|
||||
empty: 'white',
|
||||
empty: theme.colors.grayscale.light5,
|
||||
},
|
||||
displayLegend: showLegend,
|
||||
itemName: '',
|
||||
|
|
|
@ -18,83 +18,86 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { reactify, styled, css } from '@superset-ui/core';
|
||||
import { reactify, styled, css, useTheme } from '@superset-ui/core';
|
||||
import { Global } from '@emotion/react';
|
||||
import Component from './Calendar';
|
||||
|
||||
const ReactComponent = reactify(Component);
|
||||
|
||||
const Calender = ({ className, ...otherProps }) => (
|
||||
<div className={className}>
|
||||
<Global
|
||||
styles={theme => css`
|
||||
.d3-tip {
|
||||
line-height: 1;
|
||||
padding: ${theme.gridUnit * 3}px;
|
||||
background: ${theme.colors.grayscale.dark2};
|
||||
color: ${theme.colors.grayscale.light5};
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
z-index: 1000;
|
||||
font-size: ${theme.typography.sizes.s}px;
|
||||
}
|
||||
/* Creates a small triangle extender for the tooltip */
|
||||
.d3-tip:after {
|
||||
box-sizing: border-box;
|
||||
display: inline;
|
||||
font-size: ${theme.typography.sizes.xs};
|
||||
width: 100%;
|
||||
line-height: 1;
|
||||
color: ${theme.colors.grayscale.dark2};
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Northward tooltips */
|
||||
.d3-tip.n:after {
|
||||
content: '\\25BC';
|
||||
margin: -${theme.gridUnit}px 0 0 0;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
/* Eastward tooltips */
|
||||
.d3-tip.e:after {
|
||||
content: '\\25C0';
|
||||
margin: -${theme.gridUnit}px 0 0 0;
|
||||
top: 50%;
|
||||
left: -${theme.gridUnit * 2}px;
|
||||
}
|
||||
/* Southward tooltips */
|
||||
.d3-tip.s:after {
|
||||
content: '\\25B2';
|
||||
margin: 0;
|
||||
top: -${theme.gridUnit * 2}px;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
/* Westward tooltips */
|
||||
.d3-tip.w:after {
|
||||
content: '\\25B6';
|
||||
margin: -${theme.gridUnit}px 0 0 0px;
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
<ReactComponent {...otherProps} />
|
||||
</div>
|
||||
);
|
||||
const Calendar = ({ className, ...otherProps }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<div className={className}>
|
||||
<Global
|
||||
styles={css`
|
||||
.d3-tip {
|
||||
line-height: 1;
|
||||
padding: ${theme.gridUnit * 3}px;
|
||||
background: ${theme.colors.grayscale.dark2};
|
||||
color: ${theme.colors.grayscale.light5};
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
z-index: 1000;
|
||||
font-size: ${theme.typography.sizes.s}px;
|
||||
}
|
||||
/* Creates a small triangle extender for the tooltip */
|
||||
.d3-tip:after {
|
||||
box-sizing: border-box;
|
||||
display: inline;
|
||||
font-size: ${theme.typography.sizes.xs};
|
||||
width: 100%;
|
||||
line-height: 1;
|
||||
color: ${theme.colors.grayscale.dark2};
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
/* Northward tooltips */
|
||||
.d3-tip.n:after {
|
||||
content: '\\25BC';
|
||||
margin: -${theme.gridUnit}px 0 0 0;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
/* Eastward tooltips */
|
||||
.d3-tip.e:after {
|
||||
content: '\\25C0';
|
||||
margin: -${theme.gridUnit}px 0 0 0;
|
||||
top: 50%;
|
||||
left: -${theme.gridUnit * 2}px;
|
||||
}
|
||||
/* Southward tooltips */
|
||||
.d3-tip.s:after {
|
||||
content: '\\25B2';
|
||||
margin: 0;
|
||||
top: -${theme.gridUnit * 2}px;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
}
|
||||
/* Westward tooltips */
|
||||
.d3-tip.w:after {
|
||||
content: '\\25B6';
|
||||
margin: -${theme.gridUnit}px 0 0 0px;
|
||||
top: 50%;
|
||||
left: 100%;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
<ReactComponent {...otherProps} theme={theme} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Calender.defaultProps = {
|
||||
Calendar.defaultProps = {
|
||||
otherProps: {},
|
||||
};
|
||||
|
||||
Calender.propTypes = {
|
||||
Calendar.propTypes = {
|
||||
className: PropTypes.string.isRequired,
|
||||
otherProps: PropTypes.objectOf(PropTypes.any),
|
||||
};
|
||||
|
||||
export default styled(Calender)`
|
||||
export default styled(Calendar)`
|
||||
${({ theme }) => `
|
||||
.superset-legacy-chart-calendar {
|
||||
padding: ${theme.gridUnit * 3}px;
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { styled, reactify } from '@superset-ui/core';
|
||||
import { styled, reactify, useTheme } from '@superset-ui/core';
|
||||
import WorldMap from './WorldMap';
|
||||
|
||||
const ReactWorldMap = reactify(WorldMap);
|
||||
|
||||
const WorldMapComponent = ({ className, ...otherProps }) => (
|
||||
<div className={className}>
|
||||
<ReactWorldMap {...otherProps} />
|
||||
</div>
|
||||
);
|
||||
const WorldMapComponent = ({ className, ...otherProps }) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<div className={className}>
|
||||
<ReactWorldMap {...otherProps} theme={theme} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
WorldMapComponent.propTypes = {
|
||||
className: PropTypes.string.isRequired,
|
||||
|
|
|
@ -55,6 +55,7 @@ function WorldMap(element, props) {
|
|||
showBubbles,
|
||||
linearColorScheme,
|
||||
color,
|
||||
theme,
|
||||
} = props;
|
||||
const div = d3.select(element);
|
||||
div.classed('superset-legacy-chart-world-map', true);
|
||||
|
@ -90,14 +91,14 @@ function WorldMap(element, props) {
|
|||
height,
|
||||
data: processedData,
|
||||
fills: {
|
||||
defaultFill: '#eee',
|
||||
defaultFill: theme.colors.grayscale.light2,
|
||||
},
|
||||
geographyConfig: {
|
||||
popupOnHover: true,
|
||||
highlightOnHover: true,
|
||||
borderWidth: 1,
|
||||
borderColor: '#feffff',
|
||||
highlightBorderColor: '#feffff',
|
||||
borderColor: theme.colors.grayscale.light5,
|
||||
highlightBorderColor: theme.colors.grayscale.light5,
|
||||
highlightFillColor: color,
|
||||
highlightBorderWidth: 1,
|
||||
popupTemplate: (geo, d) =>
|
||||
|
@ -119,7 +120,7 @@ function WorldMap(element, props) {
|
|||
animate: true,
|
||||
highlightOnHover: true,
|
||||
highlightFillColor: color,
|
||||
highlightBorderColor: 'black',
|
||||
highlightBorderColor: theme.colors.grayscale.dark2,
|
||||
highlightBorderWidth: 2,
|
||||
highlightBorderOpacity: 1,
|
||||
highlightFillOpacity: 0.85,
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo, CSSProperties } from 'react';
|
||||
import { styled } from '@superset-ui/core';
|
||||
import React, { useMemo } from 'react';
|
||||
import { filterXSS } from 'xss';
|
||||
|
||||
export type TooltipProps = {
|
||||
|
@ -31,6 +32,22 @@ export type TooltipProps = {
|
|||
| undefined;
|
||||
};
|
||||
|
||||
const StyledDiv = styled.div<{ top: number; left: number }>`
|
||||
${({ theme, top, left }) => `
|
||||
position: absolute;
|
||||
top: ${top}px;
|
||||
left: ${left}px;
|
||||
padding: ${theme.gridUnit * 2}px;
|
||||
margin: ${theme.gridUnit * 2}px;
|
||||
background: ${theme.colors.grayscale.dark2};
|
||||
color: ${theme.colors.grayscale.light5};
|
||||
maxWidth: 300px;
|
||||
fontSize: ${theme.typography.sizes.s}px;
|
||||
zIndex: 9;
|
||||
pointerEvents: none;
|
||||
`}
|
||||
`;
|
||||
|
||||
export default function Tooltip(props: TooltipProps) {
|
||||
const { tooltip } = props;
|
||||
if (typeof tooltip === 'undefined' || tooltip === null) {
|
||||
|
@ -39,24 +56,6 @@ export default function Tooltip(props: TooltipProps) {
|
|||
|
||||
const { x, y, content } = tooltip;
|
||||
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const style: CSSProperties = useMemo(
|
||||
() => ({
|
||||
position: 'absolute',
|
||||
top: `${y}px`,
|
||||
left: `${x}px`,
|
||||
padding: '8px',
|
||||
margin: '8px',
|
||||
background: 'rgba(0, 0, 0, 0.8)',
|
||||
color: '#fff',
|
||||
maxWidth: '300px',
|
||||
fontSize: '12px',
|
||||
zIndex: 9,
|
||||
pointerEvents: 'none',
|
||||
}),
|
||||
[x, y],
|
||||
);
|
||||
|
||||
if (typeof content === 'string') {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const contentHtml = useMemo(
|
||||
|
@ -66,14 +65,18 @@ export default function Tooltip(props: TooltipProps) {
|
|||
[content],
|
||||
);
|
||||
return (
|
||||
<div style={style}>
|
||||
<StyledDiv top={y} left={x}>
|
||||
<div
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={contentHtml}
|
||||
/>
|
||||
</div>
|
||||
</StyledDiv>
|
||||
);
|
||||
}
|
||||
|
||||
return <div style={style}>{content}</div>;
|
||||
return (
|
||||
<StyledDiv top={y} left={x}>
|
||||
{content}
|
||||
</StyledDiv>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -55,9 +55,18 @@ const PivotTableWrapper = styled.div`
|
|||
`;
|
||||
|
||||
const METRIC_KEY = 'metric';
|
||||
const iconStyle = { stroke: 'black', strokeWidth: '16px' };
|
||||
const vals = ['value'];
|
||||
|
||||
const StyledPlusSquareOutlined = styled(PlusSquareOutlined)`
|
||||
stroke: ${({ theme }) => theme.colors.grayscale.light2};
|
||||
stroke-width: 16px;
|
||||
`;
|
||||
|
||||
const StyledMinusSquareOutlined = styled(MinusSquareOutlined)`
|
||||
stroke: ${({ theme }) => theme.colors.grayscale.light2};
|
||||
stroke-width: 16px;
|
||||
`;
|
||||
|
||||
const aggregatorsFactory = (formatter: NumberFormatter) => ({
|
||||
Count: aggregatorTemplates.count(formatter),
|
||||
'Count Unique Values': aggregatorTemplates.countUnique(formatter),
|
||||
|
@ -345,8 +354,8 @@ export default function PivotTableChart(props: PivotTableProps) {
|
|||
() => ({
|
||||
colSubtotalDisplay: { displayOnTop: colSubtotalPosition },
|
||||
rowSubtotalDisplay: { displayOnTop: rowSubtotalPosition },
|
||||
arrowCollapsed: <PlusSquareOutlined style={iconStyle} />,
|
||||
arrowExpanded: <MinusSquareOutlined style={iconStyle} />,
|
||||
arrowCollapsed: <StyledPlusSquareOutlined />,
|
||||
arrowExpanded: <StyledMinusSquareOutlined />,
|
||||
}),
|
||||
[colSubtotalPosition, rowSubtotalPosition],
|
||||
);
|
||||
|
|
|
@ -105,7 +105,7 @@ class WordCloud extends React.PureComponent<
|
|||
text: 'Text',
|
||||
},
|
||||
defaultEncoding: {
|
||||
color: { value: 'black' },
|
||||
color: { value: this.props.theme.colors.grayscale.dark2 },
|
||||
fontFamily: { value: this.props.theme.typography.families.sansSerif },
|
||||
fontSize: { value: 20 },
|
||||
fontWeight: { value: 'bold' },
|
||||
|
|
|
@ -68,7 +68,9 @@ type Props = {
|
|||
Readonly<typeof defaultProps>;
|
||||
|
||||
export default class BoxPlot extends React.PureComponent<Props> {
|
||||
private createEncoder = boxPlotEncoderFactory.createSelector();
|
||||
private createEncoder = boxPlotEncoderFactory(
|
||||
this.props.theme?.colors.darkGray,
|
||||
).createSelector();
|
||||
|
||||
private createMargin = createMarginSelector();
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ export type BoxPlotEncodingConfig = {
|
|||
color: ['Color', string];
|
||||
};
|
||||
|
||||
export const boxPlotEncoderFactory =
|
||||
export const boxPlotEncoderFactory = (darkGray: string) =>
|
||||
createEncoderFactory<BoxPlotEncodingConfig>({
|
||||
channelTypes: {
|
||||
x: 'XBand',
|
||||
|
@ -35,7 +35,7 @@ export const boxPlotEncoderFactory =
|
|||
defaultEncoding: {
|
||||
x: { field: 'x', type: 'nominal' },
|
||||
y: { field: 'y', type: 'quantitative' },
|
||||
color: { value: '#222' },
|
||||
color: { value: darkGray },
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ export type ScatterPlotEncodingConfig = {
|
|||
tooltip: ['Text', string, 'multiple'];
|
||||
};
|
||||
|
||||
export const scatterPlotEncoderFactory =
|
||||
export const scatterPlotEncoderFactory = (darkGray: string) =>
|
||||
createEncoderFactory<ScatterPlotEncodingConfig>({
|
||||
channelTypes: {
|
||||
x: 'X',
|
||||
|
@ -48,7 +48,7 @@ export const scatterPlotEncoderFactory =
|
|||
defaultEncoding: {
|
||||
x: { field: 'x', type: 'quantitative' },
|
||||
y: { field: 'y', type: 'quantitative' },
|
||||
fill: { value: '#222' },
|
||||
fill: { value: darkGray },
|
||||
group: [],
|
||||
size: { value: 5 },
|
||||
stroke: { value: 'none' },
|
||||
|
|
|
@ -67,7 +67,9 @@ type Props = {
|
|||
Readonly<typeof defaultProps>;
|
||||
|
||||
export default class ScatterPlot extends PureComponent<Props> {
|
||||
private createEncoder = scatterPlotEncoderFactory.createSelector();
|
||||
private createEncoder = scatterPlotEncoderFactory(
|
||||
this.props.theme?.colors.darkGray,
|
||||
).createSelector();
|
||||
|
||||
private createMargin = createMarginSelector();
|
||||
|
||||
|
|
Loading…
Reference in New Issue