Axis标签在DateTimeAxis中的定位

时间:2015-09-07 12:59:21

标签: c# wpf xaml charts data-visualization

目前我有一个日期时间轴,其中日期与点数一致,无论如何都要让这个日期出现在中心,例如条形图上。

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}" />

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

这是我得到的:

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>

图表:

enter image description here

答案 1 :(得分:0)

以下是我使用WPF Toolkit Source进行参考的内容。

我创建了一个派生自DateTimeAxis的自定义类,然后覆盖了&#34; GetPlotAreaCoordinate&#34;方法。 DateTimeAxis.Render()使用相同的&#34; DateTime&#34;列表调用该方法三次。值,一次用于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();
    }

}

&#34; 27&#34;只是我尝试的一个数字。您可能想要使用它来查看哪种方法最适合您。

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

答案 2 :(得分:0)

我创建了一个保证金转换器:

    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轴“ 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>

Imo,这应该是完全动态的。 边距转换器的厚度的最高值和最低值(在我的情况下为'10'和'-30')以及图表本身的填充最低值,我不希望这样做。不知道为什么。