本文将重点介绍 GDI 图表开发。 具体来说,我们将使用 LightningChart .NET 构建自定义 ViewXY 图表应用程序。 听起来有些复杂,这篇文章会引导您通过简单的方法来构建。
对于那些不太熟悉 GDI 图表开发术语的人来说,GDI 代表图形设备接口。 这是微软的遗留组件,用于创建图形并将其传输到终端设备。 例如,将图形对象传输到监视器。
什么是 GDI+?
Windows GDI+ 是专为 C 和 C++ 开发人员设计的面向对象的 API。 它使应用程序能够使用图形元素和格式化文本,从而能够在计算机屏幕和打印机上无缝显示。
因此,当应用程序依赖 Microsoft Win32 API 作为基础时,它们不会与底层图形硬件建立直接连接。 相反,GDI+ 组件充当中介,促进与设备驱动程序(代表这些应用程序)的交互。
System.Drawing
System.Drawing 包就像一个方便的计算机程序工具箱。 它提供了一组工具和功能,允许这些程序创建和操作图像和图形。
将其视为虚拟笔、画笔和画布的集合,可帮助计算机软件在屏幕上甚至连接到打印机时在纸上绘制图片、形状和文本! 这就像为您的计算机配备了一个艺术家工具包,可以让各种应用程序和软件中的东西看起来漂亮且具有视觉吸引力。
这是我们将用于在 LightningChart 对象中操作和渲染图像的包。
项目概况
GDI 图表开发项目将使用 GDI+ 图形库来创建自定义 ViewXY 图表。 图表的一部分将根据注释的大小调整事件进行修改。 为此,我们将使用事件句柄,这是一种响应事件(例如调整大小)的机制。 此调整大小事件会以某种方式影响图表内注释对象的位图填充。

本地设置
对于这个项目,我们需要考虑以下要求来编译项目。
操作系统:32 位或 64 位 Windows Vista 或更高版本、Windows Server 2008 R2 或更高版本。
DirectX:9.0c(Shader 模型 3 及更高版本)或 11.0 兼容图形适配器。
Visual Studio:2010-2019 用于开发,不需要部署。
平台 .NET Framework:已安装版本 4.0 或更高版本。
现在转到下一个 URL 并下载 LightningChart .NET。 然后,您将被重定向到登录表单,您必须在其中完成简单的注册过程。 完成注册过程后,您将可以访问您的 LightningChart 帐户。

登录帐户后,您将能够下载 SDK。 该 SDK 将是“免费试用”版本,但您将能够使用此数字信号处理滤波器应用程序教程的许多重要功能。 下载 SDK 后,您将拥有一个如下所示的 .exe 文件:

安装后因此请继续安装直至完成。 安装完成后,您将看到以下程序:

License Manager
在此应用程序中,您将看到购买选项。 您将使用此试用版 SDK 创建的所有项目都将可用于未来的开发并启用所有功能。

LightningChart .NET Interactive Examples
现在,您可以看到 100 多个可用于 WPF、WinForms 和/或 UWP 的交互式可视化。

Visual Studio 项目
现在让我们使用 Visual Studio。 使用 LightningChart 可视化工具和 Visual Studio 之间的主要区别在于,我们将能够分析和试验源代码中的许多功能。 在 LC 可视化工具中,选择 ViewXY 自定义 GDI+ 渲染图表并运行示例:

在窗口的右上角区域,您将看到以下选项:

对于试用版 SDK,我们将能够使用 WPF 框架。 单击要使用的框架后,我们需要指定将在其中创建项目的文件夹:

最后,将创建项目并打开 Visual Studio 并准备好执行数字信号处理滤波器应用程序。

Code Review
主要代码将包装在 MainWindow.xaml.cs 内。 在这里我们将找到 UI 控件的代码。

在代码中,我们将使用两个方法,它们将创建正确绘制图表所需的属性。 该交互式示例是使用各种用户控件构建的,用于操作和更改图表的视觉属性。 生成此图不需要这些控件,因此我们将重点关注负责生成对象的代码。
CreateChart()
这个主要方法将创建图表对象:
_chart = new LightningChart
{
ChartName = "ViewXY custom GDI+ rendering chart"
};
我们需要在更新图表属性时禁用控件重绘:
_chart.BeginUpdate();
AxisX xAxis = _chart.ViewXY.XAxes[0];
AxisY yAxis = _chart.ViewXY.YAxes[0];
BeginUpdate() 将帮助我们重新绘制控件。 我们可以访问 X 轴和 Y 轴并将这些对象分配给 X 轴/Y 轴对象。 要创建 Line Series,我们需要创建 PointLineSeries 的示例:
PointLineSeries pointLineSeries = new PointLineSeries(_chart.ViewXY, xAxis, yAxis);
pointLineSeries.LineStyle.Color = Colors.BlueViolet;
pointLineSeries.LineStyle.Width = 5;
点线系列可以呈现一条简单的线、点(散点)或两者都作为点线。 通过将 PointLineSeries 对象添加到 PointLineSeries 列表来将系列添加到图表中:
int pointsCount = 51;
SeriesPoint[] pointsArray = new SeriesPoint[pointsCount];
Random rand = new Random();
for (int i = 0; i < pointsCount; i++)
{
pointsArray[i].X = i;
pointsArray[i].Y = 20.0 + Math.Sin(i / 8.0 - 10.0) * 10.0 + (rand.NextDouble() - 0.5) * 1.0;
}
//Assign points array
pointLineSeries.Points = pointsArray;
在上面的代码中,将创建一个数据点数组,限制为 51 个点。 这些值将随机创建。 点线系列将等待一个数组,因此我们只需将创建的数组分配给 Points 属性即可。
将线系列添加到图表中:
_chart.ViewXY.PointLineSeries.Add(pointLineSeries);
创建注释椭圆:
AnnotationXY annot1 = new AnnotationXY(_chart.ViewXY, xAxis, yAxis)
{
Style = AnnotationStyle.RectangleArrow,
Sizing = AnnotationXYSizing.ScreenCoordinates
};
注释允许在图表区域的任何位置(如图所示)显示鼠标交互文本标签或图形。 用户可以使用鼠标自由移动注释,并且可以调整它们的大小和旋转,并且也可以更改它们的目标和位置。
或者,图表注释可以由自定义代码控制。 当必须在屏幕上呈现自定义图形时,注释也非常有用,因为它们可以以不同的样式和形状呈现。
在 ViewXY.Annotations 集合中创建 AnnotationXY 对象。 通过将鼠标移到注释上,它会进入鼠标交互式编辑状态,允许重新定位注释、调整其大小、旋转它以及确定箭头指向的位置。

