How can I draw a custom bracket above selected columns in an SFCartesianChart after PaletteBrushes are updated?

I’m working with an SFCartesianChart that displays hourly dynamic energy prices (24 hours, prices per hour). The columns are colored using PaletteBrushes based on price ranges, which works as expected.

I also have a selector that highlights, for example, the three cheapest consecutive hours. When the user selects this option, I update the PaletteBrushes so that these three columns get a specific color.

At that moment, I would like to draw a bracket (or any custom annotation) above those three highlighted columns, showing the average price of the selected range.

My question is: Is there an event or behavior in Syncfusion’s SFCartesianChart that triggers after the columns or PaletteBrushes are refreshed, so I can safely draw custom elements on top of the chart (e.g., via a canvas overlay or custom annotation)?

I’m looking for something like a “rendered” or “layout updated” event that fires after the chart has recalculated the column positions.

Thanks in advance for any guidance.


17 Replies

SM Saravanan Madheswaran Syncfusion Team February 16, 2026 07:10 AM UTC

Hi Marcel,


Thank you for the detailed explanation of your use case.

Currently, the chart does not expose a dedicated “rendered” or “layout updated” event specifically for scenarios like updating PaletteBrushes and then drawing additional elements on top. However, you can achieve your requirement by using custom drawing via custom segments in the chart series.

1. Custom drawing using a custom segment

You can override the segment rendering of the series and perform your custom drawing (such as a bracket above the selected columns). Please refer to the following knowledge base article, where we demonstrate how to draw custom content (vector images) in a .NET MAUI Cartesian chart:

🔗 How to load vector images in .NET MAUI Cartesian Chart
https://support.syncfusion.com/kb/article/16708/how-to-load-vector-images-in-net-maui-cartesian-chart-

In that example, instead of drawing the default column, we render an image. In your case, you can adapt this pattern to:

  • Draw the normal columns as usual, and
  • Add your custom bracket/annotation above the selected range within the overridden segment’s Draw/OnPaint logic, once the chart has calculated the segment’s bounds.

Since the segment is drawn after layout is completed, you can safely use the computed rect/points to place your bracket correctly above the three consecutive columns.

2. Using selection to trigger re-rendering

When you update the selection (for example, selecting the three cheapest consecutive hours) and/or change the PaletteBrushes, the chart will re-render the series. If you combine this with a custom segment:

  • Each selection change causes the chart to re-render
  • Your overridden drawing logic is called again
  • The bracket will be redrawn in the correct position above the newly selected columns

You can refer to the selection behavior details here:

🔗 Selection in .NET MAUI Cartesian Charts
https://help.syncfusion.com/maui/cartesian-charts/selection

You can store the selected range (start index, end index, or data points) in your view model or chart behavior and use that inside the custom segment to decide when and where to draw the bracket.

3. Drawing relative to axis positions (if needed)

If you want to align the bracket or text (average price) precisely with axis values (for example, placing it just above the maximum Y value of the selected range), you can convert between screen points and data values using the helper APIs:

🔗 How to convert screen points to data values and vice versa in .NET MAUI SfCartesianChart
https://support.syncfusion.com/kb/article/18515/how-to-convert-screen-points-to-data-values-and-vice-versa-in-net-maui-chart-sfcartesianchart

This will help you calculate the exact position above the selected columns in chart coordinates.


Regards,

Saravanan.



MT Marcel Timmermans February 16, 2026 08:46 AM UTC

Hi,


Thanks for your quick response. I’ve been looking into this, but I was under the impression that this would be called for every column. Does that mean that if I want to calculate the average price across three columns, I would need to use some kind of workaround? Or is this method called only once and responsible for rendering all columns?

Br,


Marcel




SA Saiyath Ali Fathima Bee Moidhin Abdhul Kathar Syncfusion Team February 16, 2026 10:41 AM UTC

Hi Marcel,

We can add custom annotations at the required position using ViewAnnotation. For more details, please refer to our UG documentation here: Annotations in .NET MAUI Chart control | Syncfusion

 

Additionally, we have attached a demo and a runnable sample to help you implement this functionality in your application.


Hope this helps you achieve your requirements.

 

Regards,

Fathima M


Attachment: ChartAnnotationSample_c91b3adc.zip


