Grafy vytvořené online byly v „klasickém“ ASP velký problém. Bylo nutné používat externí komponenty, které byly ve valné většině případů komerční. Při použití .NET Frameworku si lze jednoduše vytvořit graf přímo v ASP.NET.

V první řadě musíme „někde“ získat data, ze kterých budeme graf tvořit. Pro ukázku jsem si vybral čtenost jednoho článku na Interval.cz. Před započetím vlastní práce doporučuji shlédnout příklad.

Pokud začneme „od konce“, zjistíme, že v souboru default.htm toho skutečné moc není:

<!doctype html public „-//w3c//dtd html 4.0 transitional//en“ >
<html>
   <head>
      <title>Graf v ASP.NET</title>
   </head>
   <body>
      <img src=’graf.aspx‘ height=’400′ width=’400′>
   </body>
</html>

Pouze tag pro vložení obrázku přičemž cesta k očekávanému obrázku odkazuje na jakýsi soubor graf.aspx, což určitě obrázek nebude.

Nyní už víme jak bude vypadat výsledek a proto se vrhneme s chutí do práce. Data, která chceme prezentovat v grafu, máme uložena v databázi, proto použijeme ADO.NET pro jejich získání. Pokud používáte MS SQL Server 7 a vyšší, můžete bez obav použít třídy určené právě pro něj (jako je v příkladu). Pokud však máte jiný databázový server, budete muset zvolit jiného poskytovatele dat (např. OleDb, ODBC apod.).

const string sqlConnectionString=“Data Source=localhost;User ID=jmeno;Password=heslo;Initial Catalog=jmenodatabaze;“;
SqlConnection conn=new SqlConnection(sqlConnectionString);
conn.Open();
SqlCommand cmd=new SqlCommand(„SELECT Max(shlednuti) As Maximum FROM redaction_shlednuti WHERE IDClanku=1601 and month(Datum)=11 SELECT day(Datum) As Den, Shlednuti FROM redaction_shlednuti WHERE IDClanku=1601 and month(Datum)=11 order by Datum“,conn);
SqlDataReader rdr=cmd.ExecuteReader();

Výše uvedený kód v sobě neskrývá nic neobvyklého, až na jednu drobnost. Povšimněte si prosím řádku kde je vytvářen SQL příkaz. Jak jistě vidíte na první pohled, příkaz obsahuje dva SQL dotazy. SqlDataReader pak obsahuje dvě sady záznamů, mezi kterými se lze přepnout pomocí metody NextResult.

Popisovat detailně postup malování grafu by asi bylo nošením dříví do lesa, a tak pouze uvedu základní kroky, které využijete při tvorbě jakéhokoli obrázku.

const int width = 400, height = 400;
1. Bitmap objBitmap = new Bitmap(width, height);
2. Graphics objGraphics = Graphics.FromImage(objBitmap);
3. // namalovani grafu
4. Response.ContentType = („image/gif“);
5. objBitmap.Save (Response.OutputStream,ImageFormat.Gif);

  1. Vytvořit instanci třídy Bitmap.
  2. Vytvořit instanci třídy Graphics, pomocí jejichž metod pak obrázek nakreslíte (pokud nechcete použít třídu Graphics, nemusíte, pak ale budete obrázek kreslit bod po bodu a bez znalosti deskriptivní geometrie se nehnete z místa).
  3. Namalovat obrázek.
  4. Specifikovat typ dat.
  5. A nakonec vše poslat klientovi.

Zdrojový kód příkladu je myslím dostatečně komentován a pokud se budete chtít dozvědět o použitých objektech ze jmenného prostotu System.Drawing, máte možnost nahlédnout do MSDN

