Разрешить пользователю создавать серии линий на графике wpf, нажав на график - PullRequest
1 голос
/ 31 января 2011

У меня есть диаграмма WPF, в которой в настоящее время отображается серия областей. Мне нужно предоставить пользователю возможность щелкнуть диаграмму и добавить новую точку для ряда линий. Проблема в том, что я не могу найти способ конвертировать точку из MouseButtonEventArgs в LineDataPoint.

private void chtPowerFlowMap_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Point p = e.GetPosition(chtPowerFlowMap);

        points.Add(p); //Issue here is this will return a point in screen coordinates and not in chart coordinates

        ls.ItemsSource = points; //ls is an existing lineseries and points is a List<Point> object

        chtPowerFlowMap.Series.Add(ls);
    }

Заранее спасибо.

1 Ответ

1 голос
/ 31 января 2011

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

MainWindows.xaml

<chart:Chart x:Name="chart" MouseLeftButtonDown="Chart_MouseLeftButtonDown">
        <chart:LineSeries ItemsSource="{Binding}" x:Name="lineSeries"
                          DependentValuePath="Value"
                          IndependentValuePath="Date"/>
</chart:Chart>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    private ObservableCollection<Item> items;

    public MainWindow()
    {
        InitializeComponent();
        Random rd = new Random();

        items = new ObservableCollection<Item>(
                Enumerable.Range(0, 10)
                .Select(i => new Item
                {
                    Date = DateTime.Now.AddMonths(i - 10),
                    Value = rd.Next(10,50)
                }));
        this.DataContext = items;
    }

    public class Item
    {
        public DateTime Date { get; set; }
        public double Value { get; set; }
    }

    private void Chart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var p = Mouse.GetPosition(this.lineSeries);
        //ranges in the real values
        var left = items.Min(i => i.Date);
        var right = items.Max(i => i.Date);
        var top = items.Max(i => i.Value);
        var bottom = items.Min(i => i.Value);

        var hRange = right - left;
        var vRange = top - bottom;

        //ranges in the pixels
        var width = this.lineSeries.ActualWidth;
        var height = this.lineSeries.ActualHeight;

        //from the pixels to the real value
        var currentX = left + TimeSpan.FromTicks((long)(hRange.Ticks * p.X / width));
        var currentY = top - vRange * p.Y / height;

        this.items.Add(new Item { Date = currentX, Value = currentY });
    }
}
...