LiveCharts:
LiveCharts2预览版、内存管理不是很好,长时间持续更新的情况下,内存溢出,慎用
数据加载量不能太大(1000点左右 开始卡)
第一步:下载LiveChart NuGet包
第二步:引用:
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
第三步:使用:
折线图:CartesianChart
- XAML中使用:
一个图表对应多个序列,可以是多个折线图和多个柱状图
属性:
PointGeometrySize:折线图上的白点大小
LineSmoothness:折线图圆滑曲线
ScalesYAt:对齐到哪个Y轴(因为可以写多个Y轴,所以需要对应一下)
CartesianChart:设置坐标
AxisX:设置X坐标 需要Labels数量和Values数量保持一致
AxisY:纵坐标一般设置做大数值和最小数值
Separator:设置步长
Sections:设置预警线
<lvc:CartesianChart>
<lvc:CartesianChart.Series>
<lvc:LineSeries Values="23, 11, 99, 70, 87, 87, 84, 91, 55, 27, 79, 70, 70, 10, 14, 24, 27, 89, 61, 39"
Stroke="Orange" Fill="#1F00" PointGeometrySize="0" LineSmoothness="0"
Title="折线图"/>
<lvc:ColumnSeries Values="23, 11, 99, 70, 87, 87, 84, 91, 55, 27, 79, 70, 70, 10, 14, 24, 27, 89, 61, 39"
Title="柱状图" ScalesYAt="0" MaxColumnWidth="20" Fill="Green"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis Labels="a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v">
<lvc:Axis.Separator>
<lvc:Separator Step="1" Stroke="Red" StrokeDashArray="3,3"/>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis MinValue="0" MaxValue="100">
<lvc:Axis.Separator>
<lvc:Separator Step="20" Stroke="Green" StrokeDashArray="3,3" />
</lvc:Axis.Separator>
<lvc:Axis.Sections>
<lvc:AxisSection Value="75" Stroke="Red" StrokeThickness="1" />
</lvc:Axis.Sections>
</lvc:Axis>
<lvc:Axis MinValue="0" MaxValue="2" LabelFormatter="{Binding YLableFormatter}">
<lvc:Axis.Separator>
<lvc:Separator Step="0.4" StrokeDashArray="3,3" StrokeThickness="0" />
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
显示结果:
因为设置Y轴坐标的时候,是double类型,所以导致精度丢失,需要设置LabelFormatter
C#处理精度丢失代码:
// 保留两位小数
public Func<double, string> YLableFormatter { get; set; } = d =>d.ToString("0.00");
处理之后的效果: 没有问题
- C#中给表格赋值:
XAML代码:
<lvc:CartesianChart Series="{Binding SeriesList}"/>
C#赋值核心代码:
public SeriesCollection SeriesList { get; set; } = new SeriesCollection();
// 可以使用C#进行动态赋值
SeriesList.Add(new LineSeries
{
Values = new ChartValues<double> { 75, 14, 36, 33, 89, 76, 23, 21, 77, 90, 21, 22, 54, 90, 32, 47, 97, 81, 63, 21 },
Title = "压力",
Stroke = Brushes.Green,
});
效果图:
环形图 :Gauge
属性
Uses360Mode:是否使用360度
From:从多少开始
To:到多少结束
Value:值多少
<lvc:Gauge Uses360Mode="True" From="0" To="100" Value="85" />
显示效果:
仪表盘:AngularGauge
属性:
Sections:仪表警戒线
FromValue:从多少位置开始
ToValue:到多少位置结束
LabelsStep:每一个的步长
TicksStep:小格的步长
Wedge:整个的角度
TicksForeground:刻度线的颜色
Foreground:字体颜色
SectionsInnerRadius:环形圆角度
Value:值
<lvc:AngularGauge Grid.Row="1" Grid.Column="1" FromValue="50" ToValue="250" LabelsStep="50" TicksStep="25" Wedge="270" TicksForeground="White"
Foreground="White" FontWeight="Bold" FontSize="16" SectionsInnerRadius="0.5" Value="180">
<lvc:AngularGauge.Sections>
<lvc:AngularSection FromValue="50" ToValue="200" Fill="Orange" />
<lvc:AngularSection FromValue="200" ToValue="260" Fill="Red" />
</lvc:AngularGauge.Sections>
</lvc:AngularGauge>
效果:
ScottPlot:考虑性能, 建议这个 号称500万点数据无压力
第一步:下载ScottPlot NuGet包
第二步:引用:
xmlns:sp ="clr-namespace:ScottPlot;assembly=ScottPlot.Wpf"
第三步:使用:
注意:此控件只可以C#代码进行赋值
<sp:WpfPlot Name="wpf_plot" />
C#代码:
属性:
DataGen:模拟数据加载
Refresh():刷新表格 当数据变化的时候 刷新表格数据
YAxis:第一个Y轴
YAxis2:第二个Y轴
YAxisIndex:对应的Y轴
AddAxis:可以建立多个轴 XY都可以
ManualTickSpacing:轴显示的时间格式化
TickLabelFormat:刻度标签格式化
TickLabelStyle:标签样式
AddHorizontalLine:添加Y轴预警线
AddVerticalLine:添加X轴预警线
using ScottPlot;
using System.Windows;
namespace XH.CustomLesson.ChartLib
{
/// <summary>
/// ScottPlotTestWindow.xaml 的交互逻辑
/// </summary>
public partial class ScottPlotTestWindow : Window
{
public ScottPlotTestWindow()
{
InitializeComponent();
this.Loaded += ScottPlotTestWindow_Loaded;
}
private void ScottPlotTestWindow_Loaded(object sender, RoutedEventArgs e)
{
// 数据加载
var plt = wpf_plot.Plot;
// 模拟序列数据
double[] datas = DataGen.RandomWalk(new Random(),1000000);
plt.AddSignal(datas);
// 不调 Refresh 会报错 必须调用Refresh()
// YAxis:第一个Y轴
// YAxis2:第二个Y轴
plt.YAxis2.Ticks(true);
plt.YAxis2.Color(System.Drawing.Color.Red);
datas = DataGen.Cos(1000000);
var series = plt.AddSignal(datas);
//YAxisIndex 对应的Y轴
series.YAxisIndex = 1;
// 可以有多个轴 第三个Y轴
var yAxis3 = plt.AddAxis(ScottPlot.Renderable.Edge.Right,10,"新轴",System.Drawing.Color.Blue);
datas = DataGen.Sin(1000000);
series = plt.AddSignal(datas);
series.YAxisIndex = 10;
// 第二个X轴
plt.XAxis2.Ticks(true);
plt.XAxis2.Color(System.Drawing.Color.Green);
datas = DataGen.Random(new Random(),100);
var barPlot = plt.AddBar(datas, System.Drawing.Color.Orange);
barPlot.XAxisIndex = 1;
barPlot.YAxisIndex = 1;
// 第三个X轴
var xAxis3 = plt.AddAxis(ScottPlot.Renderable.Edge.Bottom,3, "第三个X轴", System.Drawing.Color.OrangeRed);
xAxis3.Ticks(true);
xAxis3.DateTimeFormat(true);
// X轴时间格式化
xAxis3.ManualTickSpacing(20, ScottPlot.Ticks.DateTimeUnit.Day);
// 斜着显示
xAxis3.TickLabelStyle(rotation: 45);
// 第四个Y轴
var yAxis4 = plt.AddAxis(ScottPlot.Renderable.Edge.Left,4, "第四个Y轴", System.Drawing.Color.OrangeRed);
yAxis4.Ticks(true);
yAxis4.DateTimeFormat(true);
// Y轴格式化
yAxis4.TickLabelFormat("P1", false);
// 添加第三个数据序列 并且对齐到第三个X轴 和 第四个Y轴
datas = DataGen.Sin(1000);
double[] x_datas = new double[1000];
DateTime dateTime = DateTime.Now;
for (int i = 0; i < x_datas.Length; i++)
{
x_datas[i] = dateTime.AddDays(i).ToOADate();
}
var scatterPlot = plt.AddScatterLines(x_datas, datas, System.Drawing.Color.Green);
scatterPlot.YAxisIndex = 4;
scatterPlot.XAxisIndex = 3;
// 预警线
var hl = plt.AddHorizontalLine(0.8, System.Drawing.Color.Red);
// 对应到哪个Y轴
//hl.YAxisIndex = 4;
plt.AddVerticalLine(DateTime.Now.AddDays(50).ToOADate());
wpf_plot.Refresh();
}
}
}
显示结果: