Unplanned
Last Updated: 31 Jul 2023 16:44 by ADMIN

Hello Telerik Support,

after taking my first steps with RangeSelector and ChartView controls I found an issue with a simple bar chart. The length of some bars in the chart of the RangeSelector doesn't match with the bars in the ChartView. The relation is wrong.I provided a screenshot and marked the bars. I could provide a sample application, but I can't attach a zip file, so here's the code of the main form:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
 
namespace TelerikChartView
{
    public partial class MainForm : Telerik.WinControls.UI.RadForm
    {
        private List<Kapazitaetspunkt> _BackListPunkte;
        private BindingList<Kapazitaetspunkt> Punkte;
 
        public MainForm()
        {
            InitializeComponent();
        }
 
        private void MainForm_Load(object sender, EventArgs e)
        {
            _BackListPunkte = new List<Kapazitaetspunkt>();
            Punkte = new BindingList<Kapazitaetspunkt>(_BackListPunkte);
            //Punkte = new BindingList<Kapazitaetspunkt>();
            rngTimeSelector.AssociatedControl = cvChart;
            rngTimeSelector.RangeSelectorElement.ScrollSelectorElement.Visibility = ElementVisibility.Collapsed;
 
            BarSeries bars = new BarSeries();
            bars.DataSource = Punkte;
            bars.ValueMember = nameof(Kapazitaetspunkt.Percentage);
            bars.CategoryMember = nameof(Kapazitaetspunkt.Date);
            cvChart.Series.Add(bars);
        }
 
        private void GenerateTestData(int addMonths = 0)
        {
            Punkte.Clear();
            const int count = 25;
            const int step = 4;
            var von = DateTime.Today.AddMonths(addMonths);
            var bis = von.AddDays(count);
            double percentage = 0;
            //_BackListPunkte.Add(new Kapazitaetspunkt(von.AddDays(-1), null));
            Punkte.Add(new Kapazitaetspunkt(von.AddDays(-1), null));
 
            while (von < bis)
            {
                //_BackListPunkte.Add(new Kapazitaetspunkt(von, percentage));
                Punkte.Add(new Kapazitaetspunkt(von, percentage));
                percentage += step;
                von = von.AddDays(1);
            }
 
            //_BackListPunkte.Add(new Kapazitaetspunkt(von.AddDays(1), null));
            Punkte.Add(new Kapazitaetspunkt(von.AddDays(1), null));
        }
 
        private void btnGenerateData_Click(object sender, EventArgs e)
        {
            GenerateTestData();
 
            rngTimeSelector.RangeSelectorElement.InitializeElements();
            rngTimeSelector.RangeSelectorElement.ResetLayout(true);
        }
 
        private void btnGenerateData2_Click(object sender, EventArgs e)
        {
            GenerateTestData(2);
 
            rngTimeSelector.RangeSelectorElement.InitializeElements();
            rngTimeSelector.RangeSelectorElement.ResetLayout(true);
 
        }
 
        private void rngTimeSelector_ScaleInitializing(object sender, ScaleInitializingEventArgs e)
        {
            e.Cancel = true;
        }
    }
 
    public class Kapazitaetspunkt : INotifyPropertyChanged
    {
        private DateTime _Date;
 
        public DateTime Date
        {
            get => _Date;
            set
            {
                if (value != Date)
                {
                    _Date = value;
                    OnPropertyChanged();
                }
            }
        }
 
 
        public double? _Percentage;
 
        public double? Percentage
        {
            get => _Percentage;
            set
            {
                if (value != Percentage)
                {
                    _Percentage = value;
                    OnPropertyChanged();
                }
            }
        }
 
 
        public Kapazitaetspunkt(DateTime date, double? percentage)
        {
            Date = date;
            Percentage = percentage;
        }
 
 
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Regards,

Stephan

Unplanned
Last Updated: 16 Apr 2021 12:30 by ADMIN
Created by: Dmitriy
Comments: 0
Category: ChartView
Type: Feature Request
3
Add the ability to aggregate a large number of data points.
Completed
Last Updated: 26 Jun 2018 06:55 by Dimitar
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: ChartView
Type: Bug Report
2
To reproduce: please refer to the attached sample project and gif file.

Workaround: 
            CustomLassoSelectionController lassoSelectionController = new CustomLassoSelectionController(); 
            this.radChartView1.Controllers.Add(lassoSelectionController);

