Подтвердить что ты не робот

Позиционирование метки оси в DateTimeAxis

В настоящий момент у меня есть ось времени даты, в которой дата совпадает с точками, есть ли в любом случае, чтобы эта дата отображалась в центре, например, на гистограмме.

Chart Img

<Style x:Key="DateTimeAxisLabelStyle2" TargetType="chartingToolkit:DateTimeAxisLabel">
    <Setter Property="DaysIntervalStringFormat" Value="{}{0:dd-MMM}" />
    <Setter Property="HoursIntervalStringFormat" Value="{}{0:hh:mm tt}" />
    <!--<Setter Property="RenderTransformOrigin" Value="1,0.5" />
    <Setter Property="RenderTransform">
       <Setter.Value>
          <RotateTransform Angle="-45" />
       </Setter.Value>
    </Setter>-->
   <!--<Setter Property="Margin" Value="30,0,-10,0" />-->
</Style>

<chartingToolkit:DateTimeAxis IntervalType="Days"
                               Interval="1"
                               Minimum="{Binding StartDate}"
                               Maximum="{Binding EndDate}"
                               Orientation="X"
                               VerticalContentAlignment="Center"
                               Title="Day"
                               AxisLabelStyle="{StaticResource DateTimeAxisLabelStyle2}" />

Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

Вот что я получил:

XAML:

<Window.Resources>
    <Style x:Key="DateTimeAxisLabelStyle1" TargetType="{x:Type chartingToolkit:DateTimeAxisLabel}">
        <Setter Property="DaysIntervalStringFormat" Value="{}{0:dd-MMM}"></Setter>
        <Setter Property="RenderTransformOrigin" Value="0.80,0.20"></Setter>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform Angle="-90"></RotateTransform>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <chartingToolkit:Chart Margin="0" Title="Chart Title">
        <chartingToolkit:Chart.DataContext>
            <local:MyDataCollection/>
        </chartingToolkit:Chart.DataContext>
        <chartingToolkit:Chart.Axes>
            <chartingToolkit:DateTimeAxis Minimum="{Binding StartDate}" Maximum="{Binding EndDate}" Orientation="X" ShowGridLines="True" AxisLabelStyle="{DynamicResource DateTimeAxisLabelStyle1}"/>
        </chartingToolkit:Chart.Axes>
        <chartingToolkit:LineSeries DependentValuePath="Y" IndependentValuePath="X" ItemsSource="{Binding}"/>
    </chartingToolkit:Chart>
</Grid>

Диаграмма:

введите описание изображения здесь

Ответ 2

Вот что я сделал с помощью WPF Toolkit Source для справки.

Я создал пользовательский класс, полученный из DateTimeAxis, затем переопределив метод GetPlotAreaCoordinate. DateTimeAxis.Render() вызывает этот метод три раза с тем же самым списком значений "DateTime", один раз для MajorTickmarks, один раз для MinorTickmarks и один раз для метки даты. В списке отсутствовали незначительные отметки, поэтому метод фактически вызывался только дважды. Я просто держу список значений, которые были оценены, и предположим, что если он в списке уже сделал отметки и теперь выполняет этикетки.

class CustomDateTimeAxis : DateTimeAxis
{
    List<object> _valueList = new List<object>();
    UnitValue prevBaseValue;

    protected override UnitValue GetPlotAreaCoordinate(object value, Range<IComparable> currentRange, double length)
    {

        _valueList.Add(value);
        UnitValue baseValue = base.GetPlotAreaCoordinate(value, currentRange, length);


        int valueCount = _valueList.Count((x) => x.Equals(value));
        if (valueCount == 2)                       
            return new UnitValue(baseValue.Value + 27, baseValue.Unit);

        prevBaseValue = baseValue;
        return baseValue;

    }

    protected override void Render(Size availableSize)
    {
        base.Render(availableSize);
        _valueList.Clear();
    }

}

"27" - это просто номер, который я пытался опробовать. Возможно, вы захотите сыграть с этим, чтобы увидеть, что лучше всего подходит вам.

return new UnitValue(baseValue.Value + 27, baseValue.Unit);

Ответ 3

Я создал Margin-Converter:

    public class MarginConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var dateTimeAxis = values[0] as DateTimeAxis; ;
        var actualAxisLength = values[1] as double?;
        var actualMaximum = values[2] as DateTime?;
        var actualMinimum = values[3] as DateTime?;

        if (dateTimeAxis == null || 
            !dateTimeAxis.Interval.HasValue || 
            !actualAxisLength.HasValue || 
            !actualMaximum.HasValue || 
            !actualMinimum.HasValue)
            return null;

        double xMargin = 0;

        var interval = dateTimeAxis.Interval.Value;

        var timeSpan = actualMaximum.Value - actualMinimum.Value;
        var timeSpanInDays = timeSpan.TotalDays;

        if (dateTimeAxis.IntervalType == DateTimeIntervalType.Months)
        {
            xMargin = 30 * interval * actualAxisLength.Value / timeSpanInDays;
        }
        else if (dateTimeAxis.IntervalType == DateTimeIntervalType.Days)
        {
            xMargin = interval * actualAxisLength.Value / timeSpanInDays;
        }

        return new Thickness(xMargin, 10, 0, -30);
    }

    public object[] ConvertBack(object value, System.Type[] targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

назвал X-Axis SharedXAxis и использовал конвертер так:

<Setter Property="Margin">
<Setter.Value>
    <MultiBinding Converter="{StaticResource MarginConv}">
        <Binding ElementName="SharedXAxis"/>
        <Binding ElementName="SharedXAxis" Path="ActualWidth"/>
        <Binding ElementName="SharedXAxis" Path="ActualMaximum"/>
        <Binding ElementName="SharedXAxis" Path="ActualMinimum"/>
    </MultiBinding>
</Setter.Value>

Имо, это должно быть полной динамикой. Top- и нижние значения толщины маржинального преобразователя (в моем случае "10" и "-30"), а также нижнее значение заполнения самой диаграммы должны быть скорректированы, не знаю почему