首页 > 编程 > .NET > 正文

用ASP.NET动态生成图像(转2)

2024-07-10 12:58:00
字体:
来源:转载
供稿:网友
stockpicker.aspx:
<script language="vb" runat=server>
   sub chartbtn_click(sender as object, e as eventargs)
      chart.imageurl = "imagegenerator_vb.aspx?"
      chart.visible = true
      for i=0 to stocks.items.count-1
         if (stocks.items(i).selected = true) then
             chart.imageurl = chart.imageurl & "symbols=" & stocks.items(i).value & "&"
         end if
      next
   end sub
</script>
<html>
   <body>
      <form runat=server>
         <h1>scott's stock picker</h1>
         <asp:checkboxlist id="stocks" runat=server>
             <asp:listitem>msft</asp:listitem>
             <asp:listitem>sun</asp:listitem>
         </asp:checkboxlist>
         <asp:button text="chart your selected stocks" onclick="chartbtn_click" runat=server/>
         <hr>
         <asp:image id="chart" imageurl="" visible=false runat=server/>
      </form>
   </body>
</html>

imagegenerator_vb.aspx:
<%@ page language="vb" contenttype="image/jpeg" %>
<%@ import namespace="system.drawing" %>
<%@ import namespace="system.drawing.drawing2d" %>
<%@ import namespace="system.drawing.imaging" %>
<%@ import namespace="chartgenerator" %>
<%@ outputcache duration="10" %>
<script language="vb" runat=server>
    function getstockdetails(symbol as string) as chartline
        dim mychartline as new chartline
        if (symbol = "msft") then
            dim stockvalues() as single = { 60, 110, 120, 180, 185, 190, 240, 290 }
            mychartline.width = 5
            mychartline.color = color.blue
            mychartline.linestyle = dashstyle.solid
            mychartline.title = "microsoft corp. (msft)"
            mychartline.symbol = "msft"
            mychartline.values = stockvalues
            return mychartline
        elseif (symbol = "sun") then
            dim stockvalues() as single = { 180, 155, 125, 60, 25, 15, 10, 3 }
            mychartline.width = 5
            mychartline.color = color.red
            mychartline.linestyle = dashstyle.dot
            mychartline.title = "sun corp. (sun)"
            mychartline.symbol = "sun"
            mychartline.values = stockvalues
            return mychartline
        end if
        return nothing
    end function
    sub page_load(sender as object, e as eventargs)
        ' generate chart data for image....
        dim xaxes() as string = { "9:00am", "9:30am", "10:00am", "11:00am", "12:00am", "1:00pm", "1:30pm" }
        dim mychartdata as new chartdata
        mychartdata.yticksize = 20
        mychartdata.ymax = 250
        mychartdata.ymin = 0
        mychartdata.xaxistitles = xaxes
        dim symbols() as string = request.querystring.getvalues("symbols")
        if (not symbols = nothing) then
           for i=0 to symbols.length-1
              dim stockvalue as chartline = getstockdetails(symbols(i).tolower)
              if (stockvalue <> nothing) then
                 mychartdata.lines.add(stockvalue)
              end if
           next
        end if
        ' create in-memory bitmap of jpeg
        dim mychartengine as new chartengine
        dim stockbitmap as bitmap = mychartengine.drawchart(600, 400, mychartdata)
        ' render bitmap stream back to client
        stockbitmap.save(response.outputstream, imageformat.jpeg)
     end sub
</script>

chartengine.cs:
using system.winforms;
using system.collections;
using system.collections.bases;
using system.drawing;
using system.drawing.drawing2d;
using system.drawing.imaging;
using system.componentmodel;
using system;
using system.io;
namespace chartgenerator  {
    //core line data structure
    public struct linedata {
        public float[] linevalues  ;
        public string linetitle ;
        public string linesymbol ;
    }

    //line data plus display style information
    public class chartline {
        private color linecolor ;
        private linedata linedata ;
        private dashstyle linestyle ;
        private int linewidth  ;
        //constructors
        public chartline() :base() {}
        public chartline(linedata linedata) :base() {
            this.linedata = linedata;
        }
        //properties
        public color color {
            get { return linecolor ; }
            set { linecolor = value ; }
        }
        public dashstyle linestyle {
            get { return linestyle ; }
            set { linestyle = value ; }
        }
        
