【问题标题】:Find the Maximum/Minimum Values of Current Viewport查找当前视口的最大值/最小值
【发布时间】:2013-09-10 18:36:06
【问题描述】:

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

我可以轻松找到数据集的最大值/最小值,如果我要使用 DateTimeContinousAxis(很遗憾不是一个选项),我可以简单地使用 ActualRange 和 @987654324 @。然而,使用DateTimeCategoricalAxis 则完全不同,因为我无法准确地找到当前视口中的数据点。我什至尝试使用PlotAreaClip,但无济于事。更何况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 控件可以在here找到。

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

【问题讨论】:

  • 您最后一次声明该方法很有前途。处理缩放和平移偏移时,那部分有什么问题?
  • @LeoLorenzoLuis 我做了测试,zoom/panoffset 不再是问题。谢谢!

标签: wpf xaml telerik rad-controls


【解决方案1】:

经过一番挖掘,我找到了这个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 中的第一个和最后一个数据点。我真的希望这对以后的其他人有所帮助!

【讨论】:

    猜你喜欢
    • 2012-09-16
    • 2017-04-20
    • 2013-08-25
    • 2019-02-25
    • 1970-01-01
    • 2021-09-15
    • 2014-06-17
    • 2013-09-28
    • 2019-09-16
    相关资源
    最近更新 更多