How to style the bars of a RadChartView?

5 posts, 0 answers
  1. Leigh
    Leigh avatar
    1 posts
    Member since:
    Jun 2013

    Posted 19 Feb 2015 Link to this post

    I'm struggling to find anything in the documentation about how to style the bars in a bar chart.

    I'd like the bars to look as per the attachment, with a shadow to the bottom and to the right.

    With series defined as a BarSeries, I tried this, but it had no effect on the appearance of the bars:

    series.BorderBoxStyle = Telerik.WinControls.BorderBoxStyle.FourBorders
    series.BorderBottomShadowColor = Color.Gray
    series.BorderRightShadowColor = Color.Gray
    series.BorderRightWidth = 20
    series.BorderBottomWidth = 40

    Please could you let me know how to achieve this?

    Leigh
  2. Dimitar
    Admin
    Dimitar avatar
    2960 posts

    Posted 24 Feb 2015 Link to this post

    Hello Leigh,

    Thank you for writing.

    This is not supported out of the box, but can be achieved by using custom renderer. The attached example shows sample implementation for this. 

    Please let me know if there is something else I can help you with. 
     
    Regards,
    Dimitar
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. Stephan
    Stephan avatar
    12 posts
    Member since:
    May 2019

    Posted 09 Jun 2020 in reply to Dimitar Link to this post

    Hello Telerik Support,

    I know this is an old post, but I found a design flaw (see: https://docs.microsoft.com/en-us/visualstudio/code-quality/ca2214?view=vs-2019&redirectedfrom=MSDN). The current version (2020.2.512) is also affected.

    The constructor of the class CartesianRenderer calls virtual method Initialize(). So you can't set any properties of the derived renderer class to use it in the overridden Initialize method. Here's some example code:

    public class RenderParameter
    {
        //just an example
        public Color Color { get; set }
         
        public RenderParameter() {}
    }
     
    public class CustomCartesianRenderer : CartesianRenderer
    {
        private RenderParameter RenderParameter { get; set; }
     
        public CustomCartesianRenderer(RenderParameter renderParameter, CartesianArea area) : base(area)
        {
            RenderParameter = renderParameter ?? throw new ArgumentNullException(nameof(renderParameter));
        }
     
     
        protected override void Initialize()
        {
            base.Initialize();
            for (int i = 0; i < this.DrawParts.Count; i++)
            {
                if (this.DrawParts[i] is BarSeriesDrawPart barPart)
                {
                    this.DrawParts[i] = new CustomBarSeriesDrawPart(RenderParameter, (BarSeries)barPart.Element, this);
                }
            }
        }
    }
     
     
    public class CustomBarSeriesDrawPart : BarSeriesDrawPart
    {
        private RenderParameter RenderParameter { get; }
     
        public CustomBarSeriesDrawPart(RenderParameter renderParameter, BarSeries series, IChartRenderer renderer) : base(series, renderer)
        {
            RenderParameter = renderParameter ?? throw new ArgumentNullException(nameof(renderParameter));
        }
     
        public override void DrawSeriesParts()
        {
            //here I want to use RenderParameter
        }
    }

     

    Regards,

    Stephan

  4. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    4131 posts

    Posted 10 Jun 2020 Link to this post

    Hello, Stephan, 

    In the DrawSeriesParts method of the custom BarSeriesDrawPart class you have access to the CartesianRenderer via the Renderer property. You need to cast it to the custom renderer that you have and thus you will have access to the RenderParameter property. Please refer to the following code snippet:
            public Form1()
            {
                InitializeComponent();
                this.radChartView1.CreateRenderer += new ChartViewCreateRendererEventHandler(radChartView1_CreateRenderer);
                BarSeries barSeries = new BarSeries("Performance", "RepresentativeName");
                barSeries.Name = "Q1";
                barSeries.DataPoints.Add(new CategoricalDataPoint(177, "Harley"));
                barSeries.DataPoints.Add(new CategoricalDataPoint(128, "White"));
                barSeries.DataPoints.Add(new CategoricalDataPoint(143, "Smith"));
                barSeries.DataPoints.Add(new CategoricalDataPoint(111, "Jones"));
                barSeries.DataPoints.Add(new CategoricalDataPoint(118, "Marshall"));
                this.radChartView1.Series.Add(barSeries);
            }
    
            void radChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
            {
                RenderParameter param = new RenderParameter();
                param.Color = Color.Red;
                e.Renderer = new CustomCartesianRenderer(param, e.Area as CartesianArea);
            }
        }
    
        public class RenderParameter
        {
            //just an example
            public Color Color { get; set; }
         
            public RenderParameter()
            {
            }
        }
        
        public class CustomCartesianRenderer : CartesianRenderer
        {
            internal RenderParameter RenderParameter { get; set; }
    
            public CustomCartesianRenderer(CartesianArea area) : base(area)
            {
            }
            public CustomCartesianRenderer(RenderParameter renderParameter, CartesianArea area) : base(area)
            {
                RenderParameter = renderParameter ?? throw new ArgumentNullException(nameof(renderParameter));
            }
    
            protected override void Initialize()
            {
                base.Initialize();
    
                for (int i = 0; i < this.DrawParts.Count; i++)
                {
                    BarSeriesDrawPart linePart = this.DrawParts[i] as BarSeriesDrawPart;
                    if (linePart != null)
                    {
                        this.DrawParts[i] = new CustomBarSeriesDrawPart((BarSeries)linePart.Element, this);
                    }
                }
            }
        }
    
        public class CustomBarSeriesDrawPart : BarSeriesDrawPart
        {
            public CustomBarSeriesDrawPart(BarSeries series, IChartRenderer renderer) : base(series, renderer)
            {
            }
    
            public override void DrawSeriesParts()
            {
                CustomCartesianRenderer customRenderer = this.Renderer as CustomCartesianRenderer;
                RenderParameter param= customRenderer.RenderParameter;
    
                Graphics graphics = customRenderer.Graphics;
                RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
    
                for (int j = 0; j < this.Element.DataPoints.Count; j++)
                {
                    RadRect slot = this.Element.DataPoints[j].LayoutSlot;
                    RectangleF temp = new RectangleF((float)(this.OffsetX + slot.X), (float)(this.OffsetY + slot.Y), (float)slot.Width, (float)slot.Height);
                    RectangleF barBounds = new RectangleF(temp.X + 10,temp.Y + 10,temp.Width,temp.Height + 10);
    
                    DataPointElement childElement = (DataPointElement)this.Element.Children[j];
    
                    float realWidth = barBounds.Width * childElement.HeightAspectRatio;
                    barBounds.Width = realWidth;
                    
                    barBounds.Height = Math.Max(barBounds.Height, 1f);
                    
                    radGraphics.FillRectangle(barBounds, Color.LightGray);
                }
                base.DrawSeriesParts();
            }
        }
    I hope this information helps. If you need any further assistance please don't hesitate to contact me. 

    Regards,
    Dess | Tech Support Engineer, Sr.
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
  5. Stephan
    Stephan avatar
    12 posts
    Member since:
    May 2019

    Posted 10 Jun 2020 Link to this post

    Hello Dess,

    your provided solution works fine. Thank you for your help.

    Regards,

    Stephan

Back to Top