2010-10-21 10 views
7

pragnę dodać ten typ wykresu w moim datagridviewcontrol: -Jak to (patrz zdjęcie) typ wykresu w DataGridView

alt text

Oto wykres jest wykreślane przez 12 miesięcy i mogę albo procenty wejściowe lub wartości porównawcze w pikselach za okres 12 miesięcy .... Proszę również powiedzieć, jak kolor wykresy

jakieś pomysły na ten sposób będzie wysoko ceniona

Edycja ---- Dzięki za wszystko odpowiedzi, które uczę da dużo, ale wciąż nie może obejść problem ...

  1. trzeba wyświetlić wiele wierszy w moim DataGridView z około 15 kolumn .... Więc jej bardzo dziwne bezpośrednio dodać wiersze ale dodawać różne kolumny dla wykresu za każdym razem, gdy dodaję wiersz ... nie mogłem wymyślić innego sposobu na osiągnięcie tego ... ponadto nie chcę zapisywać obrazów, które znalazłem, gdy muszę dodać obrazy bezpośrednio do widoku siatki .....

  2. Czy istnieje narzędzie, które osoba trzecia nie może mi pomóc, aby uzyskać niestandardowe DataGridView z wykresów

Dziękuję.

+0

WinForms, WPF lub ... –

+0

Robię aplikacją tj WinForms –

+1

WPF, Silverlight i konsola są również aplikacje desktopowe. –

Odpowiedz

0

można spróbować użyć DataGridViewImageColumn() dla danej kolumny.

Proszę odnieść się do http://msdn.microsoft.com/en-us/library/z1cc356h%28v=VS.90%29.aspx

Na wykresach, trzeba utworzyć bitmapy pierwszy, a jeśli szukać „Kod: Tworzenie map bitowych w czasie pracy (Visual C#)” na MSDN będziesz znaleźć prosty, ale skuteczny przykład. (Nie mogę opublikować jeszcze dwóch linków)

Zasadniczo musisz dodać kolumnę, która jest traktowana jak obraz, a następnie pomalować obraz przez zdarzenie formatowania komórek. Można wcześniej tworzyć i buforować obrazy lub tworzyć je w locie (preferencje). Drugi artykuł powinien pomóc w budowaniu małych wykresów.

Aby zmienić kolor, należy zmienić trzeci argument metody wartości zadanej. Na pewno nie jest to najszybsza metoda na rysowanie wykresów, ale na początek wystarczy.

+0

Proszę zobaczyć edycję ... Myślę, że jeśli utworzę około 20000 bitmap (dla 20000 wierszy w datagridview) To zajmie za dużo pamięci –

+0

Rozumiem twój problem. Myślę, że nie musisz tworzyć wszystkich 20000 z nich. Po prostu utwórz mapy bitowe w locie podczas ich wyświetlania. – mhttk

0

Oto krótki przykład kodu, aby przetestować wymagania dotyczące pamięci i wydajności kontrolek. Nie widzę, co powinieneś zrobić, aby uniknąć map bitowych, myślę, że większość kontrolerów zewnętrznych działa w podobny sposób. Jestem pewien, że mój kod można zoptymalizować na kilka sposobów, ale na początek masz kilka. Nie wiem, kiedy chciałoby się mieć 20000 wierszy w siatce, ale i tak żaden użytkownik nie może tego zobaczyć. Być może można wymyślić sposób, aby pokazać podzestawy na raz ..?

Najprawdopodobniej nie należy tworzyć obrazu w obiekcie testowym (ponieważ jest to model danych), ale raczej w warstwie prezentacji (dodałem zdarzenie DataBindingComplete, ponieważ można to wykorzystać do podobnych czynności). to tutaj, ponieważ było łatwiej. Żadne obrazy nie są zapisywane do pliku lub coś w tym stylu.

Utworzono formularz z DataGridView o nazwie dataGridView1.

Jest to kod dla formularza:

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; 

    } 

I stworzył także test-Object zapełnić siatkę:

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; 
      } 
     } 
    } 
1

znacznie łatwiejsze i prostsze, użyj google charts API.

Pod twoją DataGridView po prostu rekurencyjny szablon z tagiem <img> ze specyficznym src.

Na przykład ten kod (broken ponad 2 linie):

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

nie daje następujące:

Wystarczy zmodyfikować sekcję t:50,20,30,65,20 nieznacznie w zależności od danych twoje są wiążące.

Jak to:

<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" /> 
+0

Ps: Wykorzystanie pamięci na serwerze dla grafiki = BRAK –