我有一个C#.NET Windows Forms应用程序,使用的图表包含许多系列。我有一个物理设备存储读数,当我下载读数时,我希望图表填写详细信息。
我已经在软件中创建了可量化值(例如温度)的类型,可以根据位置使用不同的单位,允许我为显示单位设置用户,并且只需处理背景中的所有内容而无需关心,以及当它显示给用户时,它是在正确的单位。
C#.NET Charting.Series类非常严格,当尝试使用绑定数组进行绘制时,它会抛出一个带有以下语句的ArgumentExeption:“系列数据点不支持Units类型的值.Temperature只有这些类型的值可以使用:Double,Decimal,Single,int,long,uint,ulong,String,DateTime,short,ushort“。
Temperature类型有一个名为Value的属性,它是一个double,也可以隐式转换为double,但这似乎并不重要。我希望有一种方法可以绑定它,以便它在每次请求结果数组中的值时进行转换,这样它就可以正确地绘制图形,任何人都知道这是怎么回事 可能会完成吗?
我希望避免使用LogItem [],然后再使用辅助双[]进行转换。
private LogItem[] results;
private async void GraphPage_Load(object sender, EventArgs e) {
var count = await device.LogCount.Read(CancelToken);
results = new LogItem[count];
graph.DataSource = results;
graph.Series[0].XValueMembers = nameof(LogItem.DateTime); //Type is System.DateTime
graph.Series[0].YValueMembers = nameof(LogItem.Temperature); //Type my library, Units.Temperature
var prog = new Progress<double>();
prog.ProgressChanged += (sender2, e2) => {
BeginInvoke(new Action(() => {
progBar.Value = results.Count(log => !Equals(log, LogItem.Empty));
CheckEmptyPoints(); //Sets or clears Points[x].IsEmpty;
graph.Invalidate(); //Force graph to draw new results, maybe a better way of doing this?
}));
};
await device.DownloadLogs(CancelToken, results, prog); //Takes output buffer and IProgress to report more data has been downloaded.
}
答案 0 :(得分:2)
您可以使用linq将结果整形为图表友好的形状。例如:
%f[%D]
var list = results.Select(x => new { X = x.DateTime, Y = x.Temprature.Value }).ToList();
this.chart1.DataSource = list;
this.chart1.Series[0].XValueMember = "X";
this.chart1.Series[0].YValueMembers = "Y";
和X
只是占位符,您可以使用Y
和DateTime
或任何合适的标签。
答案 1 :(得分:1)
非常感谢Reza Aghaei
寻求帮助。
Linq语句确实提供了提供转换函数的答案,但只需稍加调整就可以创建一个新数组,并在每次刷新时重新绑定。
解决方案是使用Charting.DataPointsCollection.DataBind(IEnumerable dataSource, string xField, string yField, string otherFields)
绑定到数据。但是要使用Linq语句来创建要在数据绑定中使用的IEnumerable对象,并且在每次调用MoveNext时,此IEnumerable将从数组中获取数据并转换为图表。
// IEnumerable<LogItem>.Select(...) creates an IEnumerable which references the array,
// and performs the selection and conversion on each call to MoveNext().
graph.Series[0].Points.DataBind(
results.Select(l => new { X = l.DateTime, Y = l.OilCondition.Value }),
"X",
"Y",
string.Empty);
编辑:以上操作正常,但根据Points.DataBind(,,,)的文档,评估只执行一次,因此每次都需要调用DataBind(,,,)方法。