最近有个项目,客户要求在客户端能动态显示不同年份数据,用折线图来表示,并且单击相关年份能查看详细数据,这里就有个问题放在面前,要从数据库里动态生成折线图,并且不只图,还能友好的操作。
分析了一下,可以通过至少三种技术做到,一是利用
javascript
脚本自身画图功能去实现,服务端的数据可以用
Ajax
来获取,这样就做到了客户端动态画折线图显示各年数据了,但这种方法要求的客户端的脚本代码相对复杂,实现起来有一定的困难。另一种方法是用插件技术实现,比如
flash
或
silverlight
,这种方法表现效果很好,问题是我不是专业的
flash
或
silverlight
手,实现有点难度。最后一种是靠自己的
C#
基本结合
HTML
来完成了。下面说说这种做法。
首先来构建客户端代码:
1<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="
Index.aspx.cs" Inherits="MediaAdSystem.
Index" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>无标题页</title>
8</head>
9<body >
10
11<script language="javascript" type=" text/javascript">
12// <!CDATA[
13//通过滚轮实现对图片的缩放
14function ChangImg(o)
15{
16var zoom=parseInt(o.style.zoom, 10)||100;
17zoom+=event.wheelDelta/12;
18if (zoom>0)
19 o.style.zoom=zoom+ '%';
20 //一个标签显示缩放百分比
21 document .getElementById ("bfb").innerHTML =Math. floor(zoom) +"%";
22return false;
23}
24// ]]>
25</script>
26 <form id="form1" runat="server">
27 <div>
28 </div>
29 <center >
30 < table style="width: 100%;">
31 <tr>
32 <td>
33 第一年:<asp:TextBox ID="TextBox1" runat="server">90</asp:TextBox>
34 </td>
35 <td>
36 第二年:<asp:TextBox ID="TextBox2" runat="server">46</asp:TextBox>
37 </td>
38 <td>
39 第三年:<asp:TextBox ID="TextBox3" runat="server">23</asp:TextBox>
40 </td>
41 </tr>
42 <tr>
43 <td>
44 第四年:<asp:TextBox ID="TextBox4" runat="server">123</asp:TextBox>
45 </td>
46 <td>
47 第五年:<asp:TextBox ID="TextBox5" runat="server">56</asp:TextBox>
48 </td>
49 <td>
50 第六年:<asp:TextBox ID="TextBox6" runat="server">333</asp:TextBox>
51 </td>
52 </tr>
53 </ table>
54 <span id="bfb">100%</span><asp:Button ID="Button6" runat="server" Text="生成图表" />
55 <br />
56 <asp:ImageMap ID="ImageMap1" onmousewheel=" return ChangImg(this)" runat="server">
57 </asp:ImageMap>
58 </center>
59 </form>
60 </body>
61</html>
62
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>无标题页</title>
8</head>
9<body >
10
11<script language="javascript" type=" text/javascript">
12// <!CDATA[
13//通过滚轮实现对图片的缩放
14function ChangImg(o)
15{
16var zoom=parseInt(o.style.zoom, 10)||100;
17zoom+=event.wheelDelta/12;
18if (zoom>0)
19 o.style.zoom=zoom+ '%';
20 //一个标签显示缩放百分比
21 document .getElementById ("bfb").innerHTML =Math. floor(zoom) +"%";
22return false;
23}
24// ]]>
25</script>
26 <form id="form1" runat="server">
27 <div>
28 </div>
29 <center >
30 < table style="width: 100%;">
31 <tr>
32 <td>
33 第一年:<asp:TextBox ID="TextBox1" runat="server">90</asp:TextBox>
34 </td>
35 <td>
36 第二年:<asp:TextBox ID="TextBox2" runat="server">46</asp:TextBox>
37 </td>
38 <td>
39 第三年:<asp:TextBox ID="TextBox3" runat="server">23</asp:TextBox>
40 </td>
41 </tr>
42 <tr>
43 <td>
44 第四年:<asp:TextBox ID="TextBox4" runat="server">123</asp:TextBox>
45 </td>
46 <td>
47 第五年:<asp:TextBox ID="TextBox5" runat="server">56</asp:TextBox>
48 </td>
49 <td>
50 第六年:<asp:TextBox ID="TextBox6" runat="server">333</asp:TextBox>
51 </td>
52 </tr>
53 </ table>
54 <span id="bfb">100%</span><asp:Button ID="Button6" runat="server" Text="生成图表" />
55 <br />
56 <asp:ImageMap ID="ImageMap1" onmousewheel=" return ChangImg(this)" runat="server">
57 </asp:ImageMap>
58 </center>
59 </form>
60 </body>
61</html>
62
客户端主要是数据的录入,和
Img
图片标签的展示。我们发现,这里用的是
ImageMap
,并非普通的
Image
,这是因为我们要用到
ImageMap
的
Map
的功能,通过点击相应年进入该年的详细信息页面。还有一点就是我们可以从
JS
的函数中能得到图片的缩放比例,显示在一个
id
为
bfb
的
span
标签上。
下来我们就把客户端的数据,通过后台代码生成
ImageMap:
1protected void Button1_Click(object sender, EventArgs e)
2 {
3 int[] intarr = new int[6] { int.Parse(TextBox1. Text), int.Parse(TextBox2. Text), int.Parse(TextBox3. Text) ,
4 int.Parse(TextBox4. Text), int.Parse(TextBox5. Text), int.Parse(TextBox6. Text) };
5 int step = 80;
6 //画热点的图形
7 for ( int i = 0; i < 6; i++)
8 {
9 CircleHotSpot Circ = new CircleHotSpot();
10 Circ.Radius = 5;
11 Circ.X = i*step+10;
12 Circ.Y = 340 - intarr[i];
13 Circ.NavigateUrl = "http://www.baidu.com? year="+i;
14 Circ.AlternateText = i.ToString ();
15 Circ.Target = "_blank";
16 ImageMap1.HotSpots. Add(Circ);
17 }
18 ImageMap1.ImageUrl = "image1.aspx?c1=" + TextBox1. Text + "&c2=" + TextBox2. Text + "&c3=" + TextBox3. Text + "&c4=" + TextBox4. Text + "&c5=" + TextBox5. Text + "&c6=" + TextBox6. Text;
19 }
20
2 {
3 int[] intarr = new int[6] { int.Parse(TextBox1. Text), int.Parse(TextBox2. Text), int.Parse(TextBox3. Text) ,
4 int.Parse(TextBox4. Text), int.Parse(TextBox5. Text), int.Parse(TextBox6. Text) };
5 int step = 80;
6 //画热点的图形
7 for ( int i = 0; i < 6; i++)
8 {
9 CircleHotSpot Circ = new CircleHotSpot();
10 Circ.Radius = 5;
11 Circ.X = i*step+10;
12 Circ.Y = 340 - intarr[i];
13 Circ.NavigateUrl = "http://www.baidu.com? year="+i;
14 Circ.AlternateText = i.ToString ();
15 Circ.Target = "_blank";
16 ImageMap1.HotSpots. Add(Circ);
17 }
18 ImageMap1.ImageUrl = "image1.aspx?c1=" + TextBox1. Text + "&c2=" + TextBox2. Text + "&c3=" + TextBox3. Text + "&c4=" + TextBox4. Text + "&c5=" + TextBox5. Text + "&c6=" + TextBox6. Text;
19 }
20
代码中的
for
语句用来生成热点,热点的个数决定于数据。
1using System;
2using System.Collections;
3using System.Configuration;
4using System.Data;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.HtmlControls;
9using System.Web.UI.WebControls;
10using System.Web.UI.WebControls.WebParts;
11using System.Drawing;
12using System.Drawing.Drawing2D;
13using System.Drawing.Imaging;
14
15public partial class image1 : System.Web.UI.Page
16{
17 protected void Page_Load(object sender, EventArgs e)
18 {
19 DrawMarket();
20 }
21 /**//// <summary>
22 /// 自动画折线图
23 /// </summary>
24 private void DrawMarket()
25 {
26 int[] ZbArr = new int[Request.QueryString. Count];
27 for ( int i = 0; i < ZbArr.Length; i++)
28 {
29 ZbArr[i] = int.Parse(Request.QueryString[i]);
30 }
31 int width = 600, height = 360;
32 Bitmap bm = new Bitmap(width, height);
33 Graphics g = Graphics.FromImage(bm);
34 g.Clear(Color.White);
35 Brush b = new SolidBrush(Color.Green);
36 Pen p = new Pen(Color.Black,1.8f);
37 Pen p1 = new Pen(Color.Green, 2);
38 p.EndCap = LineCap.ArrowAnchor ;
39 //画坐标系
40 g.DrawLine(p, 10, 340, 540, 340);
41 g.DrawLine(p, 10, 340, 10, 10);
42 g.DrawString("年", new Font("宋体", 15, FontStyle.Bold), b, 545, 332);
43 int step = 80;
44 //画折线
45 GraphicsPath graphPath = new GraphicsPath();
46 Point[] point = new Point[ZbArr.Length];
47 for ( int i = 0; i < point.Length; i++)
48 {
49 point[i].X = i * step + 10;
50 point[i].Y = 340 - ZbArr[i];
51 }
52 Pen blackPen = new Pen(Color.Black, 3);
53 graphPath.AddLines(point);
54 g.DrawPath(p, graphPath);
55 //画点
56 for ( int i = 0; i < point.Length; i++)
57 {
58 g.DrawEllipse(p1, point[i].X - 5, point[i].Y - 5, 10, 10);
59 }
60 bm. Save(this.Response.OutputStream, ImageFormat.Jpeg);
61 g.Dispose();
62 bm.Dispose();
63
64 }
65}
66
2using System.Collections;
3using System.Configuration;
4using System.Data;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.HtmlControls;
9using System.Web.UI.WebControls;
10using System.Web.UI.WebControls.WebParts;
11using System.Drawing;
12using System.Drawing.Drawing2D;
13using System.Drawing.Imaging;
14
15public partial class image1 : System.Web.UI.Page
16{
17 protected void Page_Load(object sender, EventArgs e)
18 {
19 DrawMarket();
20 }
21 /**//// <summary>
22 /// 自动画折线图
23 /// </summary>
24 private void DrawMarket()
25 {
26 int[] ZbArr = new int[Request.QueryString. Count];
27 for ( int i = 0; i < ZbArr.Length; i++)
28 {
29 ZbArr[i] = int.Parse(Request.QueryString[i]);
30 }
31 int width = 600, height = 360;
32 Bitmap bm = new Bitmap(width, height);
33 Graphics g = Graphics.FromImage(bm);
34 g.Clear(Color.White);
35 Brush b = new SolidBrush(Color.Green);
36 Pen p = new Pen(Color.Black,1.8f);
37 Pen p1 = new Pen(Color.Green, 2);
38 p.EndCap = LineCap.ArrowAnchor ;
39 //画坐标系
40 g.DrawLine(p, 10, 340, 540, 340);
41 g.DrawLine(p, 10, 340, 10, 10);
42 g.DrawString("年", new Font("宋体", 15, FontStyle.Bold), b, 545, 332);
43 int step = 80;
44 //画折线
45 GraphicsPath graphPath = new GraphicsPath();
46 Point[] point = new Point[ZbArr.Length];
47 for ( int i = 0; i < point.Length; i++)
48 {
49 point[i].X = i * step + 10;
50 point[i].Y = 340 - ZbArr[i];
51 }
52 Pen blackPen = new Pen(Color.Black, 3);
53 graphPath.AddLines(point);
54 g.DrawPath(p, graphPath);
55 //画点
56 for ( int i = 0; i < point.Length; i++)
57 {
58 g.DrawEllipse(p1, point[i].X - 5, point[i].Y - 5, 10, 10);
59 }
60 bm. Save(this.Response.OutputStream, ImageFormat.Jpeg);
61 g.Dispose();
62 bm.Dispose();
63
64 }
65}
66
这种画图的效果相对来说明了,但出来的图的效果不是太好,需要进一步优化。
本文转自桂素伟51CTO博客,原文链接:http://blog.51cto.com/axzxs/149938
,如需转载请自行联系原作者