        public class CustomLassoSelectionController : LassoSelectionController
        {
            private IList<DataPoint> selectedPoints = null;

            public CustomLassoSelectionController()
            {
                this.selectedPoints = new List<DataPoint>();
            }

            private Point ClipLocation(Point point)
            {
                CartesianArea area = this.Area.View.GetArea<CartesianArea>();
                if (area != null)
                {
                    RectangleF clipRect = GetCartesianClipRect(area);

                    if (point.X < clipRect.X)
                    {
                        point = new Point((int)clipRect.X, point.Y);
                    }

                    if (point.X > clipRect.Width + clipRect.X)
                    {
                        point = new Point((int)clipRect.Width + (int)clipRect.X, point.Y);
                    }

                    if (point.Y < clipRect.Y)
                    {
                        point = new Point(point.X, (int)clipRect.Y);
                    }

                    if (point.Y > clipRect.Height + clipRect.Y)
                    {
                        point = new Point(point.X, (int)clipRect.Height + (int)clipRect.Y);
                    }
                }

                return point;
            }

            internal RectangleF GetCartesianClipRect(CartesianArea area)
            {
                float x1, x2, y1, y2;
                x1 = 0;
                y1 = 0;
                x2 = (float)area.View.Viewport.Right;
                y2 = (float)area.View.Viewport.Bottom;

                foreach (var axis in area.View.Axes)
                {
                    if (axis.AxisType == AxisType.First)
                    {
                        if (axis.Model.VerticalLocation == AxisVerticalLocation.Bottom)
                        {
                            y2 = Math.Min(y2, (float)axis.Model.LayoutSlot.Y);
                        }
                        else
                        {
                            y1 = Math.Max(y1, (float)axis.Model.LayoutSlot.Bottom);
                        }

                        x1 = Math.Min(x1, (float)axis.Model.LayoutSlot.X);
                        x2 = Math.Min(x2, (float)axis.Model.LayoutSlot.Right);
                    }
                    else
                    {
                        if (axis.Model.HorizontalLocation == AxisHorizontalLocation.Left)
                        {
                            x1 = Math.Max(x1, (float)axis.Model.LayoutSlot.Right);
                        }
                        else
                        {
                            x2 = Math.Min(x2, (float)axis.Model.LayoutSlot.X);
                        }

                        y1 = Math.Max(y1, (float)axis.Model.LayoutSlot.Y);
                        y2 = Math.Min(y2, (float)axis.Model.LayoutSlot.Bottom);
                    }
                }

                RectangleF result = new RectangleF((float)area.View.Viewport.X + x1, (float)area.View.Viewport.Y + y1, x2 - x1 + 1, y2 - y1 + 1);

                return result;
            }

