feat: Adds the ECharts Sankey chart (#29329)
This commit is contained in:
parent
58f33d227a
commit
c83d5b88e1
|
|
@ -33,7 +33,7 @@ const metadata = new ChartMetadata({
|
|||
{ url: example1, description: t('Demographics') },
|
||||
{ url: example2, description: t('Survey Responses') },
|
||||
],
|
||||
name: t('Sankey Diagram'),
|
||||
name: t('Sankey Diagram (legacy)'),
|
||||
tags: [
|
||||
t('Categorical'),
|
||||
t('Directional'),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* 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 { SankeyTransformedProps } from './types';
|
||||
import Echart from '../components/Echart';
|
||||
|
||||
export default function Sankey(props: SankeyTransformedProps) {
|
||||
const { height, width, echartOptions, refs } = props;
|
||||
|
||||
return (
|
||||
<Echart
|
||||
refs={refs}
|
||||
height={height}
|
||||
width={width}
|
||||
echartOptions={echartOptions}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* 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 { SankeyFormData } from './types';
|
||||
|
||||
export default function buildQuery(formData: SankeyFormData) {
|
||||
const { metric, sort_by_metric, source, target } = formData;
|
||||
const groupby = [source, target];
|
||||
return buildQueryContext(formData, baseQueryObject => [
|
||||
{
|
||||
...baseQueryObject,
|
||||
groupby,
|
||||
...(sort_by_metric && { orderby: [[metric, false]] }),
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 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, validateNonEmpty } from '@superset-ui/core';
|
||||
import {
|
||||
ControlPanelConfig,
|
||||
dndGroupByControl,
|
||||
} from '@superset-ui/chart-controls';
|
||||
|
||||
const config: ControlPanelConfig = {
|
||||
controlPanelSections: [
|
||||
{
|
||||
label: t('Query'),
|
||||
expanded: true,
|
||||
controlSetRows: [
|
||||
[
|
||||
{
|
||||
name: 'source',
|
||||
config: {
|
||||
...dndGroupByControl,
|
||||
label: t('Source'),
|
||||
multi: false,
|
||||
description: t(
|
||||
'The column to be used as the source of the edge.',
|
||||
),
|
||||
validators: [validateNonEmpty],
|
||||
freeForm: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
name: 'target',
|
||||
config: {
|
||||
...dndGroupByControl,
|
||||
label: t('Target'),
|
||||
multi: false,
|
||||
description: t(
|
||||
'The column to be used as the target of the edge.',
|
||||
),
|
||||
validators: [validateNonEmpty],
|
||||
freeForm: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
['metric'],
|
||||
['adhoc_filters'],
|
||||
['row_limit'],
|
||||
['sort_by_metric'],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: t('Chart Options'),
|
||||
expanded: true,
|
||||
controlSetRows: [['color_scheme']],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default config;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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
|
||||
* regardin
|
||||
* g 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 { Behavior, ChartMetadata, ChartPlugin, t } from '@superset-ui/core';
|
||||
import buildQuery from './buildQuery';
|
||||
import controlPanel from './controlPanel';
|
||||
import transformProps from './transformProps';
|
||||
import thumbnail from './images/thumbnail.png';
|
||||
import example1 from './images/example1.png';
|
||||
import example2 from './images/example2.png';
|
||||
import { SankeyChartProps, SankeyFormData } from './types';
|
||||
|
||||
export default class EchartsSankeyChartPlugin extends ChartPlugin<
|
||||
SankeyFormData,
|
||||
SankeyChartProps
|
||||
> {
|
||||
/**
|
||||
* 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('./Sankey'),
|
||||
metadata: new ChartMetadata({
|
||||
behaviors: [Behavior.InteractiveChart],
|
||||
credits: ['https://echarts.apache.org'],
|
||||
category: t('Flow'),
|
||||
description: t(
|
||||
`The Sankey chart visually tracks the movement and transformation of values across
|
||||
system stages. Nodes represent stages, connected by links depicting value flow. Node
|
||||
height corresponds to the visualized metric, providing a clear representation of
|
||||
value distribution and transformation.`,
|
||||
),
|
||||
exampleGallery: [{ url: example1 }, { url: example2 }],
|
||||
name: t('Sankey Chart'),
|
||||
tags: [t('Directional'), t('Distribution'), t('Flow')],
|
||||
thumbnail,
|
||||
}),
|
||||
transformProps,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* 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 { EChartsOption, SankeySeriesOption } from 'echarts';
|
||||
import { CallbackDataParams } from 'echarts/types/src/util/types';
|
||||
import {
|
||||
CategoricalColorNamespace,
|
||||
NumberFormats,
|
||||
getColumnLabel,
|
||||
getMetricLabel,
|
||||
getNumberFormatter,
|
||||
tooltipHtml,
|
||||
} from '@superset-ui/core';
|
||||
import { SankeyChartProps, SankeyTransformedProps } from './types';
|
||||
import { Refs } from '../types';
|
||||
import { getDefaultTooltip } from '../utils/tooltip';
|
||||
import { getPercentFormatter } from '../utils/formatters';
|
||||
|
||||
type Link = { source: string; target: string; value: number };
|
||||
|
||||
export default function transformProps(
|
||||
chartProps: SankeyChartProps,
|
||||
): SankeyTransformedProps {
|
||||
const refs: Refs = {};
|
||||
const { formData, height, hooks, queriesData, width } = chartProps;
|
||||
const { onLegendStateChanged } = hooks;
|
||||
const { colorScheme, metric, source, target } = formData;
|
||||
const { data } = queriesData[0];
|
||||
const colorFn = CategoricalColorNamespace.getScale(colorScheme);
|
||||
const metricLabel = getMetricLabel(metric);
|
||||
const valueFormatter = getNumberFormatter(NumberFormats.FLOAT_2_POINT);
|
||||
const percentFormatter = getPercentFormatter(NumberFormats.PERCENT_2_POINT);
|
||||
|
||||
const links: Link[] = [];
|
||||
const set = new Set<string>();
|
||||
data.forEach(datum => {
|
||||
const sourceName = String(datum[getColumnLabel(source)]);
|
||||
const targetName = String(datum[getColumnLabel(target)]);
|
||||
const value = datum[metricLabel] as number;
|
||||
set.add(sourceName);
|
||||
set.add(targetName);
|
||||
links.push({
|
||||
source: sourceName,
|
||||
target: targetName,
|
||||
value,
|
||||
});
|
||||
});
|
||||
|
||||
const seriesData: NonNullable<SankeySeriesOption['data']> = Array.from(
|
||||
set,
|
||||
).map(name => ({
|
||||
name,
|
||||
itemStyle: {
|
||||
color: colorFn(name),
|
||||
},
|
||||
}));
|
||||
|
||||
// stores a map with the total values for each node considering the links
|
||||
const nodeValues = new Map<string, number>();
|
||||
links.forEach(link => {
|
||||
const { source, target, value } = link;
|
||||
const sourceValue = nodeValues.get(source) || 0;
|
||||
const targetValue = nodeValues.get(target) || 0;
|
||||
nodeValues.set(source, sourceValue + value);
|
||||
nodeValues.set(target, targetValue + value);
|
||||
});
|
||||
|
||||
const tooltipFormatter = (params: CallbackDataParams) => {
|
||||
const { name, data } = params;
|
||||
const value = params.value as number;
|
||||
const rows = [[metricLabel, valueFormatter.format(value)]];
|
||||
const { source, target } = data as Link;
|
||||
if (source && target) {
|
||||
rows.push([
|
||||
`% (${source})`,
|
||||
percentFormatter.format(value / nodeValues.get(source)!),
|
||||
]);
|
||||
rows.push([
|
||||
`% (${target})`,
|
||||
percentFormatter.format(value / nodeValues.get(target)!),
|
||||
]);
|
||||
}
|
||||
return tooltipHtml(rows, name);
|
||||
};
|
||||
|
||||
const echartOptions: EChartsOption = {
|
||||
series: {
|
||||
animation: false,
|
||||
data: seriesData,
|
||||
lineStyle: {
|
||||
color: 'source',
|
||||
},
|
||||
links,
|
||||
type: 'sankey',
|
||||
},
|
||||
tooltip: {
|
||||
...getDefaultTooltip(refs),
|
||||
formatter: tooltipFormatter,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
refs,
|
||||
formData,
|
||||
width,
|
||||
height,
|
||||
echartOptions,
|
||||
onLegendStateChanged,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* 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 {
|
||||
QueryFormColumn,
|
||||
QueryFormData,
|
||||
QueryFormMetric,
|
||||
} from '@superset-ui/core';
|
||||
import { BaseChartProps, BaseTransformedProps } from '../types';
|
||||
|
||||
export type SankeyFormData = QueryFormData & {
|
||||
colorScheme: string;
|
||||
metric: QueryFormMetric;
|
||||
source: QueryFormColumn;
|
||||
target: QueryFormColumn;
|
||||
};
|
||||
|
||||
export interface SankeyChartProps extends BaseChartProps<SankeyFormData> {
|
||||
formData: SankeyFormData;
|
||||
}
|
||||
|
||||
export type SankeyTransformedProps = BaseTransformedProps<SankeyFormData> & {};
|
||||
|
|
@ -41,6 +41,7 @@ export {
|
|||
} from './BigNumber';
|
||||
export { default as EchartsSunburstChartPlugin } from './Sunburst';
|
||||
export { default as EchartsBubbleChartPlugin } from './Bubble';
|
||||
export { default as EchartsSankeyChartPlugin } from './Sankey';
|
||||
export { default as EchartsWaterfallChartPlugin } from './Waterfall';
|
||||
|
||||
export { default as BoxPlotTransformProps } from './BoxPlot/transformProps';
|
||||
|
|
@ -58,6 +59,7 @@ export { default as SunburstTransformProps } from './Sunburst/transformProps';
|
|||
export { default as BubbleTransformProps } from './Bubble/transformProps';
|
||||
export { default as WaterfallTransformProps } from './Waterfall/transformProps';
|
||||
export { default as HistogramTransformProps } from './Histogram/transformProps';
|
||||
export { default as SankeyTransformProps } from './Sankey/transformProps';
|
||||
|
||||
export { DEFAULT_FORM_DATA as TimeseriesDefaultFormData } from './Timeseries/constants';
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import {
|
|||
EchartsHistogramChartPlugin,
|
||||
EchartsRadarChartPlugin,
|
||||
EchartsFunnelChartPlugin,
|
||||
EchartsSankeyChartPlugin,
|
||||
EchartsTreemapChartPlugin,
|
||||
EchartsMixedTimeseriesChartPlugin,
|
||||
EchartsTreeChartPlugin,
|
||||
|
|
@ -112,6 +113,7 @@ export default class MainPreset extends Preset {
|
|||
new DistBarChartPlugin().configure({ key: 'dist_bar' }),
|
||||
new EventFlowChartPlugin().configure({ key: 'event_flow' }),
|
||||
new EchartsFunnelChartPlugin().configure({ key: 'funnel' }),
|
||||
new EchartsSankeyChartPlugin().configure({ key: 'sankey_v2' }),
|
||||
new EchartsTreemapChartPlugin().configure({ key: 'treemap_v2' }),
|
||||
new EchartsGaugeChartPlugin().configure({ key: 'gauge_chart' }),
|
||||
new EchartsGraphChartPlugin().configure({ key: 'graph_chart' }),
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class VizType(str, Enum):
|
|||
HISTOGRAM = "histogram"
|
||||
LINE = "line"
|
||||
PIVOT_TABLE = "pivot_table"
|
||||
SANKEY = "sankey"
|
||||
SUNBURST = "sunburst"
|
||||
TREEMAP = "treemap"
|
||||
|
||||
|
|
@ -89,6 +90,7 @@ def migrate(viz_type: VizType, is_downgrade: bool = False) -> None:
|
|||
MigrateHistogramChart,
|
||||
MigrateLineChart,
|
||||
MigratePivotTable,
|
||||
MigrateSankey,
|
||||
MigrateSunburst,
|
||||
MigrateTreeMap,
|
||||
)
|
||||
|
|
@ -103,6 +105,7 @@ def migrate(viz_type: VizType, is_downgrade: bool = False) -> None:
|
|||
VizType.HISTOGRAM: MigrateHistogramChart,
|
||||
VizType.LINE: MigrateLineChart,
|
||||
VizType.PIVOT_TABLE: MigratePivotTable,
|
||||
VizType.SANKEY: MigrateSankey,
|
||||
VizType.SUNBURST: MigrateSunburst,
|
||||
VizType.TREEMAP: MigrateTreeMap,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
slice_name: Sankey
|
||||
description: null
|
||||
certified_by: null
|
||||
certification_details: null
|
||||
viz_type: sankey_v2
|
||||
params:
|
||||
datasource: 22__table
|
||||
viz_type: sankey_v2
|
||||
source: product_line
|
||||
target: deal_size
|
||||
metric: count
|
||||
adhoc_filters:
|
||||
- clause: WHERE
|
||||
subject: order_date
|
||||
operator: TEMPORAL_RANGE
|
||||
comparator: No filter
|
||||
expressionType: SIMPLE
|
||||
row_limit: 10000
|
||||
color_scheme: supersetColors
|
||||
extra_form_data: {}
|
||||
dashboards: []
|
||||
cache_timeout: null
|
||||
uuid: fead4d46-ecb9-4fd9-8b9c-420629269c02
|
||||
version: 1.0.0
|
||||
dataset_uuid: e8623bb9-5e00-f531-506a-19607f5f8005
|
||||
|
|
@ -49,7 +49,7 @@ position:
|
|||
parents:
|
||||
- ROOT_ID
|
||||
- GRID_ID
|
||||
- ROW-Jq9auQfs6-
|
||||
- ROW-3XARWMYOfz
|
||||
type: CHART
|
||||
CHART-3tEC_8e-uS:
|
||||
children: []
|
||||
|
|
@ -147,7 +147,7 @@ position:
|
|||
parents:
|
||||
- ROOT_ID
|
||||
- GRID_ID
|
||||
- ROW-3XARWMYOfz
|
||||
- ROW-ux6j1ePT8I
|
||||
type: CHART
|
||||
CHART-EpsTnvUMuW:
|
||||
children: []
|
||||
|
|
@ -273,7 +273,7 @@ position:
|
|||
parents:
|
||||
- ROOT_ID
|
||||
- GRID_ID
|
||||
- ROW-ux6j1ePT8I
|
||||
- ROW-we3i1eOT75
|
||||
type: CHART
|
||||
CHART-gfrGP3BD76:
|
||||
children: []
|
||||
|
|
@ -289,6 +289,20 @@ position:
|
|||
- GRID_ID
|
||||
- ROW-W7YILGiS0-
|
||||
type: CHART
|
||||
CHART-Yi0u5d9otw:
|
||||
children: []
|
||||
id: CHART-Yi0u5d9otw
|
||||
meta:
|
||||
chartId: 359
|
||||
height: 50
|
||||
sliceName: Sankey
|
||||
uuid: fead4d46-ecb9-4fd9-8b9c-420629269c02
|
||||
width: 4
|
||||
parents:
|
||||
- ROOT_ID
|
||||
- GRID_ID
|
||||
- ROW-Jq9auQfs6-
|
||||
type: CHART
|
||||
CHART-j2o9aZo4HY:
|
||||
children: []
|
||||
id: CHART-j2o9aZo4HY
|
||||
|
|
@ -370,6 +384,7 @@ position:
|
|||
- ROW-Jq9auQfs6-
|
||||
- ROW-3XARWMYOfz
|
||||
- ROW-ux6j1ePT8I
|
||||
- ROW-we3i1eOT75
|
||||
id: GRID_ID
|
||||
parents:
|
||||
- ROOT_ID
|
||||
|
|
@ -386,9 +401,9 @@ position:
|
|||
type: ROOT
|
||||
ROW-3XARWMYOfz:
|
||||
children:
|
||||
- CHART-33vjmwrGX1
|
||||
- CHART-3tEC_8e-uS
|
||||
- CHART-A4qrvR24Ne
|
||||
- CHART-DqaJJ8Fse6
|
||||
id: ROW-3XARWMYOfz
|
||||
meta:
|
||||
background: BACKGROUND_TRANSPARENT
|
||||
|
|
@ -400,7 +415,7 @@ position:
|
|||
children:
|
||||
- CHART-qZh51tuuRH
|
||||
- CHART-j2o9aZo4HY
|
||||
- CHART-33vjmwrGX1
|
||||
- CHART-Yi0u5d9otw
|
||||
id: ROW-Jq9auQfs6-
|
||||
meta:
|
||||
background: BACKGROUND_TRANSPARENT
|
||||
|
|
@ -470,9 +485,9 @@ position:
|
|||
type: ROW
|
||||
ROW-ux6j1ePT8I:
|
||||
children:
|
||||
- CHART-DqaJJ8Fse6
|
||||
- CHART-XwFZukVv8E
|
||||
- CHART-KE7lk61Tbt
|
||||
- CHART-aAhaxRYu_t
|
||||
id: ROW-ux6j1ePT8I
|
||||
meta:
|
||||
background: BACKGROUND_TRANSPARENT
|
||||
|
|
@ -480,6 +495,16 @@ position:
|
|||
- ROOT_ID
|
||||
- GRID_ID
|
||||
type: ROW
|
||||
ROW-we3i1eOT75:
|
||||
children:
|
||||
- CHART-aAhaxRYu_t
|
||||
id: ROW-we3i1eOT75
|
||||
meta:
|
||||
background: BACKGROUND_TRANSPARENT
|
||||
parents:
|
||||
- ROOT_ID
|
||||
- GRID_ID
|
||||
type: ROW
|
||||
metadata:
|
||||
color_scheme: supersetAndPresetColors
|
||||
refresh_frequency: 0
|
||||
|
|
|
|||
|
|
@ -303,3 +303,15 @@ class MigrateHistogramChart(MigrateViz):
|
|||
groupby = self.data.get("groupby")
|
||||
if not groupby:
|
||||
self.data["groupby"] = []
|
||||
|
||||
|
||||
class MigrateSankey(MigrateViz):
|
||||
source_viz_type = "sankey"
|
||||
target_viz_type = "sankey_v2"
|
||||
remove_keys = {"groupby"}
|
||||
|
||||
def _pre_action(self) -> None:
|
||||
groupby = self.data.get("groupby")
|
||||
if groupby and len(groupby) > 1:
|
||||
self.data["source"] = groupby[0]
|
||||
self.data["target"] = groupby[1]
|
||||
|
|
|
|||
Loading…
Reference in New Issue