imaNNeo / fl_chart

FL Chart is a highly customizable Flutter chart library that supports Line Chart, Bar Chart, Pie Chart, Scatter Chart, and Radar Chart.
https://flchart.dev
MIT License
6.77k stars 1.74k forks source link

Line Chart tooltip on only certain lines #1620

Closed davidfrankl closed 4 months ago

davidfrankl commented 6 months ago

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 https://github.com/imaNNeo/fl_chart/issues/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.

https://github.com/imaNNeo/fl_chart/assets/3237960/bd09d863-ec7e-42d9-b15b-ccbe6d72dcba

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 commented 4 months ago

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:

https://github.com/imaNNeo/fl_chart/assets/7009300/c9eded61-712f-430a-8880-c422ba7efb15

davidfrankl commented 4 months ago

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 commented 4 months ago

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

davidfrankl commented 4 months ago

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 commented 4 months ago

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 commented 4 months ago

Great, thank you!

On Wed, May 8, 2024 at 9:11 PM Iman Khoshabi @.***> wrote:

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 https://github.com/imaNNeo/fl_chart/blob/main/example/lib/presentation/samples/line/line_chart_sample5.dart, we have a custom implementation that might help.

— Reply to this email directly, view it on GitHub https://github.com/imaNNeo/fl_chart/issues/1620#issuecomment-2101746468, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAYWQSAVJGFHLJ5VXZDRGF3ZBLELZAVCNFSM6AAAAABFNLSFGKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMBRG42DMNBWHA . You are receiving this because you authored the thread.Message ID: @.***>