            protected override ActionResult OnMouseUp(MouseEventArgs e)
            {
                if (e.Button != MouseButtons.Left || this.MouseDownLocation == Point.Empty || this.MouseMoveLocation == Point.Empty)
                {
                    return base.OnMouseUp(e);
                }

                if (MouseDownLocation != MouseMoveLocation)
                {
                    this.MouseMoveLocation = ClipLocation(e.Location);
                    CartesianArea area = this.Area.View.GetArea<CartesianArea>();

                    if (area != null)
                    {
                        this.selectedPoints.Clear();
                        RectangleF areaRect = RectangleF.Empty;
                        IChartView chartView = this.Area.View;
                        areaRect = GetCartesianClipRect(area);

                        Point topLeft = new Point(Math.Min(MouseDownLocation.X, e.X), Math.Min(MouseDownLocation.Y, e.Y));
                        Point lowerRight = new Point(Math.Max(MouseDownLocation.X, e.X), Math.Max(MouseDownLocation.Y, e.Y));
                        RectangleF lassoRect = new RectangleF(new PointF(topLeft.X - (float)chartView.PlotOriginX - area.View.Margin.Left, topLeft.Y - (float)chartView.PlotOriginY - area.View.Margin.Top), new SizeF(lowerRight.X - topLeft.X, lowerRight.Y - topLeft.Y));

                        foreach (var series in area.View.Series)
                        {
                            foreach (var dataPoint in series.DataPoints)
                            {
                                if (lassoRect.Contains(new PointF((float)dataPoint.LayoutSlot.Location.X, (float)dataPoint.LayoutSlot.Location.Y)))
                                {
                                    dataPoint.IsSelected = true;
                                    this.selectedPoints.Add(dataPoint);
                                }
                                else
                                {
                                    dataPoint.IsSelected = false;
                                }
                            }
                        }
                        
                        ChartDataPointsEventArgs changedArgs = new ChartDataPointsEventArgs(this.selectedPoints);
                        this.OnLassoSelectedPointsChanged(changedArgs);
                    }

                    MouseDownLocation = MouseMoveLocation = Point.Empty;
                }

                this.Result.ShouldInvalidate = true;
                return this.Result;
            }
        }
Completed
Last Updated: 23 Nov 2018 11:34 by Dimitar
To reproduce:
            WaterfallSeries series = new WaterfallSeries();
            series.ShowLabels = true;

            series.DataPoints.Add(new WaterfallDataPoint(50000, false, false, "Beginning\nBalance"));
            series.DataPoints.Add(new WaterfallDataPoint(17000, false, false, "Jan"));
            series.DataPoints.Add(new WaterfallDataPoint(14000, false, false, "Feb"));
            series.DataPoints.Add(new WaterfallDataPoint(-12000, false, false, "Mar"));
            series.DataPoints.Add(new WaterfallDataPoint(69000, true, false, "Q1"));
            series.DataPoints.Add(new WaterfallDataPoint(-22000, false, false, "Apr"));
            series.DataPoints.Add(new WaterfallDataPoint(-18000, false, false, "May"));
            series.DataPoints.Add(new WaterfallDataPoint(500, false, false, "Jun"));
            series.DataPoints.Add(new WaterfallDataPoint(-30000, true, false, "Q2"));
            series.DataPoints.Add(new WaterfallDataPoint(39000, false, true, "Ending\nBalance"));
            this.radChartView1.Series.Add(series);

            CartesianGridLineAnnotation annotation1 = new CartesianGridLineAnnotation();
            annotation1.Label = "Annotation";
            annotation1.ForeColor = Color.Lime;
            annotation1.BackColor = Color.Black;
            this.radChartView1.Annotations.Add(annotation1);

Workaround:

        public RadForm1()
        {
            InitializeComponent();
            this.radChartView1.CreateRenderer += radChartView1_CreateRenderer;

            WaterfallSeries series = new WaterfallSeries();
            series.ShowLabels = true;
     
            series.DataPoints.Add(new WaterfallDataPoint(50000, false, false, "Beginning\nBalance"));
            series.DataPoints.Add(new WaterfallDataPoint(17000, false, false, "Jan"));
            series.DataPoints.Add(new WaterfallDataPoint(14000, false, false, "Feb"));
            series.DataPoints.Add(new WaterfallDataPoint(-12000, false, false, "Mar"));
            series.DataPoints.Add(new WaterfallDataPoint(69000, true, false, "Q1"));
            series.DataPoints.Add(new WaterfallDataPoint(-22000, false, false, "Apr"));
            series.DataPoints.Add(new WaterfallDataPoint(-18000, false, false, "May"));
            series.DataPoints.Add(new WaterfallDataPoint(500, false, false, "Jun"));
            series.DataPoints.Add(new WaterfallDataPoint(-30000, true, false, "Q2"));
            series.DataPoints.Add(new WaterfallDataPoint(39000, false, true, "Ending\nBalance"));
            this.radChartView1.Series.Add(series);
 
            CartesianGridLineAnnotation annotation1 = new CartesianGridLineAnnotation();
            annotation1.Label = "Annotation";
            annotation1.ForeColor = Color.Lime;
            annotation1.BackColor = Color.Black;
            annotation1.PositonOffset = new SizeF(0, -20);
            annotation1.Axis = this.radChartView1.Axes[1] as CartesianAxis;
            annotation1.Value = 70000;
            annotation1.BorderColor = Color.Red;
            annotation1.BorderDashStyle = DashStyle.Solid;
            annotation1.BorderWidth = 1;
            this.radChartView1.Annotations.Add(annotation1);
        }

