Drawing a line at the top of a StackingColumnSeries

Good morning,
I'm using the SfChart control to draw a chart using the StackingColumnSeries object. Now I have been asked to add a colored line at the top of each column, like in the attached sketch.

The XAxis is a datetime, the YAxis is a NumericalAxis.

I have tried adding a LineSeries to the chart series, but there's basically no space between points. I thought about a line annotation, but I can't figure out how to accomplish this. Any help would be really appreciated.

Thanks in advance,
Alessandro

Attachment: chart_sketch_80b65eb6.zip

5 Replies

MP Michael Prabhu M Syncfusion Team September 6, 2018 11:04 AM UTC

Hi Alessandro, 
 
Greetings from Syncfusion, we have analyzed your requirement and it can be achieved using our ChartDataMarker for chart series as like in below code snippet. 
 
Code snippet [XAML]:   
<chart:StackingColumnSeries x:Name="series"  ItemsSource="{Binding Data}" XBindingPath="Date" YBindingPath="YValue" > 
                    <chart:StackingColumnSeries.DataMarker> 
                        <chart:ChartDataMarker ShowLabel="false" MarkerType="Square" ShowMarker="true" MarkerColor="Blue" >                             
                        </chart:ChartDataMarker> 
                    </chart:StackingColumnSeries.DataMarker> 
