apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
62.91k stars 13.91k forks source link

Time-series Line Chart Display unnecessary total #28832

Open inbreaks opened 5 months ago

inbreaks commented 5 months ago

Screenshot

Time-series Line Chart CONTRIBUTION MODE: None

image

Description

In this case, the next day's Retention rate (horizontal axis) for each channel is displayed, and the percentages on the right and total on the bottom are redundant.

Design input

This logical problem was not caused in some previous versions

image
dosubot[bot] commented 5 months ago

Hey @inbreaks! I'm Dosu, a bot here to help you with bug fixes, questions, and becoming a contributor. How can I assist you today?

To resolve the issue of redundant percentages and totals being displayed on the time-series line chart, you can adjust the control panel configuration and modify the tooltip formatting logic in Apache Superset.

  1. Adjust Control Panel Configuration: Modify the controlPanelSections configuration to ensure that unnecessary elements like redundant percentages and totals are not included. Here is an example configuration:

    const config: ControlPanelConfig = {
     controlPanelSections: [
       sections.legacyTimeseriesTime,
       timeSeriesSection[0],
       {
         label: t('Chart Options'),
         expanded: true,
         controlSetRows: [
           ['color_scheme'],
           [showBrush],
           [
             {
               name: 'send_time_range',
               config: {
                 type: 'CheckboxControl',
                 label: t('Propagate'),
                 renderTrigger: true,
                 default: false,
                 description: t('Send range filter events to other charts'),
               },
             },
           ],
           [showLegend],
           [richTooltip],
           [showMarkers],
           [lineInterpolation],
         ],
       },
       {
         label: t('X Axis'),
         expanded: true,
         controlSetRows: [
           [xAxisLabel],
           [bottomMargin],
           [xTicksLayout],
           [xAxisFormat],
           [xAxisShowMinmax, null],
         ],
       },
       {
         label: t('Y Axis'),
         expanded: true,
         controlSetRows: [
           [yAxisLabel],
           [leftMargin],
           [yAxisShowMinmax],
           [yLogScale],
           ['y_axis_format'],
           [yAxisBounds],
         ],
       },
       timeSeriesSection[1],
       sections.annotations,
     ],
     controlOverrides: {
       row_limit: {
         default: 50000,
       },
     },
     formDataOverrides: formData => ({
       ...formData,
       metrics: getStandardizedControls().popAllMetrics(),
       groupby: getStandardizedControls().popAllColumns(),
     }),
    };
    
    export default config;
  2. Modify Tooltip Formatting Logic: Adjust the transformProps function in superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts to ensure that the tooltip does not display redundant percentages and totals. Here is an example adjustment:

    const tooltipFormatter =
       xAxisDataType === GenericDataType.Temporal
         ? getTooltipTimeFormatter(tooltipTimeFormat)
         : String;
    
    const echartOptions: EChartsCoreOption = {
     // ... other options
     tooltip: {
       ...getDefaultTooltip(refs),
       show: !inContextMenu,
       trigger: richTooltip ? 'axis' : 'item',
       formatter: (params: any) => {
         const [xIndex, yIndex] = isHorizontal ? [1, 0] : [0, 1];
         const xValue: number = richTooltip
           ? params[0].value[xIndex]
           : params.value[xIndex];
         const forecastValue: any[] = richTooltip ? params : [params];
    
         if (richTooltip && tooltipSortByMetric) {
           forecastValue.sort((a, b) => b.data[yIndex] - a.data[yIndex]);
         }
    
         const forecastValues: Record<string, ForecastValue> =
           extractForecastValuesFromTooltipParams(forecastValue, isHorizontal);
    
         const isForecast = Object.values(forecastValues).some(
           value =>
             value.forecastTrend || value.forecastLower || value.forecastUpper,
         );
    
         const formatter = forcePercentFormatter
           ? percentFormatter
           : getCustomFormatter(customFormatters, metrics) ?? defaultFormatter;
    
         const rows: string[][] = [];
         const total = Object.values(forecastValues).reduce(
           (acc, value) =>
             value.observation !== undefined ? acc + value.observation : acc,
           0,
         );
         const showTotal = Boolean(isMultiSeries) && richTooltip && !isForecast;
         const showPercentage = showTotal && !forcePercentFormatter;
         const keys = Object.keys(forecastValues);
         keys.forEach(key => {
           const value = forecastValues[key];
           if (value.observation === 0 && stack) {
             return;
           }
           const row = formatForecastTooltipSeries({
             ...value,
             seriesName: key,
             formatter,
           });
           if (showPercentage && value.observation !== undefined) {
             row.push(percentFormatter.format(value.observation / (total || 1)));
           }
           rows.push(row);
         });
         if (stack) {
           keys.reverse();
           rows.reverse();
         }
         if (showTotal) {
           const totalRow = ['Total', formatter.format(total)];
           if (showPercentage) {
             totalRow.push(percentFormatter.format(1));
           }
           rows.push(totalRow);
         }
         return tooltipHtml(
           rows,
           tooltipFormatter(xValue),
           keys.findIndex(key => key === focusedSeries),
         );
       },
     },
     // ... other options
    };

By making these adjustments, you can ensure that redundant percentages and totals are not displayed on your time-series line chart [1][2][3].

To continue talking to Dosu, mention @dosu.

rusackas commented 5 months ago

CC @michael-s-molina who has been looking at these tooltip displays. Maybe they can be rendered conditionally (e.g. skip if percentage format). I also can't help but wonder if it indicates a problem that you have 171.5% of something

michael-s-molina commented 5 months ago

Hi @inbreaks. I'm not sure if I fully understand the problem. Given that this new tooltip was not officially released yet, I'm assuming you are using master. I just checked the latest master version and I'm not able to reproduce the problem. The percentages are shown when there's no contribution.

Screenshot 2024-06-04 at 08 58 11 Screenshot 2024-06-04 at 08 58 59

The only scenario I can think of that could generate your screenshot is if you formatted the Y-axis to always display as percentage.

inbreaks commented 5 months ago

Hi @michael-s-molina the background of this use case is to calculate the next-day retention rate of new users from each traffic channel, so the Y-axis will always show the percentage, but the total is not 100%, for example

traffic sources next-day retention
Google 20%
Facebook 30%
TikTok 35%

Therefore, calculating total and percentage is redundant

michael-s-molina commented 5 months ago

Hi @inbreaks. To support this use case, we would need some form of control to precisely configure what parts of the tooltip you want to display. We don't have that feature currently. Right now, you might want to disable the Rich Tooltip option until we provide such feature.

inbreaks commented 5 months ago

Hi @inbreaks. To support this use case, we would need some form of control to precisely configure what parts of the tooltip you want to display. We don't have that feature currently. Right now, you might want to disable the Rich Tooltip option until we provide such feature.

Thanks @michael-s-molina , how do I turn off Rich Tooltip? Is it possible to configure DEFAULT_FEATURE_FLAGS to do this?

michael-s-molina commented 5 months ago

Thanks @michael-s-molina , how do I turn off Rich Tooltip? Is it possible to configure DEFAULT_FEATURE_FLAGS to do this?

Screenshot 2024-06-06 at 09 51 16
inbreaks commented 17 hours ago

@michael-s-molina

I noticed that the latest release 4.1.1 has updated this feature compared to 4.0.2. I had to disable the Rich Tooltip option.