作者:孙梦镁
以下是在WPF中将身高、体重、年龄用动态图表表示出来的简单示例:
一.安装资源包:
右键点击解决方案资源管理器中的项目名称,选择“管理 NuGet 包”,并安装“MySql.Data”,“OxyPlot.Wpf”资源包。
二.编辑xaml:
在前端界面中,我们需要添加引用
xmlns:oxy="http://oxyplot.org/wpf"
引用过后,添加图表的承载控件PlotView
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" />
</Grid>
三.创建一个类并进行编辑:
这是最重要的部分,我们需要创建一个新的类(此处命名为MainViewModel)来处理 OxyPlot 的图表模型。
1.引入必要的命名空间
using OxyPlot;
using OxyPlot.Series;
using MySql.Data.MySqlClient;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using OxyPlot.Legends;
using OxyPlot.Annotations;
2.代码部分
server后面写IP地址;port后写端口号; user为用户名,一般都是root;password为MySQL连接密码;database后写要连接的数据库的名称;SELECT后写列的名称;FROM后写表的名称。
连接数据库的代码:
// 异步方法,从数据库获取员工数据
public async Task<List<EmployeeData>> FetchDataFromDatabaseAsync()
{
// 创建MySQL数据库连接
using var connection = new MySqlConnection("server=localhost;user=root;database=ku;port=3306;password=密码");
// 异步打开数据库连接
await connection.OpenAsync();
// 创建SQL命令,用于查询员工的id、身高、体重和年龄
using var command = new MySqlCommand("SELECT id, height, weight,age FROM biao", connection);
// 异步执行SQL命令并获取数据读取器
using var reader = await command.ExecuteReaderAsync();
// 用于存储查询结果的列表
var result = new List<EmployeeData>();
// 遍历读取器,将数据读取并添加到结果列表
while (await reader.ReadAsync())
{
result.Add(new EmployeeData
{
Id = Convert.ToInt32(reader["id"]),
Height = Convert.ToDouble(reader["height"]),
Weight = Convert.ToDouble(reader["weight"]),
Age = Convert.ToInt32(reader["age"])
});
}
return result;
}
编辑图表的代码:
// 私有字段,用于存储PlotModel实例
private PlotModel _plotModel;
// PlotModel属性,实现属性变更通知
public PlotModel PlotModel
{
get => _plotModel;
set { _plotModel = value; OnPropertyChanged(); }
}
// 构造函数,初始化视图模型时调用InitializePlotModel方法
public MainViewModel()
{
InitializePlotModel();
}
// 初始化PlotModel的方法
private void InitializePlotModel()
{
// 创建一个新的PlotModel实例,并设置标题
PlotModel = new PlotModel { Title = "员工信息" };
// 创建表示身高的折线图系列
var heightSeries = new LineSeries { Title = "身高", MarkerType = MarkerType.Circle, YAxisKey = "y2" };
// 创建表示体重的柱状图系列
var weightSeries = new LinearBarSeries { Title = "体重", BarWidth = 10, YAxisKey = "y1" };
// 创建表示年龄的折线图系列
var ageSeries = new LineSeries { Title = "年龄", MarkerType = MarkerType.Circle, YAxisKey = "y2" };
// 将系列添加到PlotModel
PlotModel.Series.Add(heightSeries);
PlotModel.Series.Add(weightSeries);
PlotModel.Series.Add(ageSeries);
// 添加底部的X轴,用于显示员工id
PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Bottom, Title = "员工id", MajorGridlineStyle = LineStyle.Solid });
// 添加左侧的Y轴,用于显示某些值
PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Left, Title = "值", MajorGridlineStyle = LineStyle.Solid, Key = "y2" });
// 添加右侧的Y轴,用于显示某些值
PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis { Position = OxyPlot.Axes.AxisPosition.Right, Title = "值", MajorGridlineStyle = LineStyle.Solid, Key = "y1" });
}