private void Page_Load(object sender, System.EventArgs e)
{
   // připojovací řetězec do SQL serveru
   const string sqlConnectionString=“Data Source=localhost;User ID=sa;Password=asdf;Initial Catalog=INTERVAL;“;
   // vytvoření spojení do databáze
   SqlConnection conn=new SqlConnection(sqlConnectionString);
   conn.Open();
   // provedení výběru dat
   SqlCommand cmd=new SqlCommand(„SELECT Max(shlednuti) As Maximum FROM redaction_shlednuti
      WHERE IDClanku=1601 and month(Datum)=11 SELECT day(Datum) As Den, Shlednuti
      FROM redaction_shlednuti WHERE IDClanku=1601 and month(Datum)=11 order by Datum“,conn);
   SqlDataReader rdr=cmd.ExecuteReader();
   rdr.Read();
   int maximum;
   const int width = 400, height = 400;
   int nulax=50;
   int nulay=30;
   int okrajx=30;
   int hodnot=31;
   maximum=(int) rdr[„Maximum“];
   // přechod na další sadu záznámů
   rdr.NextResult();
   // vytvoření „obrázku“
   Bitmap objBitmap = new Bitmap(width, height);
   Graphics objGraphics = Graphics.FromImage(objBitmap);
   // ramecek kolem grafu
   objGraphics.FillRectangle(new LinearGradientBrush(new Point(10,10),
      new Point(100,100),Color.Red,Color.Blue), 0, 0, width, height);
   // pozadí grafu
   objGraphics.FillRectangle(new SolidBrush(Color.White), 2, 2, width – 4, height – 4);
   // vytvoření os grafu
   objGraphics.DrawLine(new Pen(Color.Black,1),15,height-nulay,width-nulay,height-30);
   objGraphics.DrawLine(new Pen(Color.Black,1),nulax,30,nulax,height-15);
   // nastavíme font pro popis
   Font fontPopis = new Font(„Times New Roman“, 8, FontStyle.Bold);
   // nastavíme formátování textu
   StringFormat stringFormat = new StringFormat();
   stringFormat.Alignment = StringAlignment.Center;
   stringFormat.LineAlignment = StringAlignment.Center;
   // popíšeme na ose NULU
   objGraphics.DrawString(„0“, fontBanner, new SolidBrush(Color.Black),
      new Rectangle(15, height-30, 15,15), stringFormat);
   // údaje na osách budou jiným fontem než jejich průsečík
   fontPopis = new Font(„Tahoma“, 8, FontStyle.Regular);
   int konstanta= (width-nulax-okrajx)/hodnot;
   // vytvoření popisu osy x
   for (int i=1;i<=hodnot;i++)
   {
      int udaj=i*konstanta;
      objGraphics.DrawLine(new Pen(Color.Red,1),nulax+udaj,height-nulay-5,nulax+udaj,height-nulay+5);
      if (i%5 == 0)
      {
         objGraphics.DrawString(i.ToString(), fontPopis, new SolidBrush(Color.Black),
          new Rectangle(nulax-7+udaj, height-nulay+5,16,16),stringFormat);
      }
   }
   int max=maximum+50;
   float konstantay= ((float)height-60)/max;
   int pocetdilku=20;
   int jedendilek=max/pocetdilku;
   // vytvoření popisu osy x
   for (int i=1;i<=max;i++)
   {
      float udaj=i*konstantay;
      if (i%jedendilek==0)
      {
         objGraphics.DrawLine(new Pen(Color.Blue,1),nulax-5 ,height-nulay-udaj,nulax+5,height-nulay-udaj);
         float textik=i;
         objGraphics.DrawString(textik.ToString(), fontPopis,
          new SolidBrush(Color.Black), new Rectangle(nulax-35, height-nulay-7-((int)udaj),30,16),stringFormat);
      }
   }
   objGraphics.FillRectangle(new SolidBrush(Color.Aqua), 5, 5, 200, 16);
   objGraphics.DrawString(System.DateTime.Now.ToShortDateString()+“ „+System.DateTime.Now.ToShortTimeString() ,
    fontBanner, new SolidBrush(Color.Black), new Rectangle(5, 5,200,16),stringFormat);
   // vykresleni hodnot do grafu
   int zacatekx=nulax;
   int zacateky=height-nulay;
   while(rdr.Read())
   {
      int konecx=nulax+(int) rdr[„den“]*konstanta;
      float udajek=(int)rdr[„shlednuti“]*konstantay;
      int konecy=height-nulay-(int)udajek;
      objGraphics.DrawLine(new Pen(Color.Green,1),zacatekx,zacateky,konecx,konecy);
      zacatekx=konecx;
      zacateky=konecy;
   }
   // odeslaní výsledku na klienta
   Response.ContentType = („image/gif“);
   objBitmap.Save (Response.OutputStream,ImageFormat.Gif);
   // zavření spojení do databáze
   rdr.Close();
   conn.Close();
   // uvolnění paměti
   conn.Dispose();
   objGraphics.Dispose();
   objBitmap.Dispose();
   fontPopis.Dispose();
   stringFormat.Dispose();
}

Zdrojové kódy příkladu jsou samozřejmě ke stažení. Pokud si příklad doplníte o možnost předávání parametru (idclanku a měsíc), získáte užitečný modul do redakčního systému pro sledování čtenosti článků.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Žádný příspěvek v diskuzi

Odpovědět