newbie2210
newbie2210

Reputation: 243

How to make custom tooltip in SfCartesianChart?

I have tooltip that looks like this:enter image description here

But I want to customize it to this:

enter image description here

How can I do this?

This is my code:

void initState() {
    _tooltipBehavior = TooltipBehavior(
      enable: true,
      color: Colors.transparent,
      header: "",
      duration: 0,
      format: "point.y%\npoint.x",
      canShowMarker: false,
      textAlignment: ChartAlignment.center
      // builder: (data, point, series, pointIndex, seriesIndex) {
      //   return Container(
      //     child: Text("data: point.y"),
      //   );
      // },
    );
    super.initState();
  }

SfCartesianChart(
  plotAreaBorderWidth: 0, // X top line
  plotAreaBorderColor: Colors.white24,
  tooltipBehavior: _tooltipBehavior,
  primaryXAxis: DateTimeAxis(
    majorTickLines: const MajorTickLines(width: 0), // Little sticks below X line
    majorGridLines: const MajorGridLines(
      width: 0.5,
      color: Colors.transparent,
    ),
    axisLine: const AxisLine( // X bottom line
      color: Colors.white24,
      dashArray: <double>[5,5]
    ),
  ),
  primaryYAxis: NumericAxis(
    majorGridLines: const MajorGridLines(width: 1, color: Colors.white24, dashArray: <double>[5, 5]),
    majorTickLines: const MajorTickLines(width: 0), // Little sticks on left side
    axisLine: const AxisLine(
      color: Colors.transparent, // Y left line
      dashArray: <double>[5,5]
    ),
    minimum: 0,
    maximum: 100,
  ),
)

And I met a bug with displation of point.y, When I move a mouse below blue line then it shows me => point.y%. But when I move only on blue line then everything works fine, it shows me 54$. How can I fix that?

Upvotes: 2

Views: 2834

Answers (2)

yuva
yuva

Reputation: 551

#Query 1: How can I do this?

The requirement can be achieved with the help of TrackballBehavior in the chart and using its builder property and show the customizable widget. The TrackballBehavior supports the marker for the currently activated data point and has a line support too. So, you can show the marker and line for the presently activated point with the help of markerSettings property and place the custom widget with the help of the tooltipAlignment of TrackballBehavior. We have shared the code snippet below for your reference.

enter image description here

Code snippet:

import 'dart:math';
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late List<ChartData> chartData;

  @override
  void initState() {
    chartData = [
      ChartData(DateTime(2022, 12, 01, 09, 12), 50),
      ChartData(DateTime(2022, 12, 01, 09, 13), 45),
      ChartData(DateTime(2022, 12, 01, 09, 14), 54),
      ChartData(DateTime(2022, 12, 01, 09, 15), 51),
      ChartData(DateTime(2022, 12, 01, 09, 16), 53),
      ChartData(DateTime(2022, 12, 01, 09, 17), 49),
      ChartData(DateTime(2022, 12, 01, 09, 18), 54),
      ChartData(DateTime(2022, 12, 01, 09, 19), 45),
      ChartData(DateTime(2022, 12, 01, 09, 20), 30),
      ChartData(DateTime(2022, 12, 01, 09, 21), 48),
      ChartData(DateTime(2022, 12, 01, 09, 22), 65),
      ChartData(DateTime(2022, 12, 01, 09, 23), 63),
      ChartData(DateTime(2022, 12, 01, 09, 24), 71),
      ChartData(DateTime(2022, 12, 01, 09, 25), 48),
      ChartData(DateTime(2022, 12, 01, 09, 26), 51),
      ChartData(DateTime(2022, 12, 01, 09, 27), 49),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SfCartesianChart(
        trackballBehavior: TrackballBehavior(
            enable: true,
            markerSettings: const TrackballMarkerSettings(
                height: 10,
                width: 10,
                markerVisibility: TrackballVisibilityMode.visible,
                borderColor: Colors.black,
                borderWidth: 4,
                color: Colors.blue),
            activationMode: ActivationMode.singleTap,
            builder: (context, trackballDetails) {
              return SizedBox(
                height: 200,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      "${trackballDetails.groupingModeInfo!.points[0].y}%",
                      textAlign: TextAlign.left,
                      style: const TextStyle(color: Colors.white, fontSize: 20),
                    ),
                    const Padding(padding: EdgeInsets.only(top: 5)),
                    Text(
                      DateFormat('hh:mm').format(
                          trackballDetails.groupingModeInfo!.points[0].x),
                      textAlign: TextAlign.left,
                      style: const TextStyle(
                        color: Colors.white,
                        fontSize: 10,
                      ),
                    ),
                  ],
                ),
              );
            },
            tooltipDisplayMode: TrackballDisplayMode.groupAllPoints,
            tooltipAlignment: ChartAlignment.near),
        backgroundColor: Colors.black,
        plotAreaBorderWidth: 0, // X top line
        plotAreaBorderColor: Colors.white24,
        primaryXAxis: DateTimeAxis(
          majorTickLines:
              const MajorTickLines(width: 0), // Little sticks below X line
          majorGridLines: const MajorGridLines(
            width: 0.5,
            color: Colors.transparent,
          ),
          axisLine: const AxisLine(
              // X bottom line
              color: Colors.white24,
              dashArray: <double>[5, 5]),
        ),
        primaryYAxis: NumericAxis(
          interval: 50,
          majorGridLines: const MajorGridLines(
              width: 1, color: Colors.white24, dashArray: <double>[5, 5]),
          majorTickLines:
              const MajorTickLines(width: 0), // Little sticks on left side
          axisLine: const AxisLine(color: Colors.transparent, // Y left line
              dashArray: <double>[5, 5]),
          minimum: 0,
          maximum: 100,
        ),
        series: <ChartSeries<ChartData, DateTime>>[
          AreaSeries(
              borderColor: Colors.blue,
              borderWidth: 3,
              gradient: LinearGradient(colors: [
                Colors.blue.withOpacity(0.4),
                Colors.blue.withOpacity(0.2),
                Colors.blue.withOpacity(0.1)
              ], stops: const [
                0.1,
                0.3,
                0.6
              ], begin: Alignment.topCenter, end: Alignment.bottomCenter),
              dataSource: chartData,
              xValueMapper: (ChartData data, _) => data.x,
              yValueMapper: (ChartData data, _) => data.y)
        ],
      ),
    );
  }
}

class ChartData {
  final DateTime x;
  final num y;

  ChartData(this.x, this.y);
}

#Query 2 : I met a bug with displation of point.y, When I move a mouse below blue line then it shows me => point.y%.

Based on the provided code snippet, you have returned the Text widget with the string value point.y inside a text widget, that is why it shows the point.y text. Otherwise, it won't show the point.y value in the tooltip, we have also ensured this and no issue gets reproduced.

Upvotes: 3

Axel
Axel

Reputation: 402

You can follow this tutorial by the devs to understand how to customize the chart tooltip:

https://help.syncfusion.com/flutter/cartesian-charts/tooltip

You basically need to use the builder method of TooltipBehavior.

Upvotes: 0

Related Questions