Переместить расположение меток осей на диаграмме набора инструментов WPF - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть диаграмма, все работает нормально, за исключением того, что мне нужно, чтобы метки оси X "следовали" за пересечением нуля по оси Y.

enter image description here

Я играл с полями меток и могу сместить метку влево или вправо от линии сетки

<DVC:LinearAxis.AxisLabelStyle>
                <Style TargetType="{x:Type DVC:AxisLabel}">
                    <Setter Property="Margin" Value="25,0,0,0" />
                </Style>
            </DVC:LinearAxis.AxisLabelStyle>

Я понятия не имею, как переместить метку вверх по диаграмме, чтобы она появлялась посередине. Я буду привязываться к значению для определения точного местоположения, но я даже не могу понять, как переместить метку в вертикальной плоскости.

Любая помощь или указатели очень ценятся.

Спасибо.

1 Ответ

0 голосов
/ 04 сентября 2018

После множества проб и ошибок и чтения статей я наконец-то собрал действительно простое и элегантное решение.

Я связал свойство поля AxisLabel с ActualHeight области диаграммы и использовал MultiValueConverter для создания правильных значений полей.

XAML

<DVC:LinearAxis.AxisLabelStyle>
    <Style TargetType="{x:Type DVC:AxisLabel}">
        <Setter Property="Margin">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource MarginConverter}">
                    <Binding Path="ActualHeight"
                        RelativeSource="{RelativeSource AncestorType={x:Type primitives:EdgePanel}}" />
                    <Binding Path="DataContext.ChartRange" RelativeSource="{RelativeSource FindAncestor, 
                        AncestorType={x:Type DVC:LinearAxis}}" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</DVC:LinearAxis.AxisLabelStyle>

MarginConverter.cs

public class MarginConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var height = 0d;
            var chartHeight = (double) values[0];
            var range = (Range<double>) values[1];

            if (range.HasData)
            {
                if (range.Minimum > 0)
                {
                    // Set labels to bottom
                    height = 0;
                }
                else if (range.Maximum < 0)
                {
                    // Set labels to top
                    height = -chartHeight;
                }
                else
                {
                    var rangeHeight = range.Maximum - range.Minimum;
                    var pointsPerHeight = chartHeight / rangeHeight;
                    height = range.Minimum * pointsPerHeight;
                }
            }

            return new Thickness(25, height, 0, 0);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

    }

Диапазон - это максимальное и минимальное значения y, когда я рисую график и затем привязываюсь к свойству на виртуальной машине.

Это удивительно элегантное решение для того, что, как я думал, будет довольно хакерским. По мере изменения размера представления метки перемещаются с новыми размерами.

...