Search code examples
c#winformstelerik.net-4.8

Can I get the visible data points from a chart after zoom in in Telerik ChartView?


I have a telerik RadChartView that has some datas, my X axis is a DateTimeContinuousAxis and my Y axis is a LinearAxis. This RadChartView has a zoom button, that uses the LassoZoomController methods to make the zoom. I'm facing an issue to, after the zoom in or out, I want to get the visible points that the user can see in the zoom (ignoring the ones that are not visible in the zoom). Is there a way to get only the visible points in the chart after the zoom?

In the code bellow, I want to make a verification to add the dateTime on the list only if it's visible inside my radChartView

var categoricalDataPoints = radChartView.Series.Where(serie => serie.IsVisible).SelectMany(serie => serie.DataPoints)
    .OfType<CategoricalDataPoint>().ToList();

var visibleDateTimes = new List<DateTime>();

foreach (var categoricalDataPoint in categoricalDataPoints)
{
    if (categoricalDataPoint.Category is DateTime dateTime)
    {
        visibleDateTimes.Add(dateTime);
    }
}

I've tried to get the first axis and parse it to DateTimeContinuousAxis and use the ActualRange but this range is considering all the dateTimes of the chart, not only the visibles:

var categoricalDataPoints = radChartView.Series.Where(serie => serie.IsVisible).SelectMany(serie => serie.DataPoints)
    .OfType<CategoricalDataPoint>().ToList();

var visibleDateTimes = new List<DateTime>();

if (radChartView.Axes[0] is DateTimeContinuousAxis dateTimeContinuousAxis)
{
    foreach (var categoricalDataPoint in categoricalDataPoints)
    {
        if (categoricalDataPoint.Category is DateTime dateTime)
        {
            if (dateTime >= dateTimeContinuousAxis.ActualRange.Minimum && dateTime <= dateTimeContinuousAxis.ActualRange.Maximum)
            {
                visibleDateTimes.Add(dateTime);
            }
        }
    }
}


Solution

  • Gabriel, I have prepared a sample code snippet demonstrating how to get the visible data points after pan/zoom operations are executed. The below screenshots illustrate the achieved result:

    enter image description here

    enter image description here

    enter image description here

        public partial class RadForm1 : Telerik.WinControls.UI.RadForm
    {
        public RadForm1()
        {
            InitializeComponent();
    
            LineSeries lineSeries = new LineSeries();
            lineSeries.ShowLabels = true;
            lineSeries.PointSize = new SizeF(8, 8);
            for (int i = 0; i < 10; i++)
            {
                lineSeries.DataPoints.Add(new CategoricalDataPoint(6 + i * i, DateTime.Now.AddDays(i)));
            }
            DateTimeContinuousAxis continuousAxis = new DateTimeContinuousAxis();
            continuousAxis.PlotMode = AxisPlotMode.BetweenTicks;
            continuousAxis.LabelFormat = "{0:d}";
            //First assign the axis to the VerticalAxis property and then add the series to the chart
            lineSeries.HorizontalAxis = continuousAxis;
            radChartView1.Series.Add(lineSeries);
    
            this.radChartView1.ShowPanZoom = true;
            this.radChartView1.View.ZoomChanged += View_ZoomChanged;
            this.radChartView1.View.PanChanged += View_PanChanged;
        }
    
        private void View_ZoomChanged(object sender, EventArgs e)
        {
            GetVisiblePoints();
        }
    
        private void View_PanChanged(object sender, EventArgs e)
        {
            GetVisiblePoints();
        }
    
        public void GetVisiblePoints()
        {
            List<CategoricalDataPoint> visiblePoints = new List<CategoricalDataPoint>();
            IChartView view = ((IChartView)this.radChartView1.View);
            foreach (ChartSeries series in this.radChartView1.Series)
            {
                foreach (var dp in series.DataPoints)
                {
                    CategoricalDataPoint cdp = (CategoricalDataPoint)dp;
                    if (CheckIfDataPointIsVisible(view, cdp))
                    { 
                        visiblePoints.Add(cdp); 
                    }
                }
            }
    
            foreach (CategoricalDataPoint dp in visiblePoints)
            {
                Console.WriteLine(dp.Value +" >> "+dp.Category);
            }
        }
    
        private bool CheckIfDataPointIsVisible(IChartView view, CategoricalDataPoint cdp)
        {
            double width = ((ChartSeries)cdp.Presenter).Axes[1].Model.LayoutSlot.Width;
            RadRect viewport = new RadRect(-view.PlotOriginX + width, -view.PlotOriginY, view.ViewportWidth, view.ViewportHeight);
            return viewport.IntersectsWith(cdp.LayoutSlot);
        }
    
        private void radButton1_Click(object sender, EventArgs e)
        {
            GetVisiblePoints();
        }
    }