WPF绘制折线图

绘制折线图的函数如下:

 protected void DrawingLine(double drawwidth, double drawheight,double[] value,DateTime[] datetime)
        {
            double farTop = 10;
            double farBottom = 10;
            double farLeft = 10;
            double farRight = 10;

            double useHeight = drawheight - farTop - farBottom;
            double useWidth = drawwidth - farLeft - farRight;

            LineGeometry myLineX = new LineGeometry();
            myLineX.StartPoint = new Point(farLeft, useHeight+farTop);
            myLineX.EndPoint = new Point(useWidth, useHeight + farTop);

            Path myPathX = new Path();
            myPathX.Stroke = Brushes.Black;
            myPathX.StrokeThickness = 2;
            myPathX.Data = myLineX;

            gridParent.Children.Add(myPathX);

            LineGeometry myLineY = new LineGeometry();
            myLineY.StartPoint = new Point(farLeft, farTop);
            myLineY.EndPoint = new Point(farLeft, useHeight + farTop);

            Path myPathY = new Path();
            myPathY.Stroke = Brushes.Black;
            myPathY.StrokeThickness = 2;
            myPathY.Data = myLineY;

            gridParent.Children.Add(myPathY);

          double[] dtTime=new double[5];
          double maxTime = datetime[0].Ticks; ;
          double minTime = datetime[0].Ticks; ;
          for (int i = 0; i < datetime.Length; i++)
          {
              dtTime[i] = datetime[i].Ticks;
              if (dtTime[i] < minTime)
              {
                  minTime = dtTime[i];
              }
              if (dtTime[i] > maxTime)
              {
                  maxTime = dtTime[i];
              }
          }
          double maxValue = value[0];
          double minValue = value[0];
          for (int i = 0; i < value.Length; i++)
          {
              if (value[i] < minValue)
              {
                  minValue = value[i];
              }
              if (value[i] > maxValue)
              {
                  maxValue = value[i];
              }
          }

 

          double everVlaue = (useHeight - 10) / (maxValue - minValue);   //每一个刻度数值用everVlaue个页面px像素来表示;
            double everTime = (useWidth-40) / (maxTime - minTime);

            Point pt1 = new Point(farLeft + 10, useHeight - 10+farTop);
            Point[] values = new Point[5];
            values[0]=pt1;
            for (int i = 1; i < value.Length; i++)
            {
                Point pt = new Point(pt1.X + (dtTime[i] - dtTime[0]) * everTime, pt1.Y - (value[i] - value[0]) * everVlaue);
                values[i] = pt;
            }

            StreamGeometry geometry = new StreamGeometry();
         
            using (StreamGeometryContext ctx = geometry.Open())
            {
                ctx.BeginFigure(values[0], true, false);
                EllipseGeometry ellipseOne = new EllipseGeometry();
                ellipseOne.Center = values[0];
                ellipseOne.RadiusX = 3;
                ellipseOne.RadiusY = 3;

                Path myPathellipseOne = new Path();
                myPathellipseOne.Stroke = Brushes.Black;
                myPathellipseOne.StrokeThickness = 1;
                myPathellipseOne.Fill = Brushes.LightBlue;
                myPathellipseOne.Data = ellipseOne;
                myPathellipseOne.ToolTip = values[0].Y.ToString();
                gridParent.Children.Add(myPathellipseOne);
                for (int i = 1; i < values.Length; i++)
                {
                    ctx.LineTo(values[i], true, false);
                    EllipseGeometry ellipse = new EllipseGeometry();
                    ellipse.Center = values[i];
                    ellipse.RadiusX = 3;
                    ellipse.RadiusY = 3;
                
                    Path myPathellipse = new Path();
                    myPathellipse.Stroke = Brushes.Black;
                    myPathellipse.StrokeThickness = 1;
                    myPathellipse.Fill = Brushes.LightBlue;
                    myPathellipse.Data = ellipse;
                    myPathellipse.ToolTip = value[i].ToString() + " " + datetime[i].ToString();
                    gridParent.Children.Add(myPathellipse);
                }
              
            }
            geometry.FillRule = FillRule.Nonzero;
            geometry.Freeze();
            Path myPath = new Path();
            myPath.Stroke = Brushes.Red;
            myPath.StrokeThickness = 1;
            myPath.Data = geometry;
            gridParent.Children.Add(myPath);
        }

用以下函数调用绘制曲线函数——传入要绘制的数值:

  void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            double drawheight = (this.Height) * 0.5-10;
            double drawwidth = this.Width;

            double[] value = new double[5] {1,3,6,8,5};
            DateTime[] datetime = new DateTime[5] { DateTime.Parse("2012-6-30 10:20"),
            DateTime.Parse("2012-6-30 10:30"),DateTime.Parse("2012-6-30 10:40"),
            DateTime.Parse("2012-6-30 10:50"),DateTime.Parse("2012-6-30 11:00")
            };

            DrawingLine(drawwidth, drawheight,value,datetime);
        }

 

### 创建和自定义WPF折线图控件 #### 使用原生WPF功能构建折线图WPF中,可以通过`Canvas`板来自定义绘制折线图并生成图片[^2]。为了实现这一目标,通常会利用`Polyline`类来表示多段线图形,并将其放置于`Canvas`容器内。 ```xml <Window x:Class="WpfApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Title="MainWindow"> <Grid> <!-- 定义一个用于绘图的 Canvas --> <Canvas Name="canvasChart"/> </Grid> </Window> ``` 接着,在后台代码逻辑里动态添加`Polyline`实例到指定位置: ```csharp using System.Windows; using System.Windows.Media; using System.Windows.Shapes; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); // 初始化 Polyline 对象 var polyline = new Polyline { StrokeThickness = 2, Stroke = Brushes.BlueViolet, FillRule = FillRule.EvenOdd }; // 添加一系列点形成折线路径 foreach (var point in GetDataPoints()) { // 假设GetDataPoints返回Point集合 polyline.Points.Add(point); } // 将 Polyline 加入至 Canvas 中 canvasChart.Children.Add(polyline); } } ``` 此方式允许开发者灵活控制每条线的颜色、粗细以及标签等特性[^3]。 #### 利用第三方库简化开发流程 对于更复杂的需求或希望减少工作量的情况而言,采用成熟的第三方组件可能是更好的选择。例如LiveCharts就是一个流行的选择之一,它提供了简单易用API接口的同时还支持多种类型的图表展示形式。 安装NuGet包后即可快速上手使用: ```powershell Install-Package LiveCharts.Wpf ``` 随后可以在XAML文件中声明所需图表类型: ```xml <Window ... xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"> <lvc:CartesianChart Series="{Binding SeriesCollection}"> <lvc:CartesianChart.AxisY> <lvc:Axis LabelFormatter="{Binding YFormatter}"></lvc:Axis> </lvc:CartesianChart.AxisY> <lvc:CartesianChart.AxisX> <lvc:Axis Labels="{Binding Labels}" ></lvc:Axis> </lcv:CartesianChart.AxisX> </lvc:CartesianChart> </Window> ``` 通过绑定数据源给Series属性完成实际的数据呈现过程。 #### 参考开源项目获取灵感 如果想要深入了解具体实现细节,则可以从现有成功案例中学起。GitHub上的[WPFDevelopers](https://github.com/yanjinhuagood/WPFDevelopers.git)[^5]是一个很好的起点,该项目不仅包含了丰富的UI组件示例还包括了完整的解决方案文档供参考学习。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值