Cross filter is not working on the bar chart which has no dimension #29592
Replies: 2 comments
-
Hey @doheeyoon! I'm here to help you with any bugs, questions, or contributions you might have. Let's get to the bottom of this together. No, it is not the intended behavior that the CrossFilter function does not work on a bar chart without dimensions. To enable cross-filtering for such bar charts on the dashboard, ensure that the following conditions are met:
Additionally, you can use the import React, { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { css, isDefined, NativeFilterScope, styled, t, useTheme } from '@superset-ui/core';
import { Select } from 'src/components';
import { noOp } from 'src/utils/common';
import ScopingTree from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/ScopingTree';
import { ChartConfiguration, DashboardLayout, isCrossFilterScopeGlobal, RootState } from 'src/dashboard/types';
import { CHART_TYPE } from 'src/dashboard/util/componentTypes';
import { SelectOptionsType } from 'src/components/Select/types';
import Icons from 'src/components/Icons';
import { Tooltip } from 'src/components/Tooltip';
import Alert from 'src/components/Alert';
import { NEW_CHART_SCOPING_ID } from './constants';
const InfoText = styled.div`
${({ theme }) => css`
font-size: ${theme.typography.sizes.s}px;
color: ${theme.colors.grayscale.base};
margin-bottom: ${theme.gridUnit * 7}px;
`}
`;
const ChartSelect = ({ value, onSelectChange, chartConfigs }) => {
const theme = useTheme();
const layout = useSelector<RootState, DashboardLayout>(state => state.dashboardLayout.present);
const options: SelectOptionsType = useMemo(() => {
const chartLayoutItems = Object.values(layout).filter(item => item.type === CHART_TYPE);
return Object.values(chartConfigs)
.filter(chartConfig => isCrossFilterScopeGlobal(chartConfig.crossFilters.scope) || (chartConfig.id === value && value !== NEW_CHART_SCOPING_ID))
.map(chartConfig => {
const chartLayoutItem = chartLayoutItems.find(item => item.meta.chartId === Number(chartConfig.id));
return {
value: Number(chartConfig.id),
label: chartLayoutItem?.meta.sliceNameOverride || chartLayoutItem?.meta.sliceName || '',
};
});
}, [chartConfigs, layout, value]);
return (
<div css={css`margin-bottom: ${theme.gridUnit * 6}px;`}>
<div css={css`display: flex; align-items: center; margin-bottom: ${theme.gridUnit}px;`}>
<InfoText css={css`color: ${theme.colors.grayscale.dark1}; margin-right: ${theme.gridUnit}px; margin-bottom: 0;`}>{`${t('Chart')} *`}</InfoText>
<Tooltip title={t('Tooltip')} placement="top">
<Icons.InfoCircleOutlined iconSize="xs" iconColor={theme.colors.grayscale.base} css={css`& > span { line-height: 0; }`} />
</Tooltip>
</div>
<Select
data-test="select-chart"
ariaLabel={t('Select chart')}
options={options}
value={value && value === NEW_CHART_SCOPING_ID ? undefined : value}
onChange={value => onSelectChange(Number(value))}
/>
</div>
);
};
export const ScopingTreePanel = ({ onScopeUpdate, currentScope, chartId, onSelectChange, chartConfigs }) => {
const theme = useTheme();
const isCrossFiltersEnabled = useSelector<RootState, boolean>(({ dashboardInfo }) => dashboardInfo.crossFiltersEnabled);
return (
<div data-test="scoping-tree-panel" css={css`flex: 1;`}>
{!isCrossFiltersEnabled && (
<Alert
message={<span css={css`font-weight: ${theme.typography.weights.bold};`}>{t('Cross-filtering is not enabled in this dashboard')}</span>}
type="info"
closable={false}
css={css`margin-bottom: ${theme.gridUnit * 6}px;`}
/>
)}
{isDefined(chartId) && (
<ChartSelect value={chartId} onSelectChange={onSelectChange} chartConfigs={chartConfigs} />
)}
<InfoText>
{isDefined(chartId)
? t(`Select the charts to which you want to apply cross-filters when interacting with this chart. You can select "All charts" to apply filters to all charts that use the same dataset or contain the same column name in the dashboard.`)
: t(`Select the charts to which you want to apply cross-filters in this dashboard. Deselecting a chart will exclude it from being filtered when applying cross-filters from any chart on the dashboard. You can select "All charts" to apply cross-filters to all charts that use the same dataset or contain the same column name in the dashboard.`)}
</InfoText>
<ScopingTree
updateFormValues={onScopeUpdate}
initialScope={currentScope}
forceUpdate={noOp}
chartId={chartId}
title={t('All charts')}
/>
</div>
);
}; Ensure these conditions are met and use the import { cloneDeep } from 'lodash';
import {
Behavior,
FeatureFlag,
getChartMetadataRegistry,
isDefined,
isFeatureEnabled,
} from '@superset-ui/core';
import { getChartIdsInFilterScope } from './getChartIdsInFilterScope';
import {
ChartsState,
DashboardInfo,
DashboardLayout,
GLOBAL_SCOPE_POINTER,
isCrossFilterScopeGlobal,
} from '../types';
import { DEFAULT_CROSS_FILTER_SCOPING } from '../constants';
export const isCrossFiltersEnabled = (
metadataCrossFiltersEnabled: boolean | undefined,
): boolean =>
isFeatureEnabled(FeatureFlag.DashboardCrossFilters) &&
(metadataCrossFiltersEnabled === undefined || metadataCrossFiltersEnabled);
export const getCrossFiltersConfiguration = (
dashboardLayout: DashboardLayout,
metadata: Pick<
DashboardInfo['metadata'],
'chart_configuration' | 'global_chart_configuration'
>,
charts: ChartsState,
) => {
if (!isFeatureEnabled(FeatureFlag.DashboardCrossFilters)) {
return undefined;
}
const globalChartConfiguration = metadata.global_chart_configuration?.scope
? {
scope: metadata.global_chart_configuration.scope,
chartsInScope: getChartIdsInFilterScope(
metadata.global_chart_configuration.scope,
Object.values(charts).map(chart => chart.id),
dashboardLayout,
),
}
: {
scope: DEFAULT_CROSS_FILTER_SCOPING,
chartsInScope: Object.values(charts).map(chart => chart.id),
};
const chartConfiguration = {};
Object.values(dashboardLayout).forEach(layoutItem => {
const chartId = layoutItem.meta?.chartId;
if (!isDefined(chartId)) {
return;
}
const behaviors =
(
getChartMetadataRegistry().get(charts[chartId]?.form_data?.viz_type) ??
{}
)?.behaviors ?? [];
if (behaviors.includes(Behavior.InteractiveChart)) {
if (metadata.chart_configuration?.[chartId]) {
chartConfiguration[chartId] = cloneDeep(
metadata.chart_configuration[chartId],
);
}
if (!chartConfiguration[chartId]) {
chartConfiguration[chartId] = {
id: chartId,
crossFilters: {
scope: GLOBAL_SCOPE_POINTER,
},
};
}
chartConfiguration[chartId].crossFilters.chartsInScope =
isCrossFilterScopeGlobal(chartConfiguration[chartId].crossFilters.scope)
? globalChartConfiguration.chartsInScope.filter(
id => id !== Number(chartId),
)
: getChartIdsInFilterScope(
chartConfiguration[chartId].crossFilters.scope,
Object.values(charts).map(chart => chart.id),
dashboardLayout,
);
}
});
return { chartConfiguration, globalChartConfiguration };
}; |
Beta Was this translation helpful? Give feedback.
-
Hi! There is an issue comment on link: https://github.com/apache/superset/issues/25334#issuecomment-2239008373 @rusackas you can choose wich topic to close ( I think..) |
Beta Was this translation helpful? Give feedback.
-
CrossFilter function doesn't work on a bar chart with no dimensions. Interaction doesn't work on the dashboard when I click on the bar on the bar chart. I wonder if this is the intended feature. If it's something I'm not aware of, please let me know how can I cross-filter bar charts on the dashboard. (and surprisingly, cross filter is working on bar chart with dimension)
Beta Was this translation helpful? Give feedback.
All reactions