Compare commits

...

9 Commits

Author SHA1 Message Date
yousoph
ea3ba12ebf Update transformProps.ts 2025-07-17 14:45:06 -07:00
yousoph
268d8e8fee update test 2025-07-17 13:53:09 -07:00
yousoph
ae71b837ff update tests 2025-07-17 13:48:59 -07:00
yousoph
12dd4a712e Update controlPanel.tsx 2025-07-17 10:22:32 -07:00
yousoph
04714b83c2 Update controlPanel.tsx 2025-07-17 00:07:57 -07:00
yousoph
6070e84944 Update transformProps.ts 2025-07-17 00:07:09 -07:00
yousoph
1cd939e612 Update transformProps.ts 2025-07-16 23:52:00 -07:00
yousoph
e71a19a19e Update types.ts 2025-07-16 23:39:10 -07:00
yousoph
e50e378d8b Update controlPanel.tsx 2025-07-16 23:31:23 -07:00
4 changed files with 155 additions and 56 deletions

View File

@@ -359,6 +359,22 @@ const config: ControlPanelConfig = {
[xAxisLabelRotation], [xAxisLabelRotation],
[xAxisLabelInterval], [xAxisLabelInterval],
...richTooltipSection, ...richTooltipSection,
[
{
name: 'show_query_identifiers',
config: {
type: 'CheckboxControl',
label: t('Show query identifiers'),
description: t(
'Adds Query A and Query B identifiers to help differentiate series',
),
default: false,
renderTrigger: true,
visibility: ({ controls }) =>
Boolean(controls?.rich_tooltip?.value),
},
},
],
// eslint-disable-next-line react/jsx-key // eslint-disable-next-line react/jsx-key
[<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>], [<ControlSubSectionHeader>{t('Y Axis')}</ControlSubSectionHeader>],
[ [

View File

@@ -212,6 +212,7 @@ export default function transformProps(
sortSeriesAscendingB, sortSeriesAscendingB,
timeGrainSqla, timeGrainSqla,
percentageThreshold, percentageThreshold,
show_query_identifiers = false,
metrics = [], metrics = [],
metricsB = [], metricsB = [],
}: EchartsMixedTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData }; }: EchartsMixedTimeseriesFormData = { ...DEFAULT_FORM_DATA, ...formData };
@@ -395,10 +396,19 @@ export default function transformProps(
const seriesName = inverted[entryName] || entryName; const seriesName = inverted[entryName] || entryName;
const colorScaleKey = getOriginalSeries(seriesName, array); const colorScaleKey = getOriginalSeries(seriesName, array);
let displayName = `${entryName} (Query A)`; let displayName: string;
if (groupby.length > 0) { if (groupby.length > 0) {
displayName = `${MetricDisplayNameA} (Query A), ${entryName}`; // When we have groupby, format as "metric, dimension"
const metricPart = show_query_identifiers
? `${MetricDisplayNameA} (Query A)`
: MetricDisplayNameA;
displayName = `${metricPart}, ${entryName}`;
} else {
// When no groupby, format as just the entry name with optional query identifier
displayName = show_query_identifiers
? `${entryName} (Query A)`
: entryName;
} }
const seriesFormatter = getFormatter( const seriesFormatter = getFormatter(
@@ -453,10 +463,19 @@ export default function transformProps(
const seriesName = `${seriesEntry} (1)`; const seriesName = `${seriesEntry} (1)`;
const colorScaleKey = getOriginalSeries(seriesEntry, array); const colorScaleKey = getOriginalSeries(seriesEntry, array);
let displayName = `${entryName} (Query B)`; let displayName: string;
if (groupbyB.length > 0) { if (groupbyB.length > 0) {
displayName = `${MetricDisplayNameB} (Query B), ${entryName}`; // When we have groupby, format as "metric, dimension"
const metricPart = show_query_identifiers
? `${MetricDisplayNameB} (Query B)`
: MetricDisplayNameB;
displayName = `${metricPart}, ${entryName}`;
} else {
// When no groupby, format as just the entry name with optional query identifier
displayName = show_query_identifiers
? `${entryName} (Query B)`
: entryName;
} }
const seriesFormatter = getFormatter( const seriesFormatter = getFormatter(

View File

@@ -60,6 +60,7 @@ export type EchartsMixedTimeseriesFormData = QueryFormData & {
tooltipTimeFormat?: string; tooltipTimeFormat?: string;
zoomable: boolean; zoomable: boolean;
richTooltip: boolean; richTooltip: boolean;
show_query_identifiers?: boolean;
xAxisLabelRotation: number; xAxisLabelRotation: number;
xAxisLabelInterval?: number | string; xAxisLabelInterval?: number | string;
colorScheme?: string; colorScheme?: string;
@@ -133,6 +134,7 @@ export const DEFAULT_FORM_DATA: EchartsMixedTimeseriesFormData = {
groupbyB: [], groupbyB: [],
zoomable: TIMESERIES_DEFAULTS.zoomable, zoomable: TIMESERIES_DEFAULTS.zoomable,
richTooltip: TIMESERIES_DEFAULTS.richTooltip, richTooltip: TIMESERIES_DEFAULTS.richTooltip,
show_query_identifiers: false,
xAxisLabelRotation: TIMESERIES_DEFAULTS.xAxisLabelRotation, xAxisLabelRotation: TIMESERIES_DEFAULTS.xAxisLabelRotation,
xAxisLabelInterval: TIMESERIES_DEFAULTS.xAxisLabelInterval, xAxisLabelInterval: TIMESERIES_DEFAULTS.xAxisLabelInterval,
...DEFAULT_TITLE_FORM_DATA, ...DEFAULT_TITLE_FORM_DATA,

View File

@@ -28,7 +28,7 @@ import {
EchartsMixedTimeseriesProps, EchartsMixedTimeseriesProps,
} from '../../src/MixedTimeseries/types'; } from '../../src/MixedTimeseries/types';
const formData: EchartsMixedTimeseriesFormData = { const baseFormData: EchartsMixedTimeseriesFormData = {
annotationLayers: [], annotationLayers: [],
area: false, area: false,
areaB: false, areaB: false,
@@ -81,6 +81,7 @@ const formData: EchartsMixedTimeseriesFormData = {
forecastPeriods: [], forecastPeriods: [],
forecastInterval: 0, forecastInterval: 0,
forecastSeasonalityDaily: 0, forecastSeasonalityDaily: 0,
show_query_identifiers: false,
}; };
const queriesData = [ const queriesData = [
@@ -108,57 +109,118 @@ const queriesData = [
}, },
]; ];
const chartPropsConfig = { describe('MixedTimeseries transformProps', () => {
formData, it('should transform chart props for viz with query identifiers disabled', () => {
width: 800, const formData = { ...baseFormData, show_query_identifiers: false };
height: 600, const chartPropsConfig = {
queriesData, formData,
theme: supersetTheme, width: 800,
}; height: 600,
queriesData,
theme: supersetTheme,
};
const chartProps = new ChartProps({ ...chartPropsConfig, formData });
const transformed = transformProps(
chartProps as EchartsMixedTimeseriesProps,
);
it('should transform chart props for viz', () => { expect(transformed).toEqual(
const chartProps = new ChartProps(chartPropsConfig); expect.objectContaining({
const transformed = transformProps(chartProps as EchartsMixedTimeseriesProps); echartOptions: expect.objectContaining({
series: expect.arrayContaining([
expect(transformed).toEqual( expect.objectContaining({
expect.objectContaining({ data: [
echartOptions: expect.objectContaining({ [599616000000, 1],
series: expect.arrayContaining([ [599916000000, 3],
expect.objectContaining({ ],
data: [ id: 'sum__num, boy',
[599616000000, 1], stack: 'obs\na',
[599916000000, 3], }),
], expect.objectContaining({
id: 'sum__num (Query A), boy', data: [
stack: 'obs\na', [599616000000, 2],
}), [599916000000, 4],
expect.objectContaining({ ],
data: [ id: 'sum__num, girl',
[599616000000, 2], stack: 'obs\na',
[599916000000, 4], }),
], // Query B — Bar series
id: 'sum__num (Query A), girl', expect.objectContaining({
stack: 'obs\na', data: [
}), [599616000000, 1],
// Query B — Bar series [599916000000, 3],
expect.objectContaining({ ],
data: [ id: 'sum__num, boy',
[599616000000, 1], stack: 'obs\nb',
[599916000000, 3], }),
], expect.objectContaining({
id: 'sum__num (Query B), boy', data: [
stack: 'obs\nb', [599616000000, 2],
}), [599916000000, 4],
expect.objectContaining({ ],
data: [ id: 'sum__num, girl',
[599616000000, 2], stack: 'obs\nb',
[599916000000, 4], }),
], ]),
id: 'sum__num (Query B), girl', }),
stack: 'obs\nb',
}),
]),
}), }),
}), );
); });
it('should transform chart props for viz with query identifiers enabled', () => {
const formData = { ...baseFormData, show_query_identifiers: true };
const chartPropsConfig = {
formData,
width: 800,
height: 600,
queriesData,
theme: supersetTheme,
};
const chartProps = new ChartProps({ ...chartPropsConfig, formData });
const transformed = transformProps(
chartProps as EchartsMixedTimeseriesProps,
);
expect(transformed).toEqual(
expect.objectContaining({
echartOptions: expect.objectContaining({
series: expect.arrayContaining([
expect.objectContaining({
data: [
[599616000000, 1],
[599916000000, 3],
],
id: 'sum__num (Query A), boy',
stack: 'obs\na',
}),
expect.objectContaining({
data: [
[599616000000, 2],
[599916000000, 4],
],
id: 'sum__num (Query A), girl',
stack: 'obs\na',
}),
// Query B — Bar series
expect.objectContaining({
data: [
[599616000000, 1],
[599916000000, 3],
],
id: 'sum__num (Query B), boy',
stack: 'obs\nb',
}),
expect.objectContaining({
data: [
[599616000000, 2],
[599916000000, 4],
],
id: 'sum__num (Query B), girl',
stack: 'obs\nb',
}),
]),
}),
}),
);
});
}); });