图表绑定到非基本类型(Chart bind to non

编程入门 行业动态 更新时间:2024-10-26 22:22:13
图表绑定到非基本类型(Chart bind to non-primitive type)

我有一个C#.NET Windows窗体应用程序使用带有许多行系列的图表。 我有一个物理设备存储读数,当我下载读数时,我希望图表填写详细信息。

我已经在软件中创建了可以量化的值(例如温度)的类型,可以根据位置使用不同的单位,允许我为显示单位设置用户,只需处理背景中的所有内容而无需关心,以及何时显示对于用户来说,它是在正确的单位。

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. }

I have a C#.NET Windows Forms application using a chart with a number of line series. I have a physical device that stores readings on it, and as I'm downloading the readings I want the graph to fill in the detail.

I have created types in the software for quantifiable values (such as temperature) that may use different units depending on location, allowing me to have a user setting for display units, and just deal with everything in the background without caring, and when it's displayed to the user it's in the correct unit.

The C#.NET Charting.Series class is very strict and when attempting to draw using the bound array it throws an ArgumentExeption with the statement: "Series data points do not support values of type Units.Temperature only values of these types can be used: Double, Decimal, Single, int, long, uint, ulong, String, DateTime, short, ushort".

The Temperature type has a property called Value which is a double, and also is implicitly convertible to double, but this doesn't seem to matter. I'm hoping there's a way to bind this so that it converts whenever it requests the value from the results array so it can draw the graph correctly, anybody know how this might be done?

I'm hoping to avoid the need to the LogItem[] and then a secondary double[] just for the conversion.

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. }

最满意答案

您可以使用linq将结果整形为图表友好的形状。 例如:

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和Tempratue或任何合适的标签。

Many thanks to Reza Aghaei for the help.

The Linq statements do hold the answer to providing a conversion function, but just with a little tweaking so it's not creating a new array and rebinding with every refresh.

The solution is to use Charting.DataPointsCollection.DataBind(IEnumerable dataSource, string xField, string yField, string otherFields) to bind to the data. But to use Linq statements to create an IEnumerable object to be used in the databind, and on every call of MoveNext, this IEnumerable will fetch the data from the array and convert for the chart.

// 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);

EDIT: The above does work correctly, but according to the documentation on Points.DataBind(,,,), the evaluation is only performed once, so the DataBind(,,,) method does need to be called each time.

更多推荐

本文发布于:2023-07-20 11:07:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1198680.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:图表   绑定   类型   bind   Chart

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!