        public string symbol {
            get { return linedata.linesymbol ; }
            set { linedata.linesymbol = value ; }
        }
        public string title {
            get { return linedata.linetitle ; }
            set { linedata.linetitle = value ; }
        }
        public float[] values {
            get { return linedata.linevalues ; }
            set { linedata.linevalues = value ; }
        }
        public int width {
            get { return linewidth ; }
            set { linewidth = value ; }
        }

        //methods
        public void setlinedata(linedata linedata) {
            this.linedata = linedata;
        }
    }

    //chart data structure
    public class chartdata {
        private float yticksize;
        private float ymax;
        private float ymin;
        private string[] xaxistitles ;
        private chartlinelist lines = new chartlinelist();
        private color gridcolor=color.blue;
        private bool showhgridlines=true;
        private bool showvgridlines=true;
        //properties
        public float yticksize {
            get { return yticksize ; }
            set { yticksize = value ; }
        }
        public float ymax {
            get { return ymax ; }
            set { ymax = value ; }
        }

        public float ymin {
            get { return ymin ; }
            set { ymin = value ; }
        }
        public string[] xaxistitles {
            get { return xaxistitles ; }
            set { xaxistitles = value ; }
        }
        public chartlinelist lines {
            get { return lines ; }
            set { lines = value ; }
        }
        public color gridcolor {
            get { return gridcolor ; }
            set { gridcolor = value ; }
        }
        public bool showhgridlines {
            get { return showhgridlines ; }
            set { showhgridlines = value ; }
        }
        public bool showvgridlines {
            get { return showvgridlines ; }
            set { showvgridlines = value ; }
        }
        //collection of chart lines
        public class chartlinelist : typedcollectionbase {
            public chartline this[int index] {
               get {
                   return (chartline)(list[index]);
               }
               set {
                   list[index] = value;
               }
            }
            public int add(chartline value) {
               return list.add(value);
            }
            public void insert(int index, chartline value) {
               list.insert(index, value);
            }
            public int indexof(chartline value) {
               return list.indexof(value);
            }
            public bool contains(chartline value) {
               return list.contains(value);
            }
            public void remove(chartline value) {
               list.remove(value);
            }
            public void copyto(chartline[] array, int index) {
               list.copyto(array, index);
            }
       }    
    }

    //charting engine - draws a chart based on the given chartdata
    public class chartengine {
        private chartdata chartdata ;
        private float left;
        private float right;
        private float top;
        private float bottom;
        private float tickcount;
        private float ycount;   
        private float hspacing;
        private float vspacing;
        private graphics g;
        private rectangle r;
        private color backcolor;
        private color forecolor;
        private font basefont;
        private font legendfont;
        private rectanglef legendrect;
        public chartengine() {
        }                           
        public bitmap drawchart(int width, int height, chartdata chartdata) {
           bitmap newbitmap = new bitmap(width,height,pixelformat.format32bppargb);
           graphics g = graphics.fromimage(newbitmap);
           rectangle r = new rectangle(0, 0, width, height);
           color myforecolor = color.black;
           color mybackcolor = color.white;
           font myfont = new font("arial", 10);
           this.drawchart(g, r, mybackcolor, myforecolor, myfont, chartdata);
           return newbitmap;
        }
         public void drawchart(graphics g, rectangle r, color backcolor, color forecolor, font basefont, chartdata chartdata) {
            this.chartdata = chartdata;
            this.g = g;
            this.r = r;
            this.backcolor = backcolor;
            this.forecolor = forecolor;
            this.basefont = basefont;
            this.legendfont = new font(basefont.fontfamily, (basefont.size * 2/3), basefont.style | fontstyle.bold);
            g.smoothingmode = smoothingmode.antialias;
            calculatechartdimensions();        
            drawbackground();
            internaldrawchart() ;
        }