</chart:StackingColumnSeries> 
 
  
Code snippet [C#]:    
stackingColumSeries.DataMarker = new ChartDataMarker(); 
stackingColumSeries.DataMarker.ShowLabel = false; 
stackingColumSeries.DataMarker.ShowMarker = true; 
stackingColumSeries.DataMarker.MarkerType = DataMarkerType.Square; 
stackingColumSeries.DataMarker.MarkerWidth = 25 
stackingColumSeries.DataMarker.MarkerHeight = 5; 
stackingColumSeries.DataMarker.MarkerColor = Color.Blue; 
 
 
Based on this we have prepared a simple sample and it can be downloaded from the link below. 
 
Sample: 139676 
 
Screenshot: 
 
 
Hope this helps. 
 
Thanks, 
Michael 




AD Alessandro Del Sole September 7, 2018 12:48 PM UTC

Thank you, the example works really nice with fixed values. However, I have multiple charts inside a list view and each chart has a StackingColumnSeries where the maximum of the NumericalAxis is not the same to the others, therefore setting the MarkerWidth as 27 (on iOS) doesn't work. It would be probably helpful to know how to get the real width (not the width in percentage) of each segment in the stacking columns, so that it could be possible to use that value as the marker width.

Thanks again for any possible hints.


MP Michael Prabhu M Syncfusion Team September 11, 2018 07:04 AM UTC

  
Hi Alessandro, 
 
Sorry for the delay in getting back at this, we have analyzed this and to provide more generic solution we have achieved your requirement by drawing line on series segments using CustomChartRenderer.CS, so here after no need to set marker width for series. It will automatically draw line on each series segment. Please refer CustomChartRenderer.CS for Android,iOS and UWP. 
Please refer blow code snippet. 
Code snippet for Android [C#]:    
public class CustomChartRenderer : SfChartRenderer 
    { 
        protected override void OnElementChanged(ElementChangedEventArgs<SfChart> e) 
        { 
            base.OnElementChanged(e); 
        } 
        public override SfChartExt CreateNativeChart() 
        { 
            return new CustomChart(Android.App.Application.Context); 
        } 
    } 
    public class CustomChart : SfChartExt 
    { 
        public CustomChart(Android.Content.Context context) : base(context) 
        { 
             
        } 
        protected override Native.ChartSeries CreateNativeChartSeries(ChartSeries formSeries) 
        { 
            if (formSeries is StackingColumnSeries) 
            { 
                return new CustomStackingColumSeries(); 
            } 
            return base.CreateNativeChartSeries(formSeries); 
        } 
    } 
    public class CustomStackingColumSeries : Native.StackingColumnSeries 
    {         
        protected override Native.ChartSegment CreateSegment() 
        { 
            return new CustomStackingColumSegment(); 
        } 
    } 
    public class CustomStackingColumSegment : Native.ColumnSegment 
    { 
        RectF rect = new RectF(); 
        Paint paint = new Paint(); 
        public override void OnDraw(Canvas canvas) 
        { 
            canvas.Save(); 
            base.OnDraw(canvas); 
            canvas.Restore(); 
                        
            paint.Color = Android.Graphics.Color.Blue; 
            paint.StrokeWidth = 8 ; 
            paint.SetStyle(Paint.Style.Fill); 
            canvas.Save(); 
            canvas.DrawLine(Left, Top, Right, Top, paint); 
            canvas.Restore(); 
        } 
    } 
Code snippet for iOS [C#]:    
public class CustomChartRenderer : SfChartRenderer 
    { 
        protected override void OnElementChanged(ElementChangedEventArgs<SfChart> e) 
        { 
            base.OnElementChanged(e); 
        } 
        public override Native.SFChart CreateNativeChart() 
        { 
            return new CustomChart(); 
        } 
    } 
    public class CustomChart : Native.SFChart 
    { 
        protected override Native.SFSeries CreateNativeChartSeries(ChartSeries formSeries) 
        { 
            if(formSeries is StackingColumnSeries) 
            { 
                return new CustomStackingColumSeries(); 
            } 
            return base.CreateNativeChartSeries(formSeries); 
        } 
    } 
    public class CustomStackingColumSeries : Native.SFStackingColumnSeries 
    { 
        protected override Native.SFChartSegment CreateSegment() 
        { 
            return new CustomStackingColumSegment(); 
        } 
    } 
    public class CustomStackingColumSegment : Native.SFColumnSegment 
    { 
        public override void DrawSegment(CGContext context) 
        { 
            base.DrawSegment(context); 
            context.SaveState(); 
            UIColor color = UIColor.Blue;              
            context.SetStrokeColor(color.CGColor); 
            context.SetLineWidth(4);            
            context.MoveTo(Left,Top); 
            context.AddLineToPoint(Right, Top); 
            context.ClosePath(); 
            context.DrawPath(CGPathDrawingMode.FillStroke); 
            context.RestoreState(); 
        } 
    } 
Code snippet for UWP :    
[Xaml]:    
<Application.Resources> 
        <ResourceDictionary> 
            <DataTemplate x:Key="template"> 
                <Canvas> 
                    <Border Background="{Binding Interior}" Canvas.Left="{Binding RectX}" Canvas.Top="{Binding RectY}" Width="{Binding Width}" Height="{Binding Height}" BorderThickness="0,5,0,0" BorderBrush="Blue" /> 
                </Canvas> 
            </DataTemplate> 
        </ResourceDictionary> 
</Application.Resources> 
C# 
class CustomChartRenderer : SfChartRenderer 
    { 
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) 
        { 
            base.OnElementPropertyChanged(sender, e); 
            for (int i = 0;i < Control.Series.Count;i++) 
            { 
                StackingColumnSeries series = Control.Series[i] as StackingColumnSeries; 
                series.CustomTemplate=  App.Current.Resources["template"] as Windows.UI.Xaml.DataTemplate; 
            } 
        } 
    } 
  
Also, we have prepared a sample for this, which can be downloaded from the link below. 
 
Sample: 139676_new 
 
Thanks, 
Michael 




AD Alessandro Del Sole September 21, 2018 10:01 AM UTC

I forgot to reply, but thanks... the latest example did the trick. THank you very much!


MP Michael Prabhu M Syncfusion Team September 21, 2018 10:13 AM UTC

Hi Alessandro, 
 
Glad we could help, feel free to contact us any time if you need any other assistance from us. 
 
Thanks, 
Michael  



Loader.
Up arrow icon