Trackball position

My current trackall look like this:

Image_5487_1692173619102

the problem is that It hides the specific candle I selected.

is there way to get trackball position like this:

Image_3265_1692173668960


3 Replies

HK Hariharasudhan Kanagaraj Syncfusion Team August 17, 2023 02:35 PM UTC

Hi Bar IIan,


We have prepared a sample rendering the Candle Series with the crosshair and trackball and here we have given the width of the custom tooltip and the trackball line as zero using the arrowWidth property and lineWidth property and added padding to the custom tooltip using the Padding widget to avoid hiding of the selected Candle Segment as shown in the snippet below.


class _MyHomePageState extends State<MyHomePage> {

  late List<ChartSampleData> _data;

  late TrackballBehavior _trackballBehavior;

  late CrosshairBehavior _crosshairBehavior;

  @override

  void initState() {

    _data = [

      ChartSampleData(x: 01, high: 20, low: 50, open: 35, close: 45),

      ChartSampleData(x: 02, high: 60, low: 30, open: 45, close: 55),

      ChartSampleData(x: 03, high: 20, low: 50, open: 35, close: 45),

      ChartSampleData(x: 04, high: 40, low: 10, open: 20, close: 30),

      ChartSampleData(x: 05, high: 30, low: 20, open: 25, close: 30),

      ChartSampleData(x: 06, high: 70, low: 40, open: 70, close: 40),

      ChartSampleData(x: 07, high: 90, low: 60, open: 80, close: 60),

      ChartSampleData(x: 08, high: 50, low: 20, open: 20, close: 30),

      ChartSampleData(x: 09, high: 100, low: 70, open: 80, close: 90),

      ChartSampleData(x: 10, high: 80, low: 50, open: 60, close: 70),

    ];

    TextStyle textStyle1 = const TextStyle(

      fontWeight: FontWeight.bold,

      fontSize: 14,

      color: Colors.red,

    );

    TextStyle textStyle2 = const TextStyle(

      color: Colors.red,

    );

    _trackballBehavior = TrackballBehavior(

      enable: true,

      lineWidth: 0,

      tooltipSettings: const InteractiveTooltip(

        arrowWidth: 0,

        arrowLength: 0,

      ),

      activationMode: ActivationMode.singleTap,

      tooltipDisplayMode: TrackballDisplayMode.floatAllPoints,

      builder: (context, trackballDetails) {

        DateTime now = DateTime.now();

        String date = DateFormat('MM/dd hh:mm').format(now);

        return Padding(

          padding: const EdgeInsets.only(left: 50, right: 50),

          child: Container(

            height: 140,

            width: 200,

            decoration: BoxDecoration(

              color: Colors.blue.shade100.withOpacity(0.5),

              border: Border.all(

                color: Colors.indigo,

              ),

            ),

            padding: const EdgeInsets.all(10),

            child: Column(

              mainAxisAlignment: MainAxisAlignment.center,

              mainAxisSize: MainAxisSize.min,

              children: [

                Row(

                  mainAxisAlignment: MainAxisAlignment.spaceBetween,

                  children: [

                    Text(

                      'Date/Time:',

                      style: textStyle1,

                    ),

                    Text(

                      date,

                      style: textStyle2,

                    ),

                  ],

                ),

                Row(

                  mainAxisAlignment: MainAxisAlignment.spaceBetween,

                  children: [

                    Text(

                      'Close:',

                      style: textStyle1,

                    ),

                    Text(

                      _data[trackballDetails.pointIndex!].close.toString(),

                      style: textStyle2,

                    ),

                  ],

                ),

                Row(

                  mainAxisAlignment: MainAxisAlignment.spaceBetween,

                  children: [

                    Text(

                      'Open:',

                      style: textStyle1,

                    ),

                    Text(

                      _data[trackballDetails.pointIndex!].open.toString(),

                      style: textStyle2,

                    ),

                  ],

                ),

                Row(

                  mainAxisAlignment: MainAxisAlignment.spaceBetween,

                  children: [

                    Text(

                      'High:',

                      style: textStyle1,

                    ),

                    Text(

                      _data[trackballDetails.pointIndex!].high.toString(),

                      style: textStyle2,

                    ),

                  ],

                ),

                Row(

                  mainAxisAlignment: MainAxisAlignment.spaceBetween,

                  children: [

                    Text(

                      'Low:',

                      style: textStyle1,

                    ),

                    Text(

                      _data[trackballDetails.pointIndex!].low.toString(),

                      style: textStyle2,

                    ),

                  ],

                ),

              ],

            ),

          ),

        );

      },

    );

    _crosshairBehavior = CrosshairBehavior(

      enable: true,

      activationMode: ActivationMode.singleTap,

      shouldAlwaysShow: true,

    );

    super.initState();

  }

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: SfCartesianChart(

        primaryXAxis: NumericAxis(),

        primaryYAxis: NumericAxis(),

        series: <CartesianSeries<ChartSampleData, num>>[

          CandleSeries(

            dataSource: _data,

            enableSolidCandles: true,

            xValueMapper: (ChartSampleData sales, int index) => sales.x,

            highValueMapper: (ChartSampleData sales, int index) => sales.high,

            lowValueMapper: (ChartSampleData sales, int index) => sales.low,

            openValueMapper: (ChartSampleData sales, int index) => sales.open,

            closeValueMapper: (ChartSampleData sales, int index) => sales.close,

          ),

        ],

        trackballBehavior: _trackballBehavior,

        crosshairBehavior: _crosshairBehavior,

      ),

    );

  }

}

 


