Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
允许用户通过单击wpf图表在wpf图表上创建线条系列_Wpf_Charts_Toolkit - Fatal编程技术网

允许用户通过单击wpf图表在wpf图表上创建线条系列

允许用户通过单击wpf图表在wpf图表上创建线条系列,wpf,charts,toolkit,Wpf,Charts,Toolkit,我有一个WPF图表,当前显示一个面积系列。我需要允许用户能够单击图表并为直线系列添加新点。我遇到的问题是,我似乎找不到将点从鼠标按钮Ventargs转换为LineDataPoint的方法 private void chtPowerFlowMap_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Point p = e.GetPosition(chtPowerFlowMap);

我有一个WPF图表,当前显示一个面积系列。我需要允许用户能够单击图表并为直线系列添加新点。我遇到的问题是,我似乎找不到将点从鼠标按钮Ventargs转换为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);
    }
private void-chtPowerFlowMap\u预览鼠标左键向下(对象发送器,鼠标按钮ventargs e)
{
点p=e.GetPosition(chtPowerFlowMap);
points.Add(p);//这里的问题是,这将返回屏幕坐标中的点,而不是图表坐标中的点
ls.ItemsSource=points;//ls是现有的线系列,而points是列表对象
chtPowerFlowMap.Series.Add(ls);
}

提前感谢。

这里有一个完整的解决方案。你可以点击图表上的任何地方,在那个地方会有一个新的点

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 });
    }
}
公共部分类主窗口:窗口
{
私人可观测收集项目;
公共主窗口()
{
初始化组件();
随机rd=新随机();
items=新的ObservableCollection(
可枚举范围(0,10)
.选择(i=>新项目
{
Date=DateTime.Now.AddMonths(i-10),
值=rd.Next(10,50)
}));
this.DataContext=项目;
}
公共类项目
{
公共日期时间日期{get;set;}
公共双值{get;set;}
}
私有无效图表\u MouseLeftButtonDown(对象发送器,MouseButtonEventArgs e)
{
var p=Mouse.GetPosition(this.lineSeries);
//实际值的范围
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=右-左;
var vRange=顶部-底部;
//像素范围
var width=this.lineSeries.ActualWidth;
变量高度=this.lineSeries.ActualHeight;
//从像素到实际值
var currentX=左+时间跨度(从刻度((长)(hRange.Ticks*p.X/宽度));
var currentY=顶部-vRange*p.Y/高度;
this.items.Add(新项{Date=currentX,Value=currentY});
}
}

这是一个完整的解决方案。你可以点击图表上的任何地方,在那个地方会有一个新的点

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 });
    }
}
公共部分类主窗口:窗口
{
私人可观测收集项目;
公共主窗口()
{
初始化组件();
随机rd=新随机();
items=新的ObservableCollection(
可枚举范围(0,10)
.选择(i=>新项目
{
Date=DateTime.Now.AddMonths(i-10),
值=rd.Next(10,50)
}));
this.DataContext=项目;
}
公共类项目
{
公共日期时间日期{get;set;}
公共双值{get;set;}
}
私有无效图表\u MouseLeftButtonDown(对象发送器,MouseButtonEventArgs e)
{
var p=Mouse.GetPosition(this.lineSeries);
//实际值的范围
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=右-左;
var vRange=顶部-底部;
//像素范围
var width=this.lineSeries.ActualWidth;
变量高度=this.lineSeries.ActualHeight;
//从像素到实际值
var currentX=左+时间跨度(从刻度((长)(hRange.Ticks*p.X/宽度));
var currentY=顶部-vRange*p.Y/高度;
this.items.Add(新项{Date=currentX,Value=currentY});
}
}

如果将日期用作X轴,则会变得更加复杂。它需要关于点的实际宽度、实际高度、数据x范围、数据y范围和坐标的信息。如果我有时间,我会尝试实现类似的东西。如果使用日期作为X轴,它会变得更加复杂。它需要关于点的实际宽度、实际高度、数据x范围、数据y范围和坐标的信息。如果我有时间,我会尝试实现类似的东西。酷…工作得很好。如果图表工具包能够基于一组轴将鼠标点转换为图表值,那就太好了。再次感谢。只是好奇,为什么你得到的是与系列相关的点而不是图表?@Chris因为wpf图表是系列和轴的组合,因此我从轴的真正开始,从坐标原点测量。为了公正起见,起初我试图使用整个图表,但在发射和测试之后,我改变了控制。另外,这个例子对系列之外的点击做出响应,可以通过比较左侧和底部的值与系列的边框来纠正。酷…工作得很好。如果图表工具包能够基于一组轴将鼠标点转换为图表值,那就太好了。再次感谢。只是好奇,为什么你得到的是与系列相关的点而不是图表?@Chris因为wpf图表是系列和轴的组合,因此我从轴的真正开始,从坐标原点测量。为了公正起见,起初我试图使用整个图表,但在发射和测试之后,我改变了控制。此示例还响应序列外部的单击,可以通过将左侧和底部值与序列的边框进行比较来更正。