查找当前视口的最大/最小值

时间:2013-09-10 18:36:07

标签: wpf xaml telerik rad-controls

问题:如何使用DateTimeCategoricalAxis找到RadCartesianChart当前视口的最大和最小x轴值?

我可以轻松找到数据集的最大/最小值,如果我使用DateTimeContinousAxis (不幸的是不是选项),我可以简单地使用{{3} }和ActualRange。但是使用DateTimeCategoricalAxis是一个完全不同的故事,因为我无法在当前视口中准确找到数据点。我甚至尝试使用ActualVisibleRange但无济于事。更不用说,PlotAreaClip没有考虑缩放尺寸,这就成了一个问题。

任何帮助都将非常感谢!


以下是我的代码的简化版本:

XAML:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <telerik:RadCartesianChart ZoomChanged="Zooming">

        <telerik:RadCartesianChart.Behaviors>
           <telerik:ChartPanAndZoomBehavior DragMode="Pan" 
                                             PanMode="Both" 
                                             ZoomMode="None" />
        </telerik:RadCartesianChart.Behaviors>

        <telerik:RadCartesianChart.Series>
            <telerik:OhlcSeries ItemsSource="{Binding Bars}" 
                                OpenBinding="Open"
                                HighBinding="High"
                                LowBinding="Low"
                                CloseBinding="Close"
                                CategoryBinding="Date">
            </telerik:OhlcSeries>
         </telerik:RadCartesianChart.Series>

        <telerik:RadCartesianChart.HorizontalAxis>
            <telerik:DateTimeCategoricalAxis DateTimeComponent="Ticks" 
                                             ShowLabels="False"
                                             PlotMode="OnTicks" 
                                             MajorTickInterval="100">
            </telerik:DateTimeCategoricalAxis>
        </telerik:RadCartesianChart.HorizontalAxis>

        <telerik:RadCartesianChart.VerticalAxis>
            <telerik:LinearAxis HorizontalLocation="Right" 
                                RangeExtendDirection="Both"
                                Minimum="{Binding PriceMinimum, Mode=OneWay}"
                                Maximum="{Binding PriceMaximum, Mode=OneWay}"
                                MajorStep="{Binding PriceMajorStep, Mode=OneWay}" />
         </telerik:RadCartesianChart.VerticalAxis>

        <telerik:RadCartesianChart.Grid>
            <telerik:CartesianChartGrid MajorXLinesRenderMode="All" 
                                        MajorLinesVisibility="XY" />
        </telerik:RadCartesianChart.Grid>

    </telerik:RadCartesianChart>
</Grid>
</UserControl>

背后的代码:

public void Zooming(object sender, ChartZoomChangedEventArgs e)
    {
        RadCartesianChart chart = sender as RadCartesianChart;
        if (chart != null)
        {
            //PlotAreaClip.Location.X (PlotAreaClip.X also works) to get left side of clip
            //PlotAreaClip.Right to get right side of clip
            DataTuple dtMin = chart.ConvertPointToData(new Point(chart.PlotAreaClip.Location.X - Math.Abs(chart.PanOffset), chart.PlotAreaClip.Y), chart.HorizontalAxis, chart.VerticalAxis);
            DataTuple dtMax = chart.ConvertPointToData(new Point(chart.PlotAreaClip.Right - Math.Abs(chart.PanOffset), chart.PlotAreaClip.Y), chart.HorizontalAxis, chart.VerticalAxis);
            object xMin = dtMin.FirstValue;
            object xMax = dtMax.FirstValue;
            //these numbers are VERY inconsistent, especially when you zoom in!
        }
    }

可以找到所提到的Telerik控件PlotAreaClip

如果有人有任何建议,我将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:2)

在做了一些挖掘后,我发现这个thread有以下解决方案:

private DataPoint[] FindFirstLastVisiblePoints(CategoricalSeries series)
{
    DataPoint firstPoint = null;
    DataPoint lastPoint = null;
    RadRect plotArea = this.radChart1.PlotAreaClip;

    foreach (DataPoint point in series.DataPoints)
    {
        if (point.LayoutSlot.IntersectsWith(plotArea))
        {
            if (firstPoint == null)
            {
                firstPoint = point;
            }
            lastPoint = point;
        }
    }

    return new DataPoint[] { firstPoint, lastPoint };
}

基本上,此方法获取当前PlotAreaClip并返回当前ViewPort中的第一个和最后一个数据点。我真的希望将来能帮助别人!