2013-09-10 3 views
1

Вопрос: Как найти максимальное и минимальное значение оси X текущего окна просмотра RadCartesianChart с помощью DateTimeCategoricalAxis?Найти максимальные/минимальные значения текущего видового окна

я могу легко найти максимальные/минимальные значения набора данных и, если бы я был использовать DateTimeContinousAxis(к сожалению, не вариант), я мог бы просто использовать ActualRange и ActualVisibleRange. Однако использование 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.

Если у кого-нибудь есть предложения, я был бы очень признателен! Спасибо!

+0

Ваше последнее утверждение о том, что метод является многообещающим. Что не работает в этой части при работе с масштабированием и панорамированием? –

+0

@LeoLorenzoLuis Я тестировал и 'zoom' /' panoffset' больше не проблема. Спасибо! – Dom

ответ

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 и возвращает первый и последний Datapoint в текущем видовом. Я действительно надеюсь, что это поможет другим в будущем!