图1 效果展示
完成上述操作将会获得图1所示效果。
也可以添加图例、警戒线、注释框等,丰富图表样式代码部分如下:
// 添加图例到PlotModel
PlotModel.Legends.Add(new Legend
{
LegendPlacement = LegendPlacement.Outside,
LegendPosition = LegendPosition.BottomCenter,
LegendOrientation = LegendOrientation.Horizontal,
LegendBorderThickness = 0,
LegendTextColor = OxyColors.Black
});
// 创建一个水平的警戒线注释
var alertLine = new OxyPlot.Annotations.LineAnnotation
{
Type = OxyPlot.Annotations.LineAnnotationType.Horizontal,
Y = 50,
Color = OxyColors.Red,
TextColor = OxyColors.Red,
TextPosition = new DataPoint(double.NaN, 50),
Text = "警戒线"
};
// 将警戒线注释添加到PlotModel
PlotModel.Annotations.Add(alertLine);
// 创建一个矩形注释
var rectangleAnnotation = new RectangleAnnotation
{
MinimumX = 1,
MaximumX = 4,
MinimumY = 0,
MaximumY = 100,
// Fill = OxyColors.LightYellow,
Stroke = OxyColors.DarkOrange,
StrokeThickness = 1,
Layer = AnnotationLayer.BelowSeries
};
// 将矩形注释添加到PlotModel
PlotModel.Annotations.Add(rectangleAnnotation);

图2 效果展示
增添上述代码将会获得图2所示效果。
四.增添其他效果:
为了使图表不那么空旷,也可以增添其他功能(这里增添了写入员工信息的功能)
下面是xaml代码展示:
<Grid>
<oxy:PlotView Model="{Binding PlotModel}" Margin="0,45,0,0"/>
<Label Content="员工ID" HorizontalAlignment="Left" Height="30" Margin="10,10,0,0" VerticalAlignment="Top" Width="52"/>
<TextBox x:Name="txtId" HorizontalAlignment="Left" Height="22" Margin="62,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="63"/>
<Label Content="年龄" HorizontalAlignment="Left" Height="30" Margin="148,8,0,0" VerticalAlignment="Top" Width="37" RenderTransformOrigin="-0.288,0.403"/>
<Label Content="身高" HorizontalAlignment="Left" Height="30" Margin="248,10,0,0" VerticalAlignment="Top" Width="37" RenderTransformOrigin="-0.288,0.403"/>
<Label Content="体重" HorizontalAlignment="Left" Height="30" Margin="348,10,0,0" VerticalAlignment="Top" Width="37" RenderTransformOrigin="-0.288,0.403"/>
<TextBox x:Name="txtAge" HorizontalAlignment="Left" Height="22" Margin="180,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="63"/>
<TextBox x:Name="txtHeight" HorizontalAlignment="Left" Height="22" Margin="285,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="63"/>
<TextBox x:Name="txtWeight" HorizontalAlignment="Left" Height="22" Margin="385,12,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="63"/>
<Button Content="写入" HorizontalAlignment="Left" Height="19" Margin="502,15,0,0" VerticalAlignment="Top" Width="52" Click="Button_Click_1"/>
</Grid>
下面是cs代码展示:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// 获取TextBox中的值
string id = txtId.Text;
string age = txtAge.Text;
string height = txtHeight.Text;
string weight = txtWeight.Text;
// 验证输入是否有效
if (string.IsNullOrEmpty(age) || string.IsNullOrEmpty(height) || string.IsNullOrEmpty(weight) || string.IsNullOrEmpty(id))
{
MessageBox.Show("请填写所有字段!");
return;
}
// 连接数据库
string connStr = "server=localhost;user=root;database=ku;port=3306;password=09142x@smm";
MySqlConnection conn = new MySqlConnection(connStr);
{
try
{
// 打开连接
conn.Open();
// 准备SQL语句
string sql = "INSERT INTO employees (age, height, weight, id) VALUES (@age, @height, @weight, @id)";
// 创建命令对象
MySqlCommand cmd = new MySqlCommand(sql, conn);
// 添加参数以防止SQL注入攻击
cmd.Parameters.AddWithValue("@age", Convert.ToInt32(age));
cmd.Parameters.AddWithValue("@height", Convert.ToDouble(height));
cmd.Parameters.AddWithValue("@weight", Convert.ToDouble(weight));
cmd.Parameters.AddWithValue("@id", id);
// 执行命令
int affectedRows = cmd.ExecuteNonQuery();
if (affectedRows > 0)
{
MessageBox.Show("数据已成功添加!");
}
else
{
MessageBox.Show("没有数据被添加!");
}
}
catch (Exception ex)
{
// 捕获异常并显示错误信息
MessageBox.Show("发生错误:" + ex.Message);
}
}
}
这里填写完信息以后单击“写入”。

图3 效果展示

4622

被折叠的 条评论
为什么被折叠?