Snapshot:


Also attached the sample below for your reference and you can modify the sample according to your needs. If you have further queries, please get back to us.


Regards,
Hari Hara Sudhan. K.


Attachment: _184086_aa20fc1a.zip


BI Bar Ilan August 20, 2023 07:33 AM UTC

The Trackball info still hides the selected point


Image_3626_1692516822866



HK Hariharasudhan Kanagaraj Syncfusion Team August 21, 2023 01:14 PM UTC

Hi Bar IIan,


You can render the trackball tooltip without hiding the selected candle segment using the below mentioned ways.


1) As mentioned in the previous response, you can add required padding to the custom trackball tooltip by wrapping the Padding widget. So that the trackball tooltip will render with some padding from the selected candle segment.


Snapshot:


2) You can achieve the mentioned requirement by rendering the custom trackball tooltip at the fixed position. When the trackball position changes, the current pointIndex will be obtained using the onTrackballPositionChanging callback and the respective details will be displayed in the bottom left info box as shown in the code snippet below.


class _MyHomePageState extends State<MyHomePage> {

  ValueNotifier<int?> pointIndex = ValueNotifier(0);

  late TrackballBehavior _trackballBehavior;

  late CrosshairBehavior _crosshairBehavior;

  late List<ChartSampleData> _data;

  DateTime now = DateTime.now();

  late TextStyle textStyle1;

  late TextStyle textStyle2;

  late String date;

 

  @override

