Grafikk
Børre Stenseth
Moduler>Websites>Webhistogram

Histogram

Hva
Produksjon og oppdatering av et bilde

Vi skal lage en enkel vevside som tar et antall heltall og framstiler et histogram.

screen

Fila Default.aspx definerer det bildet vi skal vise fram slik:

<asp:Image ID="Image1" runat="server" ImageUrl="bildetest.gif" AlternateText="Histogram" Width="286px" Height="271px"/>

Default.aspx er i sin helhet slik:

<%@ Page Language="C#" AutoEventWireup="true"  
         CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Histogram</title>
</head>
<body>
<h1>Lag histogram</h1>
    <form id="form1" runat="server">
    <table>
    <tr>
    <td><div>
    <asp:TextBox ID="TextBox1" runat="server" Rows="12" 
                 TextMode="MultiLine" 
                 Font-Size="Large" Width="128px"></asp:TextBox>    
    </div>
    <div>        
        <asp:Button ID="Button1" runat="server" Text="Lag histogram" 
            onclick="Button1_Click" />
    </div>
    </td>
    <td>
        <asp:Image ID="Image1" runat="server" 
                   ImageUrl="~/bilde.gif"  
                   AlternateText="Histogram"
                   Width="286px" Height="271px"/>
    </td>
    </tr>
    </table>
    <div>
        <asp:Label ID="LabelMsg" runat="server" Text=":">
        </asp:Label>
    </div>
    </form>
</body>
</html>

Kodefila, default.aspx.cs definerer et konstant filnavn:

protected String BildeFilename = "bildetest.gif";

Det er laget to rutiner for å administrere selve bildefila:

protected void DeletFile()
{
    // make sure we have permission to to this
    try
    {
        File.Delete(BildeFile);
    }
    catch (Exception dex)
    {
        LabelMsg.Text = dex.Message;
    }
}

For å unngå at vi kommer opp med gamle data når vevsiden åpnes er følgende lagt inn i Page_Load.

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            DeletFile();
    }

Hovelogikken ligger i koden bak button "Lag histogram":

protected void Button1_Click(object sender, EventArgs e)
{
    // pick up data from textbox and make data
    LabelMsg.Text = ":";
    String[] lines = TextBox1.Text.Split('\r');
    List<int> data = new List<int>(lines.Length);
    try
    {
        foreach (string line in lines)
            if (line.Trim().Length > 0)
                data.Add(Convert.ToInt32(line.Trim()));
   }
   catch (Exception ex)
   {
       DeletFile();
       LabelMsg.Text = "bad format";
       data = null;
   }
    if (data != null)
    {
        // we draw on a bitmap and saves it
        Rectangle Rec = new Rectangle(0, 0,
            Convert.ToInt32(Image1.Width.Value),
            Convert.ToInt32(Image1.Height.Value));
        Bitmap canvas = new Bitmap(Rec.Width, Rec.Height,
            PixelFormat.Format16bppRgb555);
        Graphics cg = Graphics.FromImage(canvas);
        cg.FillRectangle(Brushes.White, Rec);
        // the actual drawing
        drawData(cg, Rec, data);
        // save the drawing as a (temporary) file 
        // make sure permissions on server is sufficient
        try
        {
            canvas.Save(BildeFile, ImageFormat.Gif);
        }
        catch (Exception sex)
        {
            // if image is too large
            // if not write permissions
            LabelMsg.Text = sex.Message;
        }
    }
    Image1.ImageUrl = Rel_BildeFile;
    Image1.AlternateText = "Histogram";
}

Selve uttegningen er slik som i modulen: Histogram

// draw data within Rec on g
private void drawData(Graphics g, Rectangle Rec, List<int> data)
{
    Font tFont = new Font("Arial", 16);
    SolidBrush blueBrush = new SolidBrush(Color.Blue);
    // any data to display
    if ((data==null) ||(data.Count == 0))
    {
        g.DrawString(" Ingen data ",
            tFont,
            blueBrush,
            new Point(10, 4));
    }
    else
    {
        // find max value
        float max = 0.0F;
        foreach (int number in data)
            max = Math.Max((float)number, max);
        // Width of each column, with some margins
        int w =
            (Rec.Width - 10 * data.Count - 20) / data.Count;
        // flip round top and leave some room at top for text
        int txtheight = 20;
        g.ResetTransform();
        g.TranslateTransform(0.0F, Rec.Height);
        g.ScaleTransform(1.0F,
            -1.0F * ((Rec.Height - txtheight) / (max + 1)));
        for (int ix = 0; ix < data.Count; ix++)
        {
            g.FillRectangle(Brushes.Red,
                new Rectangle(10 + ix * (w + 10), 0, w, data[ix]));
        }
        // text it 
        g.ResetTransform();
        g.DrawString("Resultater", 
            tFont, blueBrush, new Point(10, 4));
    }
    g.Flush();
}
Referanser
  • Prosjekt:
    https://svn.hiof.no/svn/psource/Csharpsites/histoweb
  • Modulen: Histogram gjør tilsvarende grafikk på en desktoppapplikasjon.
  • Modulen: Histogram gjør tilsvarende grafikk som en AJAX-løsning.
Vedlikehold

B. Stenseth, januar 2008

(Velkommen) Moduler>Websites>Webhistogram (Kalender)