mirror of
https://github.com/apache/superset.git
synced 2026-04-17 23:25:05 +00:00
refactor(monorepo): move superset-ui to superset(stage 2) (#17552)
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React, { useCallback } from 'react';
|
||||
import Echart from '../components/Echart';
|
||||
import { EventHandlers } from '../types';
|
||||
import { BoxPlotChartTransformedProps } from './types';
|
||||
|
||||
export default function EchartsBoxPlot({
|
||||
height,
|
||||
width,
|
||||
echartOptions,
|
||||
setDataMask,
|
||||
labelMap,
|
||||
groupby,
|
||||
selectedValues,
|
||||
formData,
|
||||
}: BoxPlotChartTransformedProps) {
|
||||
const handleChange = useCallback(
|
||||
(values: string[]) => {
|
||||
if (!formData.emitFilter) {
|
||||
return;
|
||||
}
|
||||
|
||||
const groupbyValues = values.map(value => labelMap[value]);
|
||||
|
||||
setDataMask({
|
||||
extraFormData: {
|
||||
filters:
|
||||
values.length === 0
|
||||
? []
|
||||
: groupby.map((col, idx) => {
|
||||
const val = groupbyValues.map(v => v[idx]);
|
||||
if (val === null || val === undefined)
|
||||
return {
|
||||
col,
|
||||
op: 'IS NULL',
|
||||
};
|
||||
return {
|
||||
col,
|
||||
op: 'IN',
|
||||
val: val as (string | number | boolean)[],
|
||||
};
|
||||
}),
|
||||
},
|
||||
filterState: {
|
||||
value: groupbyValues.length ? groupbyValues : null,
|
||||
selectedValues: values.length ? values : null,
|
||||
},
|
||||
});
|
||||
},
|
||||
[groupby, labelMap, setDataMask, selectedValues],
|
||||
);
|
||||
|
||||
const eventHandlers: EventHandlers = {
|
||||
click: props => {
|
||||
const { name } = props;
|
||||
const values = Object.values(selectedValues);
|
||||
if (values.includes(name)) {
|
||||
handleChange(values.filter(v => v !== name));
|
||||
} else {
|
||||
handleChange([name]);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Echart
|
||||
height={height}
|
||||
width={width}
|
||||
echartOptions={echartOptions}
|
||||
eventHandlers={eventHandlers}
|
||||
selectedValues={selectedValues}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { buildQueryContext } from '@superset-ui/core';
|
||||
import { boxplotOperator } from '@superset-ui/chart-controls';
|
||||
import { BoxPlotQueryFormData } from './types';
|
||||
|
||||
export default function buildQuery(formData: BoxPlotQueryFormData) {
|
||||
const { columns = [], granularity_sqla, groupby = [] } = formData;
|
||||
return buildQueryContext(formData, baseQueryObject => {
|
||||
const distributionColumns: string[] = [];
|
||||
// For now default to using the temporal column as distribution column.
|
||||
// In the future this control should be made mandatory.
|
||||
if (!columns.length && granularity_sqla) {
|
||||
distributionColumns.push(granularity_sqla);
|
||||
}
|
||||
return [
|
||||
{
|
||||
...baseQueryObject,
|
||||
columns: [...distributionColumns, ...columns, ...groupby],
|
||||
series_columns: groupby,
|
||||
post_processing: [boxplotOperator(formData, baseQueryObject)],
|
||||
},
|
||||
];
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t } from '@superset-ui/core';
|
||||
import {
|
||||
D3_FORMAT_DOCS,
|
||||
D3_FORMAT_OPTIONS,
|
||||
D3_TIME_FORMAT_OPTIONS,
|
||||
formatSelectOptions,
|
||||
sections,
|
||||
emitFilterControl,
|
||||
ControlPanelConfig,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
sections.legacyTimeseriesTime,
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['metrics'],
|
||||
['adhoc_filters'],
|
||||
emitFilterControl,
|
||||
['groupby'],
|
||||
['columns'], // TODO: this should be migrated to `series_columns`
|
||||
['series_limit'],
|
||||
['series_limit_metric'],
|
||||
[
|
||||
{
|
||||
name: 'whiskerOptions',
|
||||
config: {
|
||||
clearable: false,
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
label: t('Whisker/outlier options'),
|
||||
default: 'Tukey',
|
||||
description: t(
|
||||
'Determines how whiskers and outliers are calculated.',
|
||||
),
|
||||
choices: formatSelectOptions([
|
||||
'Tukey',
|
||||
'Min/max (no outliers)',
|
||||
'2/98 percentiles',
|
||||
'9/91 percentiles',
|
||||
]),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
sections.titleControls,
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
['color_scheme'],
|
||||
[
|
||||
{
|
||||
name: 'x_ticks_layout',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
label: t('X Tick Layout'),
|
||||
choices: formatSelectOptions([
|
||||
'auto',
|
||||
'flat',
|
||||
'45°',
|
||||
'90°',
|
||||
'staggered',
|
||||
]),
|
||||
default: 'auto',
|
||||
clearable: false,
|
||||
renderTrigger: true,
|
||||
description: t('The way the ticks are laid out on the X-axis'),
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'number_format',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
label: t('Number format'),
|
||||
renderTrigger: true,
|
||||
default: 'SMART_NUMBER',
|
||||
choices: D3_FORMAT_OPTIONS,
|
||||
description: `${t(
|
||||
'D3 format syntax: https://github.com/d3/d3-format',
|
||||
)} ${t('Only applies when "Label Type" is set to show values.')}`,
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'date_format',
|
||||
config: {
|
||||
type: 'SelectControl',
|
||||
freeForm: true,
|
||||
label: t('Date format'),
|
||||
renderTrigger: true,
|
||||
choices: D3_TIME_FORMAT_OPTIONS,
|
||||
default: 'smart_date',
|
||||
description: D3_FORMAT_DOCS,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
],
|
||||
controlOverrides: {
|
||||
groupby: {
|
||||
label: t('Series'),
|
||||
description: t('Categories to group by on the x-axis.'),
|
||||
},
|
||||
columns: {
|
||||
label: t('Distribute across'),
|
||||
multi: true,
|
||||
description: t(
|
||||
'Columns to calculate distribution across. Defaults to temporal column if left empty.',
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { t, ChartMetadata, ChartPlugin, Behavior } from '@superset-ui/core';
|
||||
import buildQuery from './buildQuery';
|
||||
import controlPanel from './controlPanel';
|
||||
import transformProps from './transformProps';
|
||||
import example from './images/BoxPlot.jpg';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import { BoxPlotQueryFormData, EchartsBoxPlotChartProps } from './types';
|
||||
|
||||
export default class EchartsBoxPlotChartPlugin extends ChartPlugin<
|
||||
BoxPlotQueryFormData,
|
||||
EchartsBoxPlotChartProps
|
||||
> {
|
||||
/**
|
||||
* The constructor is used to pass relevant metadata and callbacks that get
|
||||
* registered in respective registries that are used throughout the library
|
||||
* and application. A more thorough description of each property is given in
|
||||
* the respective imported file.
|
||||
*
|
||||
* It is worth noting that `buildQuery` and is optional, and only needed for
|
||||
* advanced visualizations that require either post processing operations
|
||||
* (pivoting, rolling aggregations, sorting etc) or submitting multiple queries.
|
||||
*/
|
||||
constructor() {
|
||||
super({
|
||||
buildQuery,
|
||||
controlPanel,
|
||||
loadChart: () => import('./EchartsBoxPlot'),
|
||||
metadata: new ChartMetadata({
|
||||
behaviors: [Behavior.INTERACTIVE_CHART],
|
||||
category: t('Distribution'),
|
||||
credits: ['https://echarts.apache.org'],
|
||||
description: t(
|
||||
'Also known as a box and whisker plot, this visualization compares the distributions of a related metric across multiple groups. The box in the middle emphasizes the mean, median, and inner 2 quartiles. The whiskers around each box visualize the min, max, range, and outer 2 quartiles.',
|
||||
),
|
||||
exampleGallery: [{ url: example }],
|
||||
name: t('Box Plot'),
|
||||
tags: [t('ECharts'), t('Range'), t('Statistical')],
|
||||
thumbnail,
|
||||
}),
|
||||
transformProps,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
CategoricalColorNamespace,
|
||||
DataRecordValue,
|
||||
getColumnLabel,
|
||||
getMetricLabel,
|
||||
getNumberFormatter,
|
||||
getTimeFormatter,
|
||||
} from '@superset-ui/core';
|
||||
import { EChartsCoreOption, BoxplotSeriesOption } from 'echarts';
|
||||
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
||||
import {
|
||||
BoxPlotChartTransformedProps,
|
||||
BoxPlotQueryFormData,
|
||||
EchartsBoxPlotChartProps,
|
||||
} from './types';
|
||||
import {
|
||||
extractGroupbyLabel,
|
||||
getColtypesMapping,
|
||||
sanitizeHtml,
|
||||
} from '../utils/series';
|
||||
import { defaultGrid, defaultTooltip, defaultYAxis } from '../defaults';
|
||||
import { getPadding } from '../Timeseries/transformers';
|
||||
import { OpacityEnum } from '../constants';
|
||||
|
||||
export default function transformProps(
|
||||
chartProps: EchartsBoxPlotChartProps,
|
||||
): BoxPlotChartTransformedProps {
|
||||
const { width, height, formData, hooks, filterState, queriesData } =
|
||||
chartProps;
|
||||
const { data = [] } = queriesData[0];
|
||||
const { setDataMask = () => {} } = hooks;
|
||||
const coltypeMapping = getColtypesMapping(queriesData[0]);
|
||||
const {
|
||||
colorScheme,
|
||||
groupby = [],
|
||||
metrics = [],
|
||||
numberFormat,
|
||||
dateFormat,
|
||||
xTicksLayout,
|
||||
emitFilter,
|
||||
legendOrientation = 'top',
|
||||
xAxisTitle,
|
||||
yAxisTitle,
|
||||
xAxisTitleMargin,
|
||||
yAxisTitleMargin,
|
||||
yAxisTitlePosition,
|
||||
} = formData as BoxPlotQueryFormData;
|
||||
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
|
||||
const numberFormatter = getNumberFormatter(numberFormat);
|
||||
const metricLabels = metrics.map(getMetricLabel);
|
||||
const groupbyLabels = groupby.map(getColumnLabel);
|
||||
|
||||
const transformedData = data
|
||||
.map((datum: any) => {
|
||||
const groupbyLabel = extractGroupbyLabel({
|
||||
datum,
|
||||
groupby: groupbyLabels,
|
||||
coltypeMapping,
|
||||
timeFormatter: getTimeFormatter(dateFormat),
|
||||
});
|
||||
return metricLabels.map(metric => {
|
||||
const name =
|
||||
metricLabels.length === 1
|
||||
? groupbyLabel
|
||||
: `${groupbyLabel}, ${metric}`;
|
||||
const isFiltered =
|
||||
filterState.selectedValues &&
|
||||
!filterState.selectedValues.includes(name);
|
||||
return {
|
||||
name,
|
||||
value: [
|
||||
datum[`${metric}__min`],
|
||||
datum[`${metric}__q1`],
|
||||
datum[`${metric}__median`],
|
||||
datum[`${metric}__q3`],
|
||||
datum[`${metric}__max`],
|
||||
datum[`${metric}__mean`],
|
||||
datum[`${metric}__count`],
|
||||
datum[`${metric}__outliers`],
|
||||
],
|
||||
itemStyle: {
|
||||
color: colorFn(groupbyLabel),
|
||||
opacity: isFiltered ? OpacityEnum.SemiTransparent : 0.6,
|
||||
borderColor: colorFn(groupbyLabel),
|
||||
},
|
||||
};
|
||||
});
|
||||
})
|
||||
.flatMap(row => row);
|
||||
const outlierData = data
|
||||
.map(datum =>
|
||||
metricLabels.map(metric => {
|
||||
const groupbyLabel = extractGroupbyLabel({
|
||||
datum,
|
||||
groupby: groupbyLabels,
|
||||
coltypeMapping,
|
||||
timeFormatter: getTimeFormatter(dateFormat),
|
||||
});
|
||||
const name =
|
||||
metricLabels.length === 1
|
||||
? groupbyLabel
|
||||
: `${groupbyLabel}, ${metric}`;
|
||||
// Outlier data is a nested array of numbers (uncommon, therefore no need to add to DataRecordValue)
|
||||
const outlierDatum = (datum[`${metric}__outliers`] || []) as number[];
|
||||
const isFiltered =
|
||||
filterState.selectedValues &&
|
||||
!filterState.selectedValues.includes(name);
|
||||
return {
|
||||
name: 'outlier',
|
||||
type: 'scatter',
|
||||
data: outlierDatum.map(val => [name, val]),
|
||||
tooltip: {
|
||||
formatter: (param: { data: [string, number] }) => {
|
||||
const [outlierName, stats] = param.data;
|
||||
const headline = groupbyLabels.length
|
||||
? `<p><strong>${sanitizeHtml(outlierName)}</strong></p>`
|
||||
: '';
|
||||
return `${headline}${numberFormatter(stats)}`;
|
||||
},
|
||||
},
|
||||
itemStyle: {
|
||||
color: colorFn(groupbyLabel),
|
||||
opacity: isFiltered
|
||||
? OpacityEnum.SemiTransparent
|
||||
: OpacityEnum.NonTransparent,
|
||||
},
|
||||
};
|
||||
}),
|
||||
)
|
||||
.flat(2);
|
||||
|
||||
const labelMap = data.reduce(
|
||||
(acc: Record<string, DataRecordValue[]>, datum) => {
|
||||
const label = extractGroupbyLabel({
|
||||
datum,
|
||||
groupby: groupbyLabels,
|
||||
coltypeMapping,
|
||||
timeFormatter: getTimeFormatter(dateFormat),
|
||||
});
|
||||
return {
|
||||
...acc,
|
||||
[label]: groupbyLabels.map(col => datum[col]),
|
||||
};
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
const selectedValues = (filterState.selectedValues || []).reduce(
|
||||
(acc: Record<string, number>, selectedValue: string) => {
|
||||
const index = transformedData.findIndex(
|
||||
({ name }) => name === selectedValue,
|
||||
);
|
||||
return {
|
||||
...acc,
|
||||
[index]: selectedValue,
|
||||
};
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
let axisLabel;
|
||||
if (xTicksLayout === '45°') axisLabel = { rotate: -45 };
|
||||
else if (xTicksLayout === '90°') axisLabel = { rotate: -90 };
|
||||
else if (xTicksLayout === 'flat') axisLabel = { rotate: 0 };
|
||||
else if (xTicksLayout === 'staggered') axisLabel = { rotate: -45 };
|
||||
else axisLabel = { show: true };
|
||||
|
||||
const series: BoxplotSeriesOption[] = [
|
||||
{
|
||||
name: 'boxplot',
|
||||
type: 'boxplot',
|
||||
data: transformedData,
|
||||
tooltip: {
|
||||
formatter: (param: CallbackDataParams) => {
|
||||
// @ts-ignore
|
||||
const {
|
||||
value,
|
||||
name,
|
||||
}: {
|
||||
value: [
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
number[],
|
||||
];
|
||||
name: string;
|
||||
} = param;
|
||||
const headline = name
|
||||
? `<p><strong>${sanitizeHtml(name)}</strong></p>`
|
||||
: '';
|
||||
const stats = [
|
||||
`Max: ${numberFormatter(value[5])}`,
|
||||
`3rd Quartile: ${numberFormatter(value[4])}`,
|
||||
`Mean: ${numberFormatter(value[6])}`,
|
||||
`Median: ${numberFormatter(value[3])}`,
|
||||
`1st Quartile: ${numberFormatter(value[2])}`,
|
||||
`Min: ${numberFormatter(value[1])}`,
|
||||
`# Observations: ${numberFormatter(value[7])}`,
|
||||
];
|
||||
if (value[8].length > 0) {
|
||||
stats.push(`# Outliers: ${numberFormatter(value[8].length)}`);
|
||||
}
|
||||
return headline + stats.join('<br/>');
|
||||
},
|
||||
},
|
||||
},
|
||||
// @ts-ignore
|
||||
...outlierData,
|
||||
];
|
||||
const addYAxisTitleOffset = !!yAxisTitle;
|
||||
const addXAxisTitleOffset = !!xAxisTitle;
|
||||
const chartPadding = getPadding(
|
||||
true,
|
||||
legendOrientation,
|
||||
addYAxisTitleOffset,
|
||||
false,
|
||||
null,
|
||||
addXAxisTitleOffset,
|
||||
yAxisTitlePosition,
|
||||
yAxisTitleMargin,
|
||||
xAxisTitleMargin,
|
||||
);
|
||||
const echartOptions: EChartsCoreOption = {
|
||||
grid: {
|
||||
...defaultGrid,
|
||||
...chartPadding,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: transformedData.map(row => row.name),
|
||||
axisLabel,
|
||||
name: xAxisTitle,
|
||||
nameGap: xAxisTitleMargin,
|
||||
nameLocation: 'middle',
|
||||
},
|
||||
yAxis: {
|
||||
...defaultYAxis,
|
||||
type: 'value',
|
||||
axisLabel: { formatter: numberFormatter },
|
||||
name: yAxisTitle,
|
||||
nameGap: yAxisTitleMargin,
|
||||
nameLocation: yAxisTitlePosition === 'Left' ? 'middle' : 'end',
|
||||
},
|
||||
tooltip: {
|
||||
...defaultTooltip,
|
||||
trigger: 'item',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
},
|
||||
},
|
||||
series,
|
||||
};
|
||||
|
||||
return {
|
||||
formData,
|
||||
width,
|
||||
height,
|
||||
echartOptions,
|
||||
setDataMask,
|
||||
emitFilter,
|
||||
labelMap,
|
||||
groupby,
|
||||
selectedValues,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
ChartDataResponseResult,
|
||||
ChartProps,
|
||||
DataRecordValue,
|
||||
QueryFormColumn,
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
} from '@superset-ui/core';
|
||||
import { EChartsCoreOption } from 'echarts';
|
||||
import { EchartsTitleFormData, DEFAULT_TITLE_FORM_DATA } from '../types';
|
||||
|
||||
export type BoxPlotQueryFormData = QueryFormData & {
|
||||
numberFormat?: string;
|
||||
whiskerOptions?: BoxPlotFormDataWhiskerOptions;
|
||||
xTickLayout?: BoxPlotFormXTickLayout;
|
||||
emitFilter: boolean;
|
||||
} & EchartsTitleFormData;
|
||||
|
||||
export type BoxPlotFormDataWhiskerOptions =
|
||||
| 'Tukey'
|
||||
| 'Min/max (no outliers)'
|
||||
| '2/98 percentiles'
|
||||
| '9/91 percentiles';
|
||||
|
||||
export type BoxPlotFormXTickLayout =
|
||||
| '45°'
|
||||
| '90°'
|
||||
| 'auto'
|
||||
| 'flat'
|
||||
| 'staggered';
|
||||
|
||||
// @ts-ignore
|
||||
export const DEFAULT_FORM_DATA: BoxPlotQueryFormData = {
|
||||
emitFilter: false,
|
||||
...DEFAULT_TITLE_FORM_DATA,
|
||||
};
|
||||
|
||||
export interface EchartsBoxPlotChartProps extends ChartProps {
|
||||
formData: BoxPlotQueryFormData;
|
||||
queriesData: ChartDataResponseResult[];
|
||||
}
|
||||
|
||||
export interface BoxPlotChartTransformedProps {
|
||||
formData: BoxPlotQueryFormData;
|
||||
height: number;
|
||||
width: number;
|
||||
echartOptions: EChartsCoreOption;
|
||||
emitFilter: boolean;
|
||||
setDataMask: SetDataMaskHook;
|
||||
labelMap: Record<string, DataRecordValue[]>;
|
||||
groupby: QueryFormColumn[];
|
||||
selectedValues: Record<number, string>;
|
||||
}
|
||||
Reference in New Issue
Block a user