        private void calculatechartdimensions() {
            right = r.width - 5;
            top = 5 * basefont.size ;
            bottom = r.height - basefont.size * 2;
            tickcount = chartdata.ymin ;
            ycount = (chartdata.ymax-chartdata.ymin) / chartdata.yticksize ;
            hspacing = (bottom-top) / ycount;
            vspacing = (right) / chartdata.xaxistitles.length;
            //left depends on width of text - for simplicities sake assume that largest yvalue is the biggest
            //take into account the first x axis title
            float maxytextsize = g.measurestring(chartdata.ymax.tostring(), basefont).width;
            float firstxtitle = g.measurestring(chartdata.xaxistitles[0], basefont).width;
            left = (maxytextsize > firstxtitle) ? maxytextsize : firstxtitle ;
            left = r.x + left + 5 ;
            //calculate size of legend box
            float maxlegendwidth = 0 ;
            float maxlegendheight = 0 ;
            //work out size of biggest legend
            foreach (chartline cl in chartdata.lines) {
                float currentwidth = g.measurestring(cl.title, legendfont).width;
                float currentheight = g.measurestring(cl.title, legendfont).height;
                maxlegendwidth = (maxlegendwidth > currentwidth) ? maxlegendwidth : currentwidth ;
                maxlegendheight = (maxlegendheight > currentheight) ? maxlegendheight : currentheight ;
            }
            legendrect = new rectanglef(r.x+2, r.y+2, maxlegendwidth + 25 + 5, ((maxlegendheight+2)*chartdata.lines.count) + 3) ;
        }
        private void drawbackground() {
            lineargradientbrush b = new lineargradientbrush(r, color.steelblue, backcolor,lineargradientmode.horizontal);
            g.fillrectangle(b, r);
            b.dispose();
        }
        private void internaldrawchart() {
             drawgrid() ;
            foreach (chartline cl in chartdata.lines) {
                drawline(cl);
            }
            drawlegend() ;
            //draw time on chart
            string timestring = "generated:" + datetime.now.tolongtimestring() ;
            sizef textsize = g.measurestring(timestring,basefont);
            g.drawstring(timestring, basefont, new solidbrush(forecolor), r.width - textsize.width - 5, textsize.height * 2 / 3) ;
        }                       
        private  void drawgrid() {
            pen gridpen = new pen(chartdata.gridcolor) ;

            //vertical - include tick desc's
            if (chartdata.showvgridlines) {
                for (int i = 0 ; (vspacing * i) < right; i++) {
                    float x = left + (vspacing *i);           
                    string desc = chartdata.xaxistitles[i];
                    g.drawline(gridpen, x,top,x,bottom +(basefont.size*1/3));
                    sizef textsize = g.measurestring(desc,basefont);
                    g.drawstring(desc, basefont, new solidbrush(chartdata.gridcolor), x-(textsize.width/2), bottom + (basefont.size*2/3)) ;
                }
            }
            //horizontal
            if (chartdata.showhgridlines) {
                for (float i = bottom ; i > top; i-=hspacing) {
                    string desc = tickcount.tostring();
                    tickcount+=chartdata.yticksize;
                    g.drawline(gridpen, right, i, left-3, i);
                    sizef textsize = g.measurestring(desc,basefont);
                    g.drawstring(desc, basefont, new solidbrush(chartdata.gridcolor), left-textsize.width - 3, i - (textsize.height/2)) ;
                }
            }
        }
        private void drawline(chartline chartline) {
            pen linepen = new pen(chartline.color);
            linepen.startcap = linecap.round;
            linepen.endcap = linecap.round;
            linepen.width = chartline.width ;
            linepen.dashstyle = chartline.linestyle;
            pointf[] values = new pointf[chartline.values.length];
            float scale = hspacing / chartdata.yticksize ;
            for (int i = 0 ; i < chartline.values.length; i++) {
                float x = left + vspacing * i;           
                values[i] = new pointf(x, bottom-chartline.values[i]*scale);
            }
            g.drawlines(linepen, values);
        }
         private void drawlegend() {
            //draw legend box
            controlpaint.drawborder(g, (rectangle)legendrect, systemcolors.windowframe, buttonborderstyle.solid);
            lineargradientbrush b = new lineargradientbrush(legendrect, backcolor, color.steelblue, lineargradientmode.horizontal);
            r.inflate(-1, -1);
            g.fillrectangle(b, legendrect);
            b.dispose();
            float starty = 5;
            foreach (chartline cl in chartdata.lines) {
                pen p = new pen(cl.color) ;
                p.width = p.width*4;
                sizef textsize = g.measurestring(cl.title, legendfont);
                float liney = starty + textsize.height / 2 ;
                g.drawline(p, r.x + 7, liney, r.x + 25, liney);
                g.drawstring(cl.title, legendfont, new solidbrush(forecolor), r.x + 30, starty);
                starty += (textsize.height+2);
            }
        }
    }
}
菜鸟学堂:
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表