        private void radChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
        {
            e.Renderer = new CustomCartesianRenderer(e.Area as CartesianArea);
        }
 
        public class CustomCartesianRenderer : CartesianRenderer
        {
            public CustomCartesianRenderer(CartesianArea area) : base(area)
            {
            }
 
            protected override void Initialize()
            {
                base.Initialize();
                for (int i = 0; i <= this.DrawParts.Count - 1; i++)
                {
                    CartesianGridLineAnnotationDrawPart annotationPart = this.DrawParts[i] as CartesianGridLineAnnotationDrawPart;
                    if (annotationPart != null)
                    {
                        this.DrawParts[i] = new CustomCartesianGridLineAnnotationDrawPart((CartesianGridLineAnnotation)annotationPart.Element, this);
                    }
                }
            }
        }

        public class CustomCartesianGridLineAnnotationDrawPart : CartesianGridLineAnnotationDrawPart
        {
            public CustomCartesianGridLineAnnotationDrawPart(CartesianGridLineAnnotation element, CartesianRenderer renderer) : base(element, renderer)
            {
            }

            public override void Draw()
            {
                FieldInfo fi = typeof(CartesianGridLineAnnotation).GetField("model", BindingFlags.NonPublic | BindingFlags.Instance);
                ChartAnnotationModel model = fi.GetValue(this.Element) as ChartAnnotationModel;
                RectangleF
                rect = ChartRenderer.ToRectangleF(model.LayoutSlot);
                rect.Offset(this.ViewportOffsetX, this.ViewportOffsetY);

                Graphics graphics = this.Renderer.Surface as Graphics;
                RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);

                Rectangle clipRect = ChartRenderer.ToRectangle(this.Element.View.GetArea<CartesianArea>().AreaModel.PlotArea.LayoutSlot);
                clipRect.Offset((int)this.ViewportOffsetX, (int)this.ViewportOffsetY);
                graphics.SetClip(clipRect);

                GraphicsPath path = new GraphicsPath();
                path.AddLine(rect.Location, new PointF(rect.Right, rect.Bottom));

                BorderPrimitiveImpl border = new BorderPrimitiveImpl(this.Element, null);
                border.PaintBorder(radGraphics, null, path, rect);

                rect.Size = graphics.MeasureString(this.Element.Label, this.Element.Font);
                rect.Offset(this.Element.PositonOffset.Width + 1, this.Element.PositonOffset.Height + 1);

                TextParams tp = new TextParams();
                tp.font = this.Element.Font;
                tp.foreColor = this.Element.ForeColor;
                tp.paintingRectangle = rect;
                tp.text = this.Element.Label;

                FillPrimitiveImpl fill = new FillPrimitiveImpl(this.Element, null);
                fill.PaintFill(radGraphics, null, rect);
            
                TextPrimitiveHtmlImpl text = new TextPrimitiveHtmlImpl();
                text.PaintPrimitive(radGraphics, 0f, new SizeF(1f, 1f), tp);
            }
        }
Completed
Last Updated: 03 Jan 2017 12:58 by ADMIN
To reproduce:

private void RadChartView1_LabelFormatting(object sender, ChartViewLabelFormattingEventArgs e)
{
    var dataPoint = e.LabelElement.DataPoint as CategoricalDataPoint;
    if (dataPoint != null)
    {
         e.LabelElement.IsVisible = false;
    }
}

Workaround:
private void RadChartView1_LabelFormatting(object sender, ChartViewLabelFormattingEventArgs e)
{
    var dataPoint = e.LabelElement.DataPoint as CategoricalDataPoint;
    if (dataPoint != null)
    {
        e.LabelElement.Text = "";
    
    }
}


Completed
Last Updated: 25 May 2017 13:24 by ADMIN
How to reproduce: explicitly set the border color of the series

Workaround:
public partial class Form1 : Form
{
    private RangeSelectorViewElement chartElement;

