Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time-series Line Chart Display unnecessary total #28832

Open
inbreaks opened this issue Jun 3, 2024 · 7 comments
Open

Time-series Line Chart Display unnecessary total #28832

inbreaks opened this issue Jun 3, 2024 · 7 comments
Assignees
Labels
viz:charts:timeseries Related to Timeseries

Comments

@inbreaks
Copy link

inbreaks commented Jun 3, 2024

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 dosubot bot added the viz:charts:timeseries Related to Timeseries label Jun 3, 2024
Copy link

dosubot bot commented Jun 3, 2024

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
Copy link
Member

rusackas commented Jun 3, 2024

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 michael-s-molina self-assigned this Jun 3, 2024
@michael-s-molina
Copy link
Member

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
Copy link
Author

inbreaks commented Jun 6, 2024

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
Copy link
Member

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
Copy link
Author

inbreaks commented Jun 6, 2024

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
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
viz:charts:timeseries Related to Timeseries
Projects
None yet
Development

No branches or pull requests

3 participants