C # WPF Telerik RadCartesianChart: форсировать постоянную длину осей, несмотря на наличие меток - PullRequest
0 голосов
/ 26 ноября 2018

Я создал очень простой график, подобный следующему:

<telerik:RadCartesianChart x:Name="chartMainCandleChart" Height="350" Width="620" VerticalAlignment="Top" HorizontalAlignment="Left" ZoomChanged="chartMainCandleChart_ZoomChanged" PanOffsetChanged="chartMainCandleChart_OffsetChanged" >
    <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:DateTimeCategoricalAxis SmartLabelsMode="SmartStep" IsStepRecalculationOnZoomEnabled="False" />
    </telerik:RadCartesianChart.HorizontalAxis>
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis HorizontalLocation="Right" SmartLabelsMode="SmartStep" IsStepRecalculationOnZoomEnabled="False"/>
    </telerik:RadCartesianChart.VerticalAxis>
    <telerik:CandlestickSeries x:Name="candleSeries" ItemsSource="{Binding SeriesCollection}" CategoryBinding="Timestamp" OpenBinding="Open" CloseBinding="Close" LowBinding="Low" HighBinding="High">
        <telerik:CandlestickSeries.DefaultVisualStyle>
            <Style TargetType="telerik:Candlestick">
                <Setter Property="StrokeThickness" Value="2" />
                <Setter Property="UpStroke" Value="GreenYellow"/>
                <Setter Property="DownStroke" Value="Red"/>
                <Setter Property="UpFill" Value="GreenYellow"/>
                <Setter Property="DownFill" Value="Red"/>
            </Style>
        </telerik:CandlestickSeries.DefaultVisualStyle>
    </telerik:CandlestickSeries>

    <telerik:RadCartesianChart.Behaviors>
        <telerik:ChartPanAndZoomBehavior x:Name="bvPanZoom" MouseWheelMode="ZoomHorizontally" DragMode="Pan" PanMode="Horizontal" ZoomMode="None" />
    </telerik:RadCartesianChart.Behaviors>

    <telerik:RadCartesianChart.Resources>
        <Style TargetType="telerik:PanZoomBar">
            <Setter Property="Visibility" Value="Collapsed"/>
        </Style>
    </telerik:RadCartesianChart.Resources>
</telerik:RadCartesianChart>

Я автоматически масштабирую его, используя эту функцию во время события OffsetChanged:

private void ScaleChartDynamically()
{
    var viewPortWidth = chartMainCandleChart.PlotAreaClip.Width;
    var xPixelsPerElem = viewPortWidth * chartMainCandleChart.Zoom.Width / SeriesCollection.Count;
    var notVisible = -chartMainCandleChart.PanOffset.X / xPixelsPerElem; // how many candles are invisible completely (on the left of viewport)
    var visible = viewPortWidth / xPixelsPerElem; // last partially visible in viewport
    var firstElem = (int)Math.Floor(notVisible) + 1; // index is zero based
    var lastElem = (int)Math.Ceiling(notVisible + visible);
    var noElements = lastElem - firstElem + 1;

    var visibleRange = SeriesCollection.Range(firstElem, noElements).SelectMany(ohlc => new[] { ohlc.Low, ohlc.High }).Select(hl => hl.ToDouble()).ToArray();
    if (visibleRange.Any())
    {
        var yAxis = (LinearAxis)chartMainCandleChart.VerticalAxis;
        yAxis.Minimum = visibleRange.Min();
        yAxis.Maximum = visibleRange.Max();
    }
}

При перетаскивании по x возникает следующая проблема-axis:

chart bug

Похоже, что проблема была решена здесь: https://www.telerik.com/forums/fixed-width-height-for-axis, но предоставленное решение не решает проблемувообще.

Я временно использую обходной путь, который принимает PlotAreaClip.Width один раз, на LeftMouseButtonClick, чтобы предотвратить «прыжки» при перетаскивании:

private double _plotAreaClipWidth;

private void chartMainCandleChart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    _plotAreaClipWidth = chartMainCandleChart.PlotAreaClip.Width;
}

Первая строка функции ScaleChartDynamically () теперь:

var viewPortWidth = _plotAreaClipWidth;

Итак, чтобы уточнить:

Я хочу удалить пробел, видимый на рисунке ниже, пробел меняется, что заставляет диаграмму «перепрыгивать» (снова вызывать событие) всякий раз, когдаPlotAreaClip. Ширина отличается.Другими словами, я хочу установить размер PlotAreaClip.Width (длина оси x) и сохранить метки, они должны быть обрезаны на обоих концах оси.Чтобы соответствовать моим общим требованиям, PlotAreaClip с осями должен охватывать всю область рендеринга элемента управления без искусственных промежутков для надписей.Баунти идет к человеку, который показывает мне, как это сделать.Чтобы понять, что я имею в виду, посмотрите на пример ниже.Посмотрите, как изменяется длина оси x при масштабировании / перетаскивании для размещения меток.Это является причиной проблемы, которая изменяет размер PlotAreaClip.Width и создает пустое пространство по сторонам диаграммы.Если вы посмотрите внимательно, то увидите, что та же проблема может быть видна и по оси y:

gap

zoom x-axis resize

...