MT Marcel Timmermans February 16, 2026 12:26 PM UTC

Hi,

Thanks, I don't think this is what I am searching for but I will give it a try.

I want to achieve this, the lines that are drawn with the text above:

Image_8894_1771244703594



VR Vallarasu Ravichandran Syncfusion Team February 17, 2026 11:33 AM UTC

Hi Marcel,

 

Thank you for your update.

To render the average text above the selected segment, you can use Shape Annotations. By utilizing data point selection, the corresponding segment index can be identified and updated either through a button click or through touch interaction. When using touch, the SelectionChanged event can be handled to apply the similar logic used for buttonbased selection.

 

We have shared the button click event code snippet and the output image for your reference. With these values, you can also draw a Line Annotation to achieve the bracketstyle line based on your requirements.

 

[C#]

 

        private void Button_Clicked(object sender, EventArgs e)

        {

            var indexesToSelect = new List<int> { 5, 6, 7 };

            PriceSeries.SelectedIndexes?.Clear();

 

            foreach (var idx in indexesToSelect)

                PriceSeries.SelectedIndexes?.Add(idx);

 

            PriceSeries.SelectionBrush = Colors.Gold;

            var selectedPrices = indexesToSelect

                .Where(i => i >= 0 && i < viewmodel.Data.Count)

                .Select(i => viewmodel.Data[i].Price)

                .ToList();

 

            double averagePrice = selectedPrices.Average();

            int minIndex = indexesToSelect.Min();

            int maxIndex = indexesToSelect.Max();

            var fromHour = viewmodel.Data[minIndex].Hour;

            var toHour = viewmodel.Data[maxIndex].Hour;

 

            var AvgText = new RectangleAnnotation()

            {

                Text = $"Avg {fromHour:HH} – {toHour:HH} = {averagePrice:0.##}",

                Fill = Colors.Black,

                X1 = fromHour,

                X2 = toHour,

                Y1 = averagePrice,

                Y2 = averagePrice + 6,

                CoordinateUnit = ChartCoordinateUnit.Axis,

                LabelStyle = new ChartAnnotationLabelStyle

                {

                    TextColor = Colors.White,

                    FontSize = 12,

                }

            };

 

            chart.Annotations.Add(AvgText);

        }

 

 

Regarding the bracketstyle lines you want to display, this can be achieved using Line Annotations. Syncfusion provides builtin support for adding arrow markers (or bracketlike visuals) to vertical and horizontal line annotations. You can refer to the official documentation below for detailed guidance:

Please review the sample and documentation and hope this helps you achieve your requirements.


 Screenshot 2026-02-17 124145

Regards,

Vallarasu R


Attachment: ChartSample_52bbdb47.zip


MT Marcel Timmermans February 17, 2026 09:07 PM UTC

Hi,


Thank you for the information, I will look into this.



PR Preethi Rajakandham Syncfusion Team February 18, 2026 04:48 AM UTC

Hi Marcel Timmermans,

You are welcome. Please check and revert back to us. We will await your response.

Regards,

Preethi R



MT Marcel Timmermans February 19, 2026 05:05 PM UTC

Hi,


I have tried using RectangleAnnotation and I am wondering if there is a way to prevent the label from disappearing in non-visible areas (see pictures). Or do I need to switch the CoordinateUnit to Pixel and calculate everything myself?

app1.png


app2.png



VR Vallarasu Ravichandran Syncfusion Team February 20, 2026 12:28 PM UTC

Hi Marcel,


Thank you for reaching out.

When using RectangleAnnotation, the label visibility depends on the available space within the defined region (X1, X2, Y1, Y2). In your case, the text extends beyond the visible annotation area, which causes the label to clip or disappear when it moves outside the chart's visible bounds.

 

1. Adjust the text to fit within the rectangle

If you want to keep using CoordinateUnit.Axis, the annotation must have enough space to render the label. You could reduce the font size or increase the rectangle size accordingly.

 

2. Use CoordinateUnit.Pixel for full control

As you mentioned, switching the CoordinateUnit to Pixel allows you to manually position and size both the rectangle and text elements. This helps maintain visibility regardless of chart zoom or axis ranges.

For more details here: Positioning the annotation in .NET MAUI Chart control | Syncfusion

 

3. Use a TextAnnotation instead of a label inside a rectangle

From your screenshot, it appears the label has its own background, separate from the rectangle. If your requirement is more text‑focused, you may use TextAnnotation directly this avoids clipping issues and provides better customization for text rendering. For more details here: Text Annotations in .NET MAUI Chart control | Syncfusion 
Please review the documentation and hope this helps you achieve your requirements.

 

Regards,

Vallarasu R



MT Marcel Timmermans February 22, 2026 09:34 PM UTC

Hi,

I used option 2 as the other suggestions did not work. It would be nice that in future version there is a an dedicated “rendered” or “layout updated” event. As I could not implemented what I needed to do. So I have the closed thing I could build with this.

thanks for the support,


Marcel



VR Vallarasu Ravichandran Syncfusion Team February 23, 2026 12:48 PM UTC

Hi Marcel,

 

Thank you for the update, and We glad to hear that option 2 worked for you. We appreciate your feedback as well that having a dedicated “rendered” or “layout updated” event would definitely make scenarios easier, but we can also achieve with custom annotation class.

 

Regarding the behavior you observed: the built‑in TextAnnotation gets clipped whenever it moves outside the chart’s visible plot area. Because of this, the label can disappear when positioned beyond the chart bounds.

To avoid this, you can override the Draw method and implement your own custom rendering logic. This approach lets you fully control how and where the annotation is drawn, ensuring it stays visible even when the annotation moves outside the default plot area.

 [C#]

        private void Button_Clicked(object sender, EventArgs e)

        {

            var indexesToSelect = new List<int> { 0,1, 2 };

            ---------------

            ----------------

            var AvgText = new CustomTextAnnotation()

            {

                Text = $"Avg {fromHour:HH} – {toHour:HH} = {averagePrice:0.##}",

                // store the data index so CustomTextAnnotation can compute a pixel X

                DataIndex = indexesToSelect[1], // used middle index for better centering of label

                X1 = fromHour,

                Y1 = averagePrice,

                CoordinateUnit = ChartCoordinateUnit.Axis,

                LabelStyle = new ChartAnnotationLabelStyle

                {

                    TextColor = Colors.White,

                    FontSize = 18,

                    Background = Colors.Grey

                }

            };

 

            // assign the owning chart so the annotation can reference series bounds when drawing

            AvgText.OwnerChart = chart;

            chart.Annotations.Add(AvgText);

        }

 

 // Custom annotation class

 public class CustomTextAnnotation : TextAnnotation

 {

     public SfCartesianChart? OwnerChart { get; set; }

     public int? DataIndex { get; set; }

     protected override void Draw(ICanvas canvas, RectF dirtyRect)

     {

          // Add drawing logic

      }

}


Our chart annotations support complete custom drawing through the Draw override, and we’ve prepared a sample using a CustomTextAnnotation class that inherits from TextAnnotation. In this sample, the annotation text automatically adjusts and stays positioned within the series bounds, preventing clipping or disappearance.

For reference, here is the documentation on overriding the draw method:

TextAnnotation Methods- MAUI API Reference | Syncfusion

 

Using this approach, you can maintain label visibility consistently, regardless of its position. We’ve also included the sample and its output for your convenience.

 

 Screenshot 2026-02-23 150830

 

Regards,

Vallarasu R


Attachment: CustomAnnotationSample_c7458034.zip


MT Marcel Timmermans February 23, 2026 05:20 PM UTC

Thanks. I will look into this as well.




MT Marcel Timmermans March 1, 2026 05:26 PM UTC

Hi,

Thanks, this is working great!




VR Vallarasu Ravichandran Syncfusion Team March 2, 2026 05:39 AM UTC

Hi Marcel,


Thanks for the update! Glad to know everything is working fine now.

If you need any further clarification or assistance, please feel free to let us know. We are happy to help.

 

Regards,

Vallarasu R



MT Marcel Timmermans March 2, 2026 02:21 PM UTC

Hi, 

Everything is working as expected. So, no issues.

 Thanks for the very good support!!

Br,

Marcel




PR Preethi Rajakandham Syncfusion Team March 3, 2026 05:11 AM UTC

Hi Marcel Timmermans,

Thank you for the update.


Loader.
Up arrow icon