fix: Disable cross filtering on charts with no dimensions (#30176)

This commit is contained in:
Kamil Gabryjelski 2024-09-09 12:43:14 +02:00 committed by GitHub
parent 0744abe87b
commit 3aafd29768
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 57 additions and 23 deletions

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Behavior, ChartMetadata, ChartPlugin, t } from '@superset-ui/core'; import { ChartMetadata, ChartPlugin, t } from '@superset-ui/core';
import thumbnail from './images/thumbnail.png'; import thumbnail from './images/thumbnail.png';
import transformProps from './transformProps'; import transformProps from './transformProps';
import buildQuery from './buildQuery'; import buildQuery from './buildQuery';
@ -25,6 +25,7 @@ import example1 from './images/example1.png';
import example2 from './images/example2.png'; import example2 from './images/example2.png';
import { EchartsBubbleChartProps, EchartsBubbleFormData } from './types'; import { EchartsBubbleChartProps, EchartsBubbleFormData } from './types';
// TODO: Implement cross filtering
export default class EchartsBubbleChartPlugin extends ChartPlugin< export default class EchartsBubbleChartPlugin extends ChartPlugin<
EchartsBubbleFormData, EchartsBubbleFormData,
EchartsBubbleChartProps EchartsBubbleChartProps
@ -35,7 +36,6 @@ export default class EchartsBubbleChartPlugin extends ChartPlugin<
controlPanel, controlPanel,
loadChart: () => import('./EchartsBubble'), loadChart: () => import('./EchartsBubble'),
metadata: new ChartMetadata({ metadata: new ChartMetadata({
behaviors: [Behavior.InteractiveChart],
category: t('Correlation'), category: t('Correlation'),
credits: ['https://echarts.apache.org'], credits: ['https://echarts.apache.org'],
description: t( description: t(

View File

@ -17,7 +17,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Behavior, ChartMetadata, ChartPlugin, t } from '@superset-ui/core'; import { ChartMetadata, ChartPlugin, t } from '@superset-ui/core';
import buildQuery from './buildQuery'; import buildQuery from './buildQuery';
import controlPanel from './controlPanel'; import controlPanel from './controlPanel';
import transformProps from './transformProps'; import transformProps from './transformProps';
@ -26,6 +26,7 @@ import example1 from './images/example1.png';
import example2 from './images/example2.png'; import example2 from './images/example2.png';
import { HistogramChartProps, HistogramFormData } from './types'; import { HistogramChartProps, HistogramFormData } from './types';
// TODO: Implement cross filtering
export default class EchartsHistogramChartPlugin extends ChartPlugin< export default class EchartsHistogramChartPlugin extends ChartPlugin<
HistogramFormData, HistogramFormData,
HistogramChartProps HistogramChartProps
@ -46,7 +47,6 @@ export default class EchartsHistogramChartPlugin extends ChartPlugin<
controlPanel, controlPanel,
loadChart: () => import('./Histogram'), loadChart: () => import('./Histogram'),
metadata: new ChartMetadata({ metadata: new ChartMetadata({
behaviors: [Behavior.InteractiveChart],
credits: ['https://echarts.apache.org'], credits: ['https://echarts.apache.org'],
category: t('Distribution'), category: t('Distribution'),
description: t( description: t(

View File

@ -110,13 +110,25 @@ export default function EchartsMixedTimeseries({
const handleChange = useCallback( const handleChange = useCallback(
(seriesName: string, seriesIndex: number) => { (seriesName: string, seriesIndex: number) => {
if (!emitCrossFilters) { const isFirst = isFirstQuery(seriesIndex);
if (
!emitCrossFilters ||
(isFirst && groupby.length === 0) ||
(!isFirst && groupbyB.length === 0)
) {
return; return;
} }
setDataMask(getCrossFilterDataMask(seriesName, seriesIndex).dataMask); setDataMask(getCrossFilterDataMask(seriesName, seriesIndex).dataMask);
}, },
[emitCrossFilters, setDataMask, getCrossFilterDataMask], [
isFirstQuery,
emitCrossFilters,
groupby.length,
groupbyB.length,
setDataMask,
getCrossFilterDataMask,
],
); );
const eventHandlers: EventHandlers = { const eventHandlers: EventHandlers = {
@ -140,7 +152,7 @@ export default function EchartsMixedTimeseries({
const isFirst = isFirstQuery(seriesIndex); const isFirst = isFirstQuery(seriesIndex);
const values = [ const values = [
...(eventParams.name ? [eventParams.name] : []), ...(eventParams.name ? [eventParams.name] : []),
...(isFirst ? labelMap : labelMapB)[eventParams.seriesName], ...((isFirst ? labelMap : labelMapB)[eventParams.seriesName] || []),
]; ];
if (data && xAxis.type === AxisType.Time) { if (data && xAxis.type === AxisType.Time) {
drillToDetailFilters.push({ drillToDetailFilters.push({
@ -179,9 +191,14 @@ export default function EchartsMixedTimeseries({
}), }),
}), }),
); );
const hasCrossFilter =
(isFirst && groupby.length > 0) || (!isFirst && groupbyB.length > 0);
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, { onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillToDetailFilters, drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(seriesName, seriesIndex), crossFilter: hasCrossFilter
? getCrossFilterDataMask(seriesName, seriesIndex)
: undefined,
drillBy: { drillBy: {
filters: drillByFilters, filters: drillByFilters,
groupbyFieldName: isFirst ? 'groupby' : 'groupby_b', groupbyFieldName: isFirst ? 'groupby' : 'groupby_b',

View File

@ -17,7 +17,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Behavior, ChartMetadata, ChartPlugin, t } from '@superset-ui/core'; import { ChartMetadata, ChartPlugin, t } from '@superset-ui/core';
import buildQuery from './buildQuery'; import buildQuery from './buildQuery';
import controlPanel from './controlPanel'; import controlPanel from './controlPanel';
import transformProps from './transformProps'; import transformProps from './transformProps';
@ -26,6 +26,7 @@ import example1 from './images/example1.png';
import example2 from './images/example2.png'; import example2 from './images/example2.png';
import { SankeyChartProps, SankeyFormData } from './types'; import { SankeyChartProps, SankeyFormData } from './types';
// TODO: Implement cross filtering
export default class EchartsSankeyChartPlugin extends ChartPlugin< export default class EchartsSankeyChartPlugin extends ChartPlugin<
SankeyFormData, SankeyFormData,
SankeyChartProps SankeyChartProps
@ -46,7 +47,6 @@ export default class EchartsSankeyChartPlugin extends ChartPlugin<
controlPanel, controlPanel,
loadChart: () => import('./Sankey'), loadChart: () => import('./Sankey'),
metadata: new ChartMetadata({ metadata: new ChartMetadata({
behaviors: [Behavior.InteractiveChart],
credits: ['https://echarts.apache.org'], credits: ['https://echarts.apache.org'],
category: t('Flow'), category: t('Flow'),
description: t( description: t(

View File

@ -95,7 +95,7 @@ export default function EchartsSunburst(props: SunburstTransformedProps) {
const handleChange = useCallback( const handleChange = useCallback(
(treePathInfo: TreePathInfo[]) => { (treePathInfo: TreePathInfo[]) => {
if (!emitCrossFilters) { if (!emitCrossFilters || !columns?.length) {
return; return;
} }
@ -142,7 +142,9 @@ export default function EchartsSunburst(props: SunburstTransformedProps) {
} }
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, { onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillToDetailFilters, drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(treePathInfo), crossFilter: columns?.length
? getCrossFilterDataMask(treePathInfo)
: undefined,
drillBy: { filters: drillByFilters, groupbyFieldName: 'columns' }, drillBy: { filters: drillByFilters, groupbyFieldName: 'columns' },
}); });
} }

View File

@ -70,6 +70,8 @@ export default function EchartsTimeseries({
setExtraControlHeight(updatedHeight); setExtraControlHeight(updatedHeight);
}, [formData.showExtraControls]); }, [formData.showExtraControls]);
const hasDimensions = ensureIsArray(groupby).length > 0;
const getModelInfo = (target: ViewRootGroup, globalModel: GlobalModel) => { const getModelInfo = (target: ViewRootGroup, globalModel: GlobalModel) => {
let el = target; let el = target;
let model: ComponentModel | null = null; let model: ComponentModel | null = null;
@ -139,6 +141,9 @@ export default function EchartsTimeseries({
const eventHandlers: EventHandlers = { const eventHandlers: EventHandlers = {
click: props => { click: props => {
if (!hasDimensions) {
return;
}
if (clickTimer.current) { if (clickTimer.current) {
clearTimeout(clickTimer.current); clearTimeout(clickTimer.current);
} }
@ -215,8 +220,10 @@ export default function EchartsTimeseries({
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, { onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillToDetailFilters, drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(seriesName),
drillBy: { filters: drillByFilters, groupbyFieldName: 'groupby' }, drillBy: { filters: drillByFilters, groupbyFieldName: 'groupby' },
crossFilter: hasDimensions
? getCrossFilterDataMask(seriesName)
: undefined,
}); });
} }
}, },

View File

@ -97,7 +97,7 @@ export default function EchartsTreemap({
const handleChange = useCallback( const handleChange = useCallback(
(data, treePathInfo) => { (data, treePathInfo) => {
if (!emitCrossFilters) { if (!emitCrossFilters || groupby.length === 0) {
return; return;
} }
@ -144,7 +144,10 @@ export default function EchartsTreemap({
}); });
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, { onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillToDetailFilters, drillToDetail: drillToDetailFilters,
crossFilter: getCrossFilterDataMask(data, treePathInfo), crossFilter:
groupby.length > 0
? getCrossFilterDataMask(data, treePathInfo)
: undefined,
drillBy: { filters: drillByFilters, groupbyFieldName: 'groupby' }, drillBy: { filters: drillByFilters, groupbyFieldName: 'groupby' },
}); });
} }

View File

@ -17,7 +17,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Behavior, ChartMetadata, ChartPlugin, t } from '@superset-ui/core'; import { ChartMetadata, ChartPlugin, t } from '@superset-ui/core';
import buildQuery from './buildQuery'; import buildQuery from './buildQuery';
import controlPanel from './controlPanel'; import controlPanel from './controlPanel';
import transformProps from './transformProps'; import transformProps from './transformProps';
@ -27,6 +27,7 @@ import example2 from './images/example2.png';
import example3 from './images/example3.png'; import example3 from './images/example3.png';
import { EchartsWaterfallChartProps, EchartsWaterfallFormData } from './types'; import { EchartsWaterfallChartProps, EchartsWaterfallFormData } from './types';
// TODO: Implement cross filtering
export default class EchartsWaterfallChartPlugin extends ChartPlugin< export default class EchartsWaterfallChartPlugin extends ChartPlugin<
EchartsWaterfallFormData, EchartsWaterfallFormData,
EchartsWaterfallChartProps EchartsWaterfallChartProps
@ -47,7 +48,6 @@ export default class EchartsWaterfallChartPlugin extends ChartPlugin<
controlPanel, controlPanel,
loadChart: () => import('./EchartsWaterfall'), loadChart: () => import('./EchartsWaterfall'),
metadata: new ChartMetadata({ metadata: new ChartMetadata({
behaviors: [Behavior.InteractiveChart],
credits: ['https://echarts.apache.org'], credits: ['https://echarts.apache.org'],
category: t('Evolution'), category: t('Evolution'),
description: t( description: t(

View File

@ -26,6 +26,7 @@ import {
getNumberFormatter, getNumberFormatter,
getTimeFormatter, getTimeFormatter,
} from '@superset-ui/core'; } from '@superset-ui/core';
import { noop } from 'lodash';
import { import {
BaseTransformedProps, BaseTransformedProps,
@ -137,7 +138,8 @@ export const contextMenuEventHandler =
} }
onContextMenu(pointerEvent.clientX, pointerEvent.clientY, { onContextMenu(pointerEvent.clientX, pointerEvent.clientY, {
drillToDetail: drillFilters, drillToDetail: drillFilters,
crossFilter: getCrossFilterDataMask(e.name), crossFilter:
groupby.length > 0 ? getCrossFilterDataMask(e.name) : undefined,
drillBy: { filters: drillFilters, groupbyFieldName: 'groupby' }, drillBy: { filters: drillFilters, groupbyFieldName: 'groupby' },
}); });
} }
@ -157,11 +159,14 @@ export const allEventHandlers = (
formData, formData,
} = transformedProps; } = transformedProps;
const eventHandlers: EventHandlers = { const eventHandlers: EventHandlers = {
click: clickEventHandler( click:
getCrossFilterDataMask(selectedValues, groupby, labelMap), groupby.length > 0
setDataMask, ? clickEventHandler(
emitCrossFilters, getCrossFilterDataMask(selectedValues, groupby, labelMap),
), setDataMask,
emitCrossFilters,
)
: noop,
contextmenu: contextMenuEventHandler( contextmenu: contextMenuEventHandler(
groupby, groupby,
onContextMenu, onContextMenu,