    public Form1()
    {
        InitializeComponent();

        LineSeries lineSeries = new LineSeries();
        lineSeries.Name = "Line";
        lineSeries.BorderColor = Color.Green;
        lineSeries.DataPoints.Add(new CategoricalDataPoint(20, "Jan"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(22, "Apr"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(12, "Jul"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(19, "Oct"));
        this.radChartView1.Series.Add(lineSeries);

        this.chartElement = this.radRangeSelector1.RangeSelectorElement.AssociatedElement as RangeSelectorViewElement;
        this.chartElement.SeriesInitialized += ChartElement_SeriesInitialized;
    }

    private void ChartElement_SeriesInitialized(object sender, SeriesInitializedEventArgs e)
    {
        if (e.Series.Name == "Line")
        {
            e.Series.BorderColor = this.radChartView1.Series.Where(s => s.Name == "Line").First().BorderColor;
        }
    }
}
Unplanned
Last Updated: 15 Jun 2017 12:41 by ADMIN
ADMIN
Created by: Dimitar
Comments: 0
Category: ChartView
Type: Feature Request
2

			
Declined
Last Updated: 15 Aug 2017 13:11 by ADMIN
Use LogarithmicAxis and set the Minimum to 0.1

Workaround is availble in the atched project.
Completed
Last Updated: 09 Nov 2016 08:18 by ADMIN
How to reproduce:
Dim table As New DataTable()
table.Columns.Add("Name", GetType(String))
table.Columns.Add("X", GetType(Integer))
 
For i As Integer = 0 To 99
    table.Rows.Add($"User {i}", i)
Next
 
Dim series As New BarSeries()
series.DataSource = table
series.CategoryMember = "Name"
series.ValueMember = "X"
 
RadChartView1.Series.Add(series)
 
CType(RadChartView1.Area, CartesianArea).Orientation = Orientation.Horizontal
         
Dim panZoomController As New ChartPanZoomController()
panZoomController.PanZoomMode = ChartPanZoomMode.Vertical
RadChartView1.Controllers.Add(panZoomController)
 
RadChartView1.Zoom(1, 8)

Workaround: create a custom ChartPanZoomController
Dim panZoomController As New MyChartPanZoomController()
panZoomController.PanZoomMode = ChartPanZoomMode.Vertical
RadChartView1.Controllers.Add(panZoomController)

Public Class MyChartPanZoomController
    Inherits ChartPanZoomController

    Protected Overrides Function OnMouseMove(e As MouseEventArgs) As ActionResult

        Dim cartesianArea As CartesianArea = TryCast(Me.Area, CartesianArea)
        If cartesianArea Is Nothing Then
            Return MyBase.OnMouseMove(e)
        End If

        Dim panPoint As Point? = Me.GetType().BaseType.GetField("panPoint", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me)

        If e.Button = MouseButtons.Left AndAlso panPoint.HasValue Then
            Dim offsetX As Double = Me.GetType().BaseType.GetField("offsetX", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me)

            Dim currentOffsetX As Double = offsetX
            Dim defaultAxis As Axis = If(cartesianArea.Orientation = Orientation.Horizontal,
                                         Me.Area.GetType().GetMethod("GetDefaultFirstAxis", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me.Area, New Object() {}),
                                         Me.Area.GetType().GetMethod("GetDefaultSecondAxis", BindingFlags.Instance Or BindingFlags.NonPublic).Invoke(Me.Area, New Object() {}))

            If Me.PanZoomMode = ChartPanZoomMode.Horizontal OrElse Me.PanZoomMode = ChartPanZoomMode.Both Then
                currentOffsetX += (panPoint.Value.X - e.Location.X) * -1

                If currentOffsetX > 0 Then
                    currentOffsetX = 0
                End If

                If currentOffsetX < defaultAxis.Model.LayoutSlot.Width * (DirectCast(cartesianArea.View, IChartView).ZoomWidth - 1) Then
                    currentOffsetX = -defaultAxis.Model.LayoutSlot.Width * (DirectCast(cartesianArea.View, IChartView).ZoomWidth - 1)
                End If
            End If

            Dim offsetY As Double = Me.GetType().BaseType.GetField("offsetY", BindingFlags.Instance Or BindingFlags.NonPublic).GetValue(Me)
            Dim currentOffsetY As Double = offsetY
            If Me.PanZoomMode = ChartPanZoomMode.Vertical OrElse Me.PanZoomMode = ChartPanZoomMode.Both Then
                currentOffsetY += (panPoint.Value.Y - e.Location.Y) * -1

                If currentOffsetY > 0 Then
                    currentOffsetY = 0
                End If

                If currentOffsetY < -defaultAxis.Model.LayoutSlot.Height * (DirectCast(cartesianArea.View, IChartView).ZoomHeight - 1) Then
                    currentOffsetY = -defaultAxis.Model.LayoutSlot.Height * (DirectCast(cartesianArea.View, IChartView).ZoomHeight - 1)
                End If
            End If

            cartesianArea.View.Pan(currentOffsetX, currentOffsetY)
        End If

        Return Controller.Empty

    End Function

End Class
Unplanned
Last Updated: 30 Apr 2018 10:46 by ADMIN
Created by: promat
Comments: 1
Category: ChartView
Type: Feature Request
2
It would be great to be able to generate Box Plot graphics, both in the RadCharView control and in the Report.
Completed
Last Updated: 18 Jun 2018 14:35 by Nathan
ADMIN
Created by: Hristo
Comments: 5
Category: ChartView
Type: Feature Request
2
The new controller should allow lasso selection of data points without zooming the view port.
Unplanned
Last Updated: 16 Nov 2017 11:41 by ADMIN
When combining scalebreaks and series stacking, the rendered chart does not match the data. 

See attached solution: The bar of the category "1/2016" has a length of 105 (as indicated by the tooltips) -- but the corresponding axis labeling shows a value of 37.  The scalebreak is off too (probably matching the wrong axis).
Unplanned
Last Updated: 11 Jul 2016 08:40 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: ChartView
Type: Feature Request
2
Note: when you apply a palette the series doesn't have hover and selection indication.
Completed
Last Updated: 12 Feb 2015 13:36 by ADMIN
Steps to reproduce:
1. Add chart to a form.
2. Add two bar series with CombineMode set to Stack100
3. Add two data points to the series with values 0.0 and identical category
4. Run the project an you will see an exception.
Declined
Last Updated: 09 Jun 2015 04:34 by ADMIN
ChartLegendElement is not able to wrap the LegendItems


Completed
Last Updated: 10 Feb 2015 12:54 by ADMIN
Add RightToLeft support in DrillDownNavigator.
Declined
Last Updated: 28 Dec 2016 10:52 by ADMIN
ADMIN
Created by: Peter
Comments: 3
Category: ChartView
Type: Feature Request
2
The Line Series cannot be clicked/selected and cannot be used in DrillDown scenarios.
Completed
Last Updated: 04 Feb 2015 14:32 by ADMIN
ADMIN
Created by: Ivan Petrov
Comments: 0
Category: ChartView
Type: Feature Request
2
Add Scatter area series support for RadChartView.
Completed
Last Updated: 03 Feb 2015 14:02 by ADMIN
Currently only axes labels can be rotated. There should be a way to rotate series labels as well.

Resolution:

Set the LabelRotationAngle property of the series to preferred angle. 
Completed
Last Updated: 03 Feb 2015 16:06 by ADMIN
Introduce mechanism that will allow the vertical axis to appear at a certain position regardless of the size of its labels. For reference see Stock Series \ Indicators example.