清单< T>&GT从名单&LT显示在DataGridView的热图;在C#中 [英] Displaying HeatMap in DataGridView from List<List<T>> in C#

查看:257
本文介绍了清单< T>&GT从名单&LT显示在DataGridView的热图;在C#中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在touples列表清单得到了一些数据。我的任务是使从热图。
作为在C#中的新手,我已经搜查了网,发现解决所画在DataGridView中的元素这一任务的一种方式,但我不明白,怎么办呢。
所以,我有Touples的列表:

I've got some data in List of List of touples. My task is to make a heatmap from that. Being newbie in C#, I've searched the net and found a way of solving this task by painting elements in DataGridView, but I don't understand, how to do it. So,I've got a list of Touples:

 using SpikeDataPacket = List<Tuple<double, double>>;

这是我加载网格内数据的方式:

This is the way I load data inside the grid:

public HeatForm(List<SpikeDataPacket> list)
{
  SpikeList = list;
  InitializeComponent();
  var bindstim = new BindingList<SpikeDataPacket>(SpikeList);
  var stimsource = new BindingSource(bindstim, null);
  heatMap.DataSource = stimsource;
}

但是,这显示与容量和在DataGridView内部计数,而不是数据表。
另外,我发现数颜色的方式,但不知道如何使用它:

But this displays a table with "capacity" and "count" inside the DataGridView, but not the data. Also, I've found the way to count the color, but don't know, how to apply it:

private Color HeatMapColor(double value, double min, double max)
{
  Color firstColour = Color.RoyalBlue;
  Color secondColour = Color.LightSkyBlue;

  // Example: Take the RGB
  //135-206-250 // Light Sky Blue
  // 65-105-225 // Royal Blue
// 70-101-25 // Delta

int rOffset = Math.Max(firstColour.R, secondColour.R);
int gOffset = Math.Max(firstColour.G, secondColour.G);
int bOffset = Math.Max(firstColour.B, secondColour.B);

int deltaR = Math.Abs(firstColour.R - secondColour.R);
int deltaG = Math.Abs(firstColour.G - secondColour.G);
int deltaB = Math.Abs(firstColour.B - secondColour.B);

double val = (value - min) / (max - min);
int r = rOffset - Convert.ToByte(deltaR * (1 - val));
int g = gOffset - Convert.ToByte(deltaG * (1 - val));
int b = bOffset - Convert.ToByte(deltaB * (1 - val));        

  return Color.FromArgb(255, r, g, b);
}

感谢你在前进!

推荐答案

我想我会有所不同解决这个问题。

I think I would tackle the problem somewhat differently.


  • 我要开始的没有数据绑定。无论是元组结构名单的名单,也不是双到颜色映射适合于井数据绑定

  • 我也不能确定你的颜色映射算法..

  • I would start without using DataBinding. Neither the List of List of Tuple structure nor the mapping of a double to a Color lends itself to well to DataBinding.
  • I'm also not sure about your color mapping algorithm..

要填写数据到一个DataGridView DGV我用一个简单的程序,该程序首先prepares的DGV,然后描绘了细胞:

To fill the data into a DataGridView DGV I use a simple routine, which first prepares the DGV and then paints the Cells:

void fillData()
{
    int maxRow = data.Count;
    int maxCol = data[0].Count;
    double factor = 1.0;

    DGV.RowHeadersVisible = false;
    DGV.ColumnHeadersVisible = false;
    DGV.AllowUserToAddRows = false;
    DGV.AllowUserToOrderColumns = false;
    DGV.CellBorderStyle = DataGridViewCellBorderStyle.None;
    //..

    int rowHeight = DGV.ClientSize.Height / maxRow - 1;
    int colWidth = DGV.ClientSize.Width / maxCol - 1;

    for (int c = 0; c < maxRow; c++) DGV.Columns.Add(c.ToString(), "");
    for (int c = 0; c < maxRow; c++) DGV.Columns[c].Width = colWidth;
    DGV.Rows.Add(maxRow);
    for (int r = 0; r < maxRow; r++) DGV.Rows[r].Height = rowHeight;

    List<Color> baseColors = new List<Color>();  // create a color list
    baseColors.Add(Color.RoyalBlue);
    baseColors.Add(Color.LightSkyBlue);
    baseColors.Add(Color.LightGreen);
    baseColors.Add(Color.Yellow);
    baseColors.Add(Color.Orange);
    baseColors.Add(Color.Red);
    List<Color> colors = interpolateColors(baseColors, 1000);

    for (int r = 0; r < maxRow; r++)
    {
        for (int c = 0; c < maxRow; c++)
        {
            DGV[r,c].Style.BackColor = 
                           colors[ Convert.ToInt16( data[r][c].Item2 * factor)];

        }
    }

}

您会wnat改变一些东西,特别是底座的颜色和你想要得到的,这取决于你的价值观的颜色数也从一个双精度值到整数索引的映射!

You would wnat to change a few things, especially the base colors and the number of colors you want to get, depending on your values but also the mapping from a double value to a integer index!

下面是创建内插颜色的列表的功能。这需要几个基础的颜色和长度N和返回n插值颜色。这使得映射简单灵活。

Here is the function to create a list of interpolated colors. It takes a few base colors and a length N and returns N interpolated colors. This makes the mapping simple and flexible..

List<Color> interpolateColors(List<Color> stopColors, int count)
{
    SortedDictionary<float, Color> gradient = new SortedDictionary<float, Color>();
    for (int i = 0; i < stopColors.Count; i++) 
        gradient.Add(1f * i / (stopColors.Count-1), stopColors[i]);
    List<Color> ColorList = new List<Color>();

    using (Bitmap bmp = new Bitmap(count, 1))
    using (Graphics G = Graphics.FromImage(bmp))
    {
        Rectangle bmpCRect = new Rectangle(Point.Empty, bmp.Size);
        LinearGradientBrush br = new LinearGradientBrush
                                (bmpCRect, Color.Empty, Color.Empty, 0, false);
        ColorBlend cb = new ColorBlend();
        cb.Positions = new float[gradient.Count];
        for (int i = 0; i < gradient.Count; i++) 
            cb.Positions[i] = gradient.ElementAt(i).Key;
        cb.Colors = gradient.Values.ToArray();
        br.InterpolationColors = cb;
        G.FillRectangle(br, bmpCRect);
        for (int i = 0; i < count; i++) ColorList.Add(bmp.GetPixel(i, 0));
        br.Dispose();
    }
    return ColorList;
}

我的测试数据进行了这样的创建:

My test data were created like this:

List<List<Tuple<double,double>>> data = new List<List<Tuple<double,double>>>();

Random R = new Random();

void createData(int maxRow, int maxCol)
{
    for (int c = 0; c < maxRow; c++)
    {
        data.Add(new List<Tuple<double, double>>());
        for (int r = 0; r < maxRow; r++)
        {
            data[c].Add(new Tuple<double, double>(c, Math.Min(999, R.Next(r*c))));
        }
    }
}

和我使用它是这样的:

private void Form1_Load(object sender, EventArgs e)
{
    createData(40, 40);
    fillData();
}

下面是一个(相当沉闷)截图:

Here is a (rather boring) screenshot:

一旦你得到了展示,只要你想,你可能需要决定要不要去寻求解决方案的 数据绑定。我相信,你将需要使用 OwnerDrawing 单元。一旦你有了单元格中的值,可以使用相同的映射只是这样的:

Once you got the display as you want it, you may want to decide about going for a solution with DataBinding. I believe that you will need to use OwnerDrawing the Cells. Once you have the values in the cells you can use the same mapping simply like this:

private void DGV_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
   Color theColor = .....
   e.Graphics.Clear(colors[theColor]);
}

这篇关于清单&LT; T&GT;&GT从名单&LT显示在DataGridView的热图;在C#中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