为注释椭圆指定属性
有多个可以自定义的注释属性。 以下是针对此实例修改的代码:
annot1.SizeScreenCoords.Width = 300;
annot1.SizeScreenCoords.Height = 200;
annot1.Anchor.X = 0.5f;
annot1.Anchor.Y = 0.5f;
annot1.Shadow.Visible = false;
annot1.Fill.Style = RectFillStyle.Bitmap;
annot1.Text = "Annotation with custom drawing";
annot1.TextStyle.Font = new WpfFont("Segoe UI", 12f, true, false);
annot1.TextStyle.VerticalAlign = AlignmentVertical.Bottom;
annot1.LocationCoordinateSystem = CoordinateSystem.ScreenCoordinates;
annot1.LocationScreenCoords.X = 300;
annot1.LocationScreenCoords.Y = 300;
annot1.TextStyle.Color = Colors.White;
annot1.TargetAxisValues.X = pointsArray[30].X;
annot1.TargetAxisValues.Y = pointsArray[30].Y;
annot1.Fill.Bitmap.Image = CreateCustomDrawing((int)annot1.SizeScreenCoords.Width, (int)annot1.SizeScreenCoords.Height);
annot1.Fill.Bitmap.Layout = BitmapFillLayout.Center;
annot1.Fill.Color = Colors.Transparent;
annot1.Fill.GradientFill = GradientFill.Solid;
annot1.ResizedByUser += annot1_ResizedByMouse;
_chart.ViewXY.Annotations.Add(annot1);
ScreenCoordinates 允许通过屏幕坐标设置尺寸。 此属性使用 SizeScreenCoords.Height 和 SizeScreenCoords.Width。
Anchor 属性控制文本区域如何放置在 Location 处。 通过设置 Anchor.X = 0.5 和 Anchor.Y = 0.5,箭头的起点位于中间。 当设置 Anchor.X 0.1 且 Anchor.Y = 0.25 时,箭头起点位于左上角附近。

Location是箭头的起点。 它可以通过屏幕坐标、轴值或与目标的相对偏移来设置。 使用 LocationCoordinateSystem 进行选择,并使用 LocationScreenCoords、LocationAxisValues 或 LocationRelativeOffset 通过所选方法控制位置。 位置也是文本区域旋转的中心点。
创建自定义绘图:
将 GDI+ 图形绘制为位图图像对象:
System.Drawing.Bitmap bm = new System.Drawing.Bitmap(width, height);
System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bm);
Color color = Colors.Lime;
System.Drawing.Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(128, color.R, color.G, color.B));
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
绘制填充椭圆:
graphics.FillEllipse(brush, new System.Drawing.Rectangle(0, 0, width, height));
画线:
graphics.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Red, 3.0F), new System.Drawing.Point(width / 2, 0), new System.Drawing.Point(width / 2, height));
graphics.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Red, 3.0F), new System.Drawing.Point(0, height / 2), new System.Drawing.Point(width, height / 2));
保存到 PNG 格式的内存流。 PNG 存储 alpha 颜色信息:
MemoryStream memStream = new MemoryStream();
bm.Save(memStream, ImageFormat.Png);
创建BitMapFrame:它表示解码器返回并被编码器接受的图像数据
BitmapFrame bmpf = BitmapFrame.Create(memStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
释放资源并返回BitMapFrame:
graphics.Dispose();
memStream.Dispose();
return bmpf;
annot1_ResizedByMouse:方法以正确的尺寸重新创建填充图像。
private void annot1_ResizedByMouse(object sender, AnnotationResizedByUserXYEventArgs e)
{
//Cancel the ongoing rendering, as this handler will cause repaint by property changes
e.CancelRendering = true;
//Recreate the fill image in correct size
_chart.ViewXY.Annotations[0].Fill.Bitmap.Image =
CreateCustomDrawing
(
(int)e.NewSize.Width,
(int)e.NewSize.Height
);
}
添加 LightningChart .NET 作为图表库源时,您还可以通过仅使用高端图表组件来改进图形渲染结果。 总而言之,我们还了解了对最终用户特别有用的自定义注释。 这涉及设置屏幕坐标和定义注释属性。
感谢您阅读这个 GDI 图表开发项目,希望它能够帮助到您
渝公网安备50010702505508