Как сделать этот (см. изображение) тип графика в datagridview

Я хочу добавить этот тип графика в свой datagridviewcontrol: -

альтернативный текст

Здесь график построен за 12 месяцев, и я могу ввести проценты или сравнительные значения в пикселях за 12 месяцев... Пожалуйста, также скажите, как раскрасить графики

Любые идеи для этого будут высоко оценены

Изменить ---- Спасибо за все ответы, я многому научился, но все еще не мог обойти проблему...

  1. Мне нужно отобразить много строк в моем datagridview с примерно 15 столбцами.... Так что очень странно напрямую добавлять строки, но добавлять разные столбцы для графика каждый раз, когда я добавляю строку... не мог придумать ни одного другой способ сделать это .... более того, я не хочу сохранять изображения, которые, как я обнаружил, мне нужно, если я добавлю изображения непосредственно в вид сетки.....

  2. Есть ли какой-либо сторонний инструмент, который может помочь мне получить собственное представление данных с диаграммами?

Спасибо .


person Ankush Roy    schedule 21.10.2010    source источник
comment
Я делаю настольное приложение, т.е. WinForms   -  person Ankush Roy    schedule 21.10.2010
comment
WPF, Silverlight и Console также являются настольными приложениями.   -  person Henk Holterman    schedule 23.10.2010
comment
@Henk: Простите мое невежество, но разве Silverlight не ориентирован на веб-приложение?   -  person Bruno Brant    schedule 27.10.2010
comment
@Bruno: Да, но и вне браузера   -  person Henk Holterman    schedule 27.10.2010


Ответы (5)


Вот способ использования панелей (div):

http://weblogs.asp.net/stevewellens/archive/2010/03/01/visual-data-binding-hot-dang.aspx

person Steve Wellens    schedule 26.10.2010

Намного проще и проще использовать API Google Charts.

В вашем DataGridView просто повторите шаблон с тегом <img> с определенным src.

Например, этот код (разбитый на 2 строки):

<img src="http://chart.apis.google.com/chart?
   cht=bvs&chd=t:50,20,30,65,20&chs=220x30" width="120" />

Дал бы вам следующее:

Вам просто нужно немного изменить раздел t:50,20,30,65,20 в зависимости от данных, к которым вы привязываетесь.

Так:

<img src="http://chart.apis.google.com/chart?
   cht=bvs&chd=t:<%# Eval("t1") %>,<%# Eval("t2") %>,<%# Eval("t3") %>,<%# Eval("t4") %>,<%# Eval("t5") %>&chs=220x30" width="120" />
person Steven de Salas    schedule 23.11.2010
comment
Ps: Использование памяти на сервере для графики = НЕТ - person Steven de Salas; 24.11.2010

Попробуйте использовать управление диаграммами: http://msdn.microsoft.com/en-us/library/dd456632.aspx

person Petr Behenský    schedule 22.10.2010
comment
Спасибо за ответ ... я успешно добавил элемент управления диаграммой, но как взять этот элемент управления внутри сетки .... ?? - person Ankush Roy; 23.10.2010

вы можете попробовать использовать DataGridViewImageColumn() для этого конкретного столбца.

См. http://msdn.microsoft.com/en-us/library/z1cc356h%28v=VS.90%29.aspx

Для графиков вам нужно сначала создать растровые изображения, и если вы выполните поиск «Код: создание растрового изображения во время выполнения (Visual C#)» в msdn, вы найдете простой, но эффективный пример. (две ссылки пока не могу разместить)

В основном вам нужно добавить столбец, который обрабатывается как изображение, а затем нарисовать изображение через событие форматирования ячейки. Вы можете создавать и кэшировать свои изображения заранее или создавать их на лету (ваши предпочтения). Вторая статья должна помочь вам построить свои маленькие графики.

Чтобы изменить цвет, вам нужно изменить 3-й аргумент метода setpoint. Конечно, это не самый быстрый способ рисования графиков, но для начала достаточно простой.

person mhttk    schedule 24.10.2010
comment
пожалуйста, посмотрите редактирование... Я думаю, что если я создам около 20000 растровых изображений (для 20000 строк в datagridview), это займет слишком много памяти - person Ankush Roy; 26.10.2010
comment
Я понимаю вашу проблему. Я думаю, вам не нужно создавать все 20000 из них. Просто создавайте растровые изображения на лету по мере их отображения. - person mhttk; 27.10.2010

Вот краткий пример кода, чтобы вы могли проверить требования к памяти и производительность ваших элементов управления. Я не понимаю, что вы должны сделать, чтобы избежать растровых изображений, я думаю, что большинство сторонних элементов управления работают аналогичным образом. Я уверен, что мой код можно оптимизировать несколькими способами, но вам есть с чего начать. Не уверен, когда нужно иметь 20000 строк в сетке, ни один пользователь все равно не увидит все это. Возможно, можно найти способ показать подмножества за раз..?

Создание изображения, вероятно, должно выполняться не в тестовом объекте (поскольку это модель данных), а скорее на уровне представления (я добавил событие DataBindingComplete, поскольку его можно использовать для аналогичных вещей), я сделал это здесь, потому что это было проще. Никакие изображения не сохраняются в файл или что-то в этом роде.

Я создал форму с DataGridView под названием dataGridView1.

Это код формы:

List<TestObject> _list = new List<TestObject>();

    public Form1()
    {
        InitializeComponent();
        dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);

    }


    void dataGridView1_DataBindingComplete( object sender, DataGridViewBindingCompleteEventArgs e )
    {

    }

    private void Form1_Load( object sender, EventArgs e )
    {
        // Populate the grid, here you should add as many rows as you want to display
        _list.Add(new TestObject("Obj1", 20, Brushes.Red, new int[]{3,4,5,3,5,6}));
        _list.Add(new TestObject("Obj2", 10, Brushes.Green, new int[] { 1, 2, 3, 4, 5, 6 }));
        _list.Add(new TestObject("Obj3", 30, Brushes.Blue, new int[] { 3, 2, 1, 1, 2, 3 }));


        dataGridView1.DataSource = _list;

    }

Я также создал тестовый объект для заполнения сетки:

public class TestObject
    {

        private const int BitmapWidth = 100;
        private const int BitmapHeight = 20;
        private System.Drawing.Brush _color;
        private string _name;
        private int[] _numbers;
        private int _value;


        public TestObject( string name, int value, System.Drawing.Brush color, int[] series )
        {
            _name = name;
            _numbers = series;
            _color = color;
            _value = value;
        }

        public string Name
        {
            get { return _name; }
        }
        public string Value { get { return _value.ToString(); } }

        public Image Series
        {
            get
            {
                int width = BitmapWidth / _numbers.Length - _numbers.Length;

                System.Drawing.Bitmap b = new Bitmap(BitmapWidth, BitmapHeight);
                Graphics g = Graphics.FromImage(b);
                g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;

                int current = 0;

                for (int i = 0;i < _numbers.Length;i++)
                {
                    g.FillRectangle(_color, current, BitmapHeight - (BitmapHeight / 10) * _numbers[i], width, (BitmapHeight / 10) * _numbers[i]);
                    current+=width + 2;
                }

                return b;
            }
        }
    }
person Mikael    schedule 26.10.2010