  void initState() {

    _data = [

      ChartSampleData(x: 01, high: 20, low: 50, open: 35, close: 45),

      ChartSampleData(x: 02, high: 60, low: 30, open: 45, close: 55),

      ChartSampleData(x: 03, high: 20, low: 50, open: 35, close: 45),

      ChartSampleData(x: 04, high: 40, low: 10, open: 20, close: 30),

      ChartSampleData(x: 05, high: 30, low: 20, open: 25, close: 30),

      ChartSampleData(x: 06, high: 70, low: 40, open: 70, close: 40),

      ChartSampleData(x: 07, high: 90, low: 60, open: 80, close: 60),

      ChartSampleData(x: 08, high: 50, low: 20, open: 20, close: 30),

      ChartSampleData(x: 09, high: 100, low: 70, open: 80, close: 90),

      ChartSampleData(x: 10, high: 80, low: 50, open: 60, close: 70),

    ];

    date = DateFormat('MM/dd hh:mm').format(now);

    textStyle1 = const TextStyle(

      fontWeight: FontWeight.bold,

      fontSize: 14,

      color: Colors.red,

    );

    textStyle2 = const TextStyle(

      color: Colors.red,

    );

    _trackballBehavior = TrackballBehavior(

      enable: true,

      lineWidth: 0,

      tooltipSettings: const InteractiveTooltip(

        arrowWidth: 0,

        arrowLength: 0,

        enable: false,

      ),

      activationMode: ActivationMode.singleTap,

      tooltipDisplayMode: TrackballDisplayMode.floatAllPoints,

    );

    _crosshairBehavior = CrosshairBehavior(

      enable: true,

      activationMode: ActivationMode.singleTap,

      shouldAlwaysShow: true,

    );

    super.initState();

  }

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Stack(

        children: [

          SfCartesianChart(

            onTrackballPositionChanging: (trackballArgs) {

              pointIndex.value = trackballArgs.chartPointInfo.dataPointIndex;

            },

            primaryXAxis: NumericAxis(),

            primaryYAxis: NumericAxis(),

            series: <CartesianSeries<ChartSampleData, num>>[

              CandleSeries(

                dataSource: _data,

                enableSolidCandles: true,

                xValueMapper: (ChartSampleData sales, int index) => sales.x,

                highValueMapper: (ChartSampleData sales, int index) =>

                    sales.high,

                lowValueMapper: (ChartSampleData sales, int index) => sales.low,

                openValueMapper: (ChartSampleData sales, int index) =>

                    sales.open,

                closeValueMapper: (ChartSampleData sales, int index) =>

                    sales.close,

              ),

            ],

            trackballBehavior: _trackballBehavior,

            crosshairBehavior: _crosshairBehavior,

          ),

          Padding(

            padding: const EdgeInsets.only(left: 40, bottom: 35),

            child: Align(

              alignment: Alignment.bottomLeft,

              child: ValueListenableBuilder(

                valueListenable: pointIndex,

                builder: (BuildContext context, int? value, Widget? child) {

                  return Container(

                    height: 140,

                    width: 200,

                    decoration: BoxDecoration(

                      color: Colors.blue.shade100.withOpacity(0.5),

                      border: Border.all(

                        color: Colors.indigo,

                      ),

                    ),

                    padding: const EdgeInsets.all(10),

                    child: Column(

                      mainAxisAlignment: MainAxisAlignment.center,

                      mainAxisSize: MainAxisSize.min,

                      children: [

                        Row(

                          mainAxisAlignment: MainAxisAlignment.spaceBetween,

                          children: [

                            Text(

                              'Date/Time:',

                              style: textStyle1,

                            ),

                            Text(

                              date,

                              style: textStyle2,

                            ),

                          ],

                        ),

                        Row(

                          mainAxisAlignment: MainAxisAlignment.spaceBetween,

                          children: [

                            Text(

                              'Close:',

                              style: textStyle1,

                            ),

                            Text(

                              _data[pointIndex.value!].close.toString(),

                              style: textStyle2,

                            ),

                          ],

                        ),

                        Row(

                          mainAxisAlignment: MainAxisAlignment.spaceBetween,

                          children: [

                            Text(

                              'Open:',

                              style: textStyle1,

                            ),

                            Text(

                              _data[pointIndex.value!].open.toString(),

                              style: textStyle2,

                            ),

                          ],

                        ),

                        Row(

                          mainAxisAlignment: MainAxisAlignment.spaceBetween,

                          children: [

                            Text(

                              'High:',

                              style: textStyle1,

                            ),

                            Text(

                              _data[pointIndex.value!].high.toString(),

                              style: textStyle2,

                            ),

                          ],

                        ),

                        Row(

                          mainAxisAlignment: MainAxisAlignment.spaceBetween,

                          children: [

                            Text(

                              'Low:',

                              style: textStyle1,

                            ),

                            Text(

                              _data[pointIndex.value!].low.toString(),

                              style: textStyle2,

                            ),

                          ],

                        ),

                      ],

                    ),

                  );

                },

              ),

            ),

          ),

        ],

      ),

    );

  }

}

 



Snapshot:


Also attached the sample below for your reference and you can modify the sample based on your requirements. If you have further queries, please get back to us.


Regards,
Hari Hara Sudhan. K.


Attachment: _184086_ee2ed042.zip

Loader.
Up arrow icon