首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
yjz0065 (115)
iiprogram (70)
ShowLong (2)
coofucoo (106)
psyl (153)
capsicum29 (8)
qdzx2008 (51)
cyp403 (16)
lphpc (31)
smallnest (63)
CSDN - 文档中心 - 其他开发语言 阅读:3379   评论: 0    参与评论
标题   源码推荐:一个使用C#绘制图形引擎的Framework     选择自 ghj1976 的 Blog
关键字   源码推荐:一个使用C#绘制图形引擎的Framework
出处   http://www.chinaasp.com/

 


                           Batman
    下面将推荐一个可以很方便的生成多种图形格式的,使用了ASP+技术的图形
引擎代码。它的主要描述如下:
1.可以生成的图形文件格式支持BMP
  EMF,GIF,Icon,JPEG,PNG,TIFF,WMF
2.在文件ChartEngine.cs中为这个图形引擎的大量关键代码
  StockPicker.aspx文件是一个使用该引擎绘图的例子
3.要使用这个图形引擎,需要把所有的代码文件复制到你的web的某个
运用目录(注:不是普通目录)中,然后在该目录下建立一个bin目录,
然后运行mk.bat
4.ImageGenerator_VB.asp文件的头使用了<%@ Page ContentType="image/jpeg"
  %>来说明生成的是某种格式的图形文件
5.为了服务器性能考虑,还可以在ImageGenerator_VB.asp中增加以下代码
<%@ OutputCache Duration="60" %>,该代码可以将生成的图形文件缓存起来
这样如果网站访问量大时,可以大大减轻服务器的负担

    好了,废话少说,大家可以自己研究研究代码:
1.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 = DateTime.ToString(DateTime.Now) ;

            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);

            }

        }

    }

}

2.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" %>
<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.White
            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 Is Nothing) then
           for i=0 to Symbols.Length-1
              Dim stockValue as ChartLine = GetStockDetails(symbols(i).ToLower)
              if (stockValue <> noting) 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>

3.StockPicker.aspx文件
<script language="C#" runat=server>
   void ChartBtn_Click(Object sender, EventArgs e) {
      chart.ImageUrl = "ImageGenerator_Vb.aspx?";
      chart.Visible = true;
      foreach(ListItem item in Stocks.Items) {
         if (item.Selected == true) {
            chart.ImageUrl += "symbols=" + item.Value + "&";
         }
      }
   }
</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>

4.mk.bat文件
csc /t:library /debug+ /out:bin\chartgen.dll ChartEngine.cs /r:System.Web.dll /r:System.Winforms.dll /r:System.Drawing.dll /r:System.dll

 


相关文章
对该文的评论