透视ObservableCollection

问题描述:



我有以下两个课程



Hi,
I have following two classes

public class MyDateObject
    {
        private double? _value1;
        private double? _value2;
        private double? _value3;
        private DateTime _date;

        public double? Value1
        {
            get
            {
                return this._value1;
            }
            set
            {
                this._value1 = value;
            }
        }

        public double? Value2
        {
            get
            {
                return this._value2;
            }
            set
            {
                this._value2 = value;
            }
        }

        public double? Value3
        {
            get
            {
                return this._value3;
            }
            set
            {
                this._value3 = value;
            }
        }

        public DateTime Date
        {
            get
            {
                return this._date;
            }
            set
            {
                this._date = value;
            }
        }

        public MyDateObject(double? value1, double? value2, double? value3, DateTime date)
        {
            this._value1 = value1;
            this._value2 = value2;
            this._value3 = value3;
            this._date = date;
        }
    }







public class MainPageViewModel
    {
        DateTime baseDate = DateTime.Today.AddDays(-15);
        public const int min = 0;
        public const int max = 79;
        Random r = new Random();

        private ObservableCollection<MyDateObject> _chartData;
        public ObservableCollection<MyDateObject> ChartData
        {
            get
            {
                return this._chartData;
            }
            set
            {
                this._chartData = value;
            }
        }

        public MainPageViewModel()
        {
            this.ChartData = new ObservableCollection<MyDateObject>();
            for (int i = 0; i < 30; i++)
            {
                ChartData.Add(new MyDateObject(r.Next(min, max), r.Next(min, max), r.Next(min, max), baseDate.AddDays(i)));
                string str = ChartData[i].Date.ToString();
                pivot.str = ChartData[i].Value1;                
            }
        }
    }





现在我想基于日期转向ChartData绑定到一个看起来像以下格式的网格



............... 1 2 3 4

价值1 6 9 56 78

价值2 8 51 7 21

价值3 79 45 57 25



Now I want to Pivot ChartData on the basis of day to bind to a grid which looks like the following format

...............1 2 3 4
Value 1 6 9 56 78
Value 2 8 51 7 21
Value 3 79 45 57 25

从理论上讲,您可以按日期对数据进行分组(使用Linq),使用sum函数填充Value1,Value2和Value3列(假设您每个日期有一个项目,它只会将该项目相加,并且在这种情况下,它将与Min,Max和Average函数相同,而不是Sum),只需转置该表即可完成。



所以分组你会得到这样的东西

Theoretically speaking you can just group your data by date (using Linq), use the sum function to fill in Value1, Value2 and Value3 columns (assuming that you have one item per one date it will sum only that one, and in that case it will work the same with Min, Max and Average functions instead of Sum) and just transpose that table and you are done.

So grouping you will get you something like this
        Value1 Value2 Value3
1            6      8     79
2            9     51     45
3           56      7     57
4           78     21     25





和转置会让你达到目标。

但是,我们在哪里没有至少一个但是。对。 :)



为了做到这一点,你必须使用能够适应你的数据并相应地创建动态类型的动态表达式(动态) type将具有与 ObservableCollection 中的日期值对应的属性。通常这不是完整的.net框架4.0中的问题(最快的方法是使用[ dynamic linq ] - 下载动态linq [这里]),但是既然你使用的是Silverlight,我们谈的是非常有限的动态表达式框架(即动态linq 将不起作用在Silverlight中)。



由于您有分组数据,我将跳到有趣的部分。由于现在编写的代码太多,我将尝试描述我将如何做到这一点。



你可以忘记绑定数据而是让你的自己的网格(表格)并手动填充正确的数据。创建结构以保存所有可能的日期(我假设不同)。创建第一行作为标题行,并填写表的列的日期描述。将第一列创建为标题列,其中包含Value1,Value2和Value3的描述。然后迭代你的 MyDateObject '对象的集合,并为每个项找到包含所有 Date 的索引。日期,因为它将是网格中值的列索引。



快乐编码。



and transpose will get you to your goal.
But, where would we be without at least one but. Right. :)

In order to do this kind of thing right, you''ll have to use dynamic expressions that will adapt to your data and create dynamic type accordingly (dynamic type will have properties that correspond to date values in your ObservableCollection). Generally this is not a problem in full .net framework 4.0 (fastest way is to use [dynamic linq] - download dynamic linq [here]), but since you are using Silverlight we are talking about very restricted dynamic expression framework (i.e. dynamic linq will not work in Silverlight).

Since you have grouped data I will skip to the fun part. And as it will be too much code to write right now, I will try to describe how I would do that.

You can forget about binding data and instead make your own grid (table) and fill it with right data manually. Create structure to hold all possible dates ordered (and distinct, I assume). Create first row as header row and fill in the date descriptions for columns of your table. Create first column as header column with descriptions Value1, Value2 and Value3. Then iterate over your collection of MyDateObject''s objects and for each item find index of Date in structure that holds all dates as that will be the column index of your values in grid.

Happy coding.