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

Line Chart tooltip on only certain lines #1620

Closed
davidfrankl opened this issue Mar 28, 2024 · 6 comments
Closed

Line Chart tooltip on only certain lines #1620

davidfrankl opened this issue Mar 28, 2024 · 6 comments
Labels
Line Chart question Further information is requested

Comments

@davidfrankl
Copy link

davidfrankl commented Mar 28, 2024

Is your feature request related to a problem? Please describe.

I have a line chart with multiple lines. I only want tooltips for a certain subset of the lines. I am aware of #1092, which shows how to hide the value for certain lines. However, there is still a problem. With that solution, the tooltip is displayed above the top-most line, regardless of whether that line has a tooltip.

Consider the following example:

final lineBarsData = [
  LineChartBarData(
    spots: [
      const FlSpot(0, 10),
      const FlSpot(100, 10),
    ],
  ),
  LineChartBarData(
    spots: [
      const FlSpot(0, 90),
      const FlSpot(100, 90),
    ],
  ),
];

return LineChart(
  LineChartData(
    minY: 0,
    maxY: 100,
    lineBarsData: lineBarsData,
    lineTouchData: LineTouchData(
      getTouchedSpotIndicator:
          (LineChartBarData barData, List<int> spotIndexes) {
        return spotIndexes.map((spotIndex) {
          if (barData == lineBarsData[1]) {
            return null;
          }

          return const TouchedSpotIndicatorData(
            FlLine(color: Colors.black, strokeWidth: 4.0),
            FlDotData(),
          );
        }).toList();
      },
      touchTooltipData: LineTouchTooltipData(
        getTooltipItems: (touchedSpots) {
          return touchedSpots.mapIndexed((index, spot) {
            if (spot.barIndex == 1) {
              return null;
            }

            return LineTooltipItem(
              spot.y.toString(),
              const TextStyle(color: Colors.black),
              textAlign: TextAlign.left,
            );
          }).toList();
        },
      ),
    ),
  ),
);

Notice that the tooltip is displayed at the very top of the chart, but it pertains to the line at the very bottom.

Screen.Recording.2024-03-28.at.3.27.06.PM.mov

Describe the solution you'd like

Ideally in my example, the tooltip box should be adjacent to the bottom line, or say, adjacent to the top-most of the lines for which tooltip is non-null.

More generally, I would like an option to avoid showing tooltips for a certain line altogether. This option could be available on the LineChartBarData itself, for example bool showTooltips. If false, do not show any tooltips for this line, and do not consider this line when determining where to place the tooltip box.

Describe alternatives you've considered

I am not aware of any other way to control where the tooltip box is positioned.

Additional context
Add any other context or screenshots about the feature request here.

@imaNNeo
Copy link
Owner

imaNNeo commented May 9, 2024

The point is that we have a callback inside LineTouchData called distanceCalculator,
The default implementation calculates the only x axis distance. As the result, it doesn't matter how much space do we have in the vertical axis:

// Default distanceCalculator only considers distance on x axis
double _xDistance(Offset touchPoint, Offset spotPixelCoordinates) {
  return (touchPoint.dx - spotPixelCoordinates.dx).abs();
}

But you can override it to consider both x and y axes.
Take a look at this code:

distanceCalculator:
    (Offset touchPoint, Offset spotPixelCoordinates) =>
        (touchPoint - spotPixelCoordinates).distance,

I just updated the LineChartSample6. Please take a look:

Screen.Recording.2024-05-09.at.02.20.22.mov

@davidfrankl
Copy link
Author

Hey @imaNNeo thanks for the response. I am aware of the distanceCalculator, but I don't think it satisfies my use case.

In my use case, there are two or more lines which may be arbitrarily close to or far from each other. It could be that for a given X value, the two lines even share the same Y value.

Furthermore, I want the tooltip to be displayed for line 1 regardless of how far in the Y direction the mouse is from line 1, and I dont want the tooltip for line 2 regardless of how close in the Y direction the mouse is.

The problem arises when Line 2 is far from Line 1 in the Y dimension. The tooltip is displayed above Line 2, instead of above Line 1 as desired.

@imaNNeo
Copy link
Owner

imaNNeo commented May 9, 2024

For this use-case, you can disable the builtInTouches and implement your own logic. have you tried that?

@davidfrankl
Copy link
Author

I haven't. I actually assumed that if you set handleBuiltInTouches: false, then the interactive tooltips would be disabled altogether. It sounds like that's not the case.

If I get some time to work on this, I'll give it a shot and report back.

Thanks

@imaNNeo
Copy link
Owner

imaNNeo commented May 9, 2024

If you set handleBuiltInTouches: false, it disables the default behavior, so it's ready to implement your own logic.
It's simple, you override the touchCallback and you do whatever you want.

In line chart sample 5, we have a custom implementation that might help.

@davidfrankl
Copy link
Author

davidfrankl commented May 9, 2024 via email

OlehSv pushed a commit to Oleh-Sv/fl_chart that referenced this issue May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Line Chart question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants