| 
             尝试ASP.NET绘图失败后,改用VML来绘制柱状图,饼图和折线图。其中,柱状图又分了两类,普通的柱状图和分组柱状图。调用的函数分别为:drawBars,drawGroupBars,drawPie,drawLines 
            参数说明在注释中有详细的解释。 
            /***************************************** 
            函数名称:VMLImage 函数说明:定义VMLImage类 传入参数:VMLImage的位置参数 left :左边距 top :右边距 width :宽度 height :高度 xDesc :X轴的描述信息 yDesc :Y轴的描述信息 zeroBased:坐标数据是否从0算起 返回:新定义的VMLImage对象 *****************************************/ function VMLImage(left,top,width,height,xDesc,yDesc,zeroBased) { this.left = left; this.top = top; this.width = width; this.height = height; this.xDesc = xDesc; this.yDesc = yDesc; this.position = "bottom"; //控制显示描述信息的位置 this.zeroBased = zeroBased==null?true:zeroBased; return this; } /********************************************************** 函数名称:drawBars 函数说明:绘制柱状图 传入参数: vmlImage :VMLImage对象参数,包含了VML图形的宽度,高度,边距等参数信息 columnWidth :柱状图中每个柱子的宽度 dataDesc :数组,描述每个数据代表的意义描述信息 dataArray :绘制图形的数据值 返回:无 ***********************************************************/ function drawBars(vmlImage,columnWidth,dataDesc,dataArray) { if(dataArray==null||dataArray.length==0) return; offsetLeft = vmlImage.left; offsetTop = vmlImage.top; canvasWidth = vmlImage.width; canvasHeight = vmlImage.height; xDesc = vmlImage.xDesc; yDesc = vmlImage.yDesc; var spaceSpan = 15; //距离坐标轴两端的空间 //只有一组数据的时候居中显示 if(dataArray.length==1) spaceSpan = spaceSpan = (canvasWidth - dataDesc.length * columnWidth )/2; var yCoordCount = 10; //对Y轴进行均分的数目 var maxValue=getMaxValue(dataArray); var minValue =getMinValue(dataArray); var baseValue=0; if(!vmlImage.zeroBased) { baseValue = minValue-((maxValue - minValue)/(yCoordCount-1)); if(baseValue==maxValue) baseValue=0; } var divImage = document.createElement("<div style='z-index:100;' width:"+eval(canvasWidth-50)+"px;height:"+eval(canvasHeight+50)+"px></div>"); var eleRect = null; //画背景图 eleRect = document.createElement("<v:rect style='position:absolute;left:"+offsetLeft+"px;top:"+eval(offsetTop-10)+"px;width:"+canvasWidth+"px;height:"+eval(canvasHeight+10)+"px;z-index:-1' fillcolor='#9cf' stroked='f'></v:rect>"); eleRect.appendChild(document.createElement("<v:fill rotate='t' angle='-45' focus='100%' type='gradient'/>")); divImage.insertBefore(eleRect); //The plus 20px used for end arrow var originalPoint = new Point(offsetLeft,canvasHeight+offsetTop); var xEndPoint = new Point(offsetLeft + canvasWidth + 20,originalPoint.y); var yEndPoint = new Point(offsetLeft,offsetTop-20); var eleShape = null; var eleTextBox = null; //画横坐标轴 X轴 var eleLine = document.createElement("<v:line alt='' style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+"px,"+originalPoint.y+"px' to='"+xEndPoint.x+"px,"+xEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke endarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注X轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+canvasWidth) + "px;top:" + eval(offsetTop+canvasHeight+10) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + xDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); //画纵坐标轴 Y轴 eleLine = document.createElement("<v:line alt='' style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+","+originalPoint.y+"px' to='"+yEndPoint.x+"px,"+yEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke startarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注Y轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+10) + "px;top:" + eval(offsetTop-30) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + yDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); //画三维背景 cornerPoint.x=280 cornerPoint.y=240 var cornerPoint = new Point(offsetLeft + 10, canvasHeight + offsetTop - 10); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+cornerPoint.x+"px,"+eval(offsetTop-10)+"px' to='"+cornerPoint.x+"px,"+cornerPoint.y+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' to='"+offsetLeft+"px,"+cornerPoint.y+"px' from='"+cornerPoint.x+"px,"+eval(offsetTop+canvasHeight)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+cornerPoint.x+"px,"+cornerPoint.y+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+cornerPoint.y+"px' strokecolor='#69f'/>")); //画纵坐标 Y轴,均分为10等份 var stepHeight = canvasHeight / yCoordCount; var leftEnd = offsetLeft -8;//坐标刻度的长度 divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+eval(offsetTop-10)+"px' to='"+eval(offsetLeft+10)+"px,"+eval(offsetTop)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+eval(offsetLeft+10)+"px,"+eval(offsetTop-10)+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+eval(offsetTop-10)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+offsetTop+"px' to='"+leftEnd+"px,"+eval(offsetTop)+"px'/>")); for(var i=1;i< yCoordCount ;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i -10 ; divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+spanHeight+"px' to='"+eval(offsetLeft+10)+"px,"+eval(spanHeight+10)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+eval(offsetLeft+10)+"px,"+spanHeight+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+spanHeight+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+eval(spanHeight+10)+"px' to='"+leftEnd+"px,"+eval(spanHeight+10)+"px'/>")); } /****************************** 画柱状图的主体部分 ******************************/ //获得数据的缩放比率 if(baseValue>0) maxValue -= baseValue; var ratio = canvasHeight/ maxValue; var newData = resetValue(ratio,baseValue,dataArray); /********************************************** 标示数据在坐标轴 **********************************************/ var stepValue = maxValue / yCoordCount; for(var i=0;i<=yCoordCount;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i -10 ; eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft-70) + "px;top:" + spanHeight + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='right'>" + Math.round(eval(stepValue*i+baseValue)) + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); } //柱子的数目 var columnCount = dataArray.length; //获得柱子之间的间距 var columnSpan=null; if(columnCount==1) columnSpan=spaceSpan; else columnSpan = (canvasWidth - spaceSpan*2 - columnCount * columnWidth)/(columnCount-1); //起画点坐标 var leftStart = offsetLeft + spaceSpan; for(var i=0;i<columnCount;i++) { var topVal = canvasHeight + offsetTop - newData[i]; var heightVal = newData[i]; var columnColor = getColor(i); var eleRect = document.createElement("<v:rect style='position:absolute;left:"+leftStart+"px;top:"+topVal+"px;width:"+columnWidth+";height:"+heightVal+"px;z-index:1' fillcolor='"+columnColor.color1+"'></v:rect>"); eleRect.appendChild(document.createElement("<v:fill color2='"+columnColor.color2+"' rotate='t' type='gradient'/>")); eleRect.appendChild(document.createElement("<o:extrusion v:ext='view' backdepth='20pt' color='"+columnColor.color1+"' on='t'/>")); //画柱状图上面的数据 eleShape = document.createElement("<v:shape style='position:absolute;left:"+leftStart+"px;top:" +eval(topVal-25)+ "px;width:" + (columnWidth+15) + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='center'>" + dataArray[i] + "</td></tr></table>"; eleShape.appendChild(eleTextBox);   divImage.appendChild(eleRect); 
            divImage.appendChild(eleShape); //画柱状图下面标示的名称 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(leftStart - columnWidth/2) + "px;top:" + eval(canvasHeight + offsetTop) + "px;width:" + eval(columnWidth+columnSpan) + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML= "<table cellspacing='3' cellpadding='0'><tr><td align='center'>" + dataDesc[i] + "</td></tr></table>" eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); leftStart += columnWidth+columnSpan; } document.body.appendChild(divImage); } /********************************************************** 
            函数名称:drawGroupBars 函数说明:绘制分组柱状图 传入参数: vmlImage :VMLImage对象,包含了宽度,高度,边距等参数 columnWidth :柱状图中每个柱子的宽度 dataDesc :数据信息描述 groupDesc :分组信息描述 dataArray :二维数组,内容为分组数据的数组 返回:无 ***********************************************************/ function drawGroupBars(vmlImage,columnWidth,dataDesc,groupDesc,dataArray) { if(dataArray==null || dataArray.length==0) return; offsetLeft = vmlImage.left; offsetTop = vmlImage.top; canvasWidth = vmlImage.width; canvasHeight = vmlImage.height; xDesc = vmlImage.xDesc; yDesc = vmlImage.yDesc; var spaceSpan = 15; //距离坐标轴两端的空间 //只有一组数据的时候居中显示 if(dataArray.length==1) spaceSpan = spaceSpan = (canvasWidth - dataDesc.length * columnWidth )/2; var yCoordCount = 10; //对Y轴进行均分的数目 var maxValue=0; for(var i=0;i<dataArray.length;i++) { var tmpMaxValue = getMaxValue(dataArray[i]); if(tmpMaxValue > maxValue) maxValue = tmpMaxValue; } var minValue =dataArray[0][0]; for(var i=0;i<dataArray.length;i++) { var tmpMinValue = getMinValue(dataArray[i]); if(tmpMinValue < minValue) minValue = tmpMinValue; } //判断是否从0开始算坐标 var baseValue=0; if(!vmlImage.zeroBased) { baseValue = minValue-((maxValue - minValue)/(yCoordCount-1)); if(baseValue==maxValue) baseValue=0; } var divImage = document.createElement("<div style='z-index:100;' width:"+eval(canvasWidth-50)+"px;height:"+eval(canvasHeight+50)+"px></div>"); //画背景图 var eleBackRect = document.createElement("<v:rect style='position:absolute;left:"+offsetLeft+"px;top:"+eval(offsetTop-10)+"px;width:"+canvasWidth+"px;height:"+eval(canvasHeight+10)+"px;z-index:-1' fillcolor='#9cf' stroked='f'></v:rect>"); eleBackRect.appendChild(document.createElement("<v:fill rotate='t' angle='-45' focus='100%' type='gradient'/>")); divImage.insertBefore(eleBackRect); //The plus 20px used for end arrow var originalPoint = new Point(offsetLeft,canvasHeight+offsetTop); var xEndPoint = new Point(offsetLeft + canvasWidth + 20,originalPoint.y); var yEndPoint = new Point(offsetLeft,offsetTop-20); var eleShape=null; var eleTextBox = null; //画横坐标轴 X轴 var eleLine = document.createElement("<v:line alt='' style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+"px,"+originalPoint.y+"px' to='"+xEndPoint.x+"px,"+xEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke endarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注X轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+canvasWidth) + "px;top:" + eval(offsetTop+canvasHeight+10) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + xDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape);  //画纵坐标轴 Y轴 
            eleLine = document.createElement("<v:line alt='' style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+","+originalPoint.y+"px' to='"+yEndPoint.x+"px,"+yEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke startarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注Y轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+10) + "px;top:" + eval(offsetTop-30) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + yDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); //画三维背景 cornerPoint.x=280 cornerPoint.y=240 var cornerPoint = new Point(offsetLeft + 10, canvasHeight + offsetTop - 10); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+cornerPoint.x+"px,"+eval(offsetTop-10)+"px' to='"+cornerPoint.x+"px,"+cornerPoint.y+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' to='"+offsetLeft+"px,"+cornerPoint.y+"px' from='"+cornerPoint.x+"px,"+eval(offsetTop+canvasHeight)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+cornerPoint.x+"px,"+cornerPoint.y+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+cornerPoint.y+"px' strokecolor='#69f'/>")); //画纵坐标 Y轴,均分为10等份 var stepHeight = canvasHeight / yCoordCount; var leftEnd = offsetLeft -8;//坐标刻度的长度 divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+eval(offsetTop-10)+"px' to='"+eval(offsetLeft+10)+"px,"+eval(offsetTop)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+eval(offsetLeft+10)+"px,"+eval(offsetTop-10)+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+eval(offsetTop-10)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+offsetTop+"px' to='"+leftEnd+"px,"+eval(offsetTop)+"px'/>")); for(var i=1;i< yCoordCount ;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i -10 ; divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+spanHeight+"px' to='"+eval(offsetLeft+10)+"px,"+eval(spanHeight+10)+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+eval(offsetLeft+10)+"px,"+spanHeight+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+spanHeight+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+eval(spanHeight+10)+"px' to='"+leftEnd+"px,"+eval(spanHeight+10)+"px'/>")); } /****************************** 画柱状图的主体部分 ******************************/ //获得数据的缩放比率 if(baseValue > 0) maxValue -= baseValue; var ratio = canvasHeight/ maxValue; /********************************************** 标示数据在坐标轴 **********************************************/ var stepValue = maxValue / yCoordCount; for(var i=0;i<=yCoordCount;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i -10 ; eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft-70) + "px;top:" + spanHeight + "px;width:" + 50 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='right'>" + Math.round(eval(stepValue*i + baseValue)) + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); } //绘制柱状图的组数目 var groupCount = groupDesc.length; //每组中包含的柱状图的数目,必须保证每组数据中的数据个数一致!!! var columnCount = dataDesc.length; //获得柱子之间的间距 if(groupCount==1) columnSpan = spaceSpan; else columnSpan = (canvasWidth - spaceSpan*2 - columnCount * columnWidth*groupCount)/(groupCount-1); //起画点坐标 var leftStart = offsetLeft + spaceSpan; for(var i=0;i<dataArray.length;i++) { var oldData = dataArray[i]; var newData = resetValue(ratio,baseValue,oldData); for(var j=0;j<columnCount;j++) { var topVal = canvasHeight + offsetTop - newData[j]; var heightVal = newData[j]; var columnColor = getColor(j); var eleRect = document.createElement("<v:rect style='position:absolute;left:"+leftStart+"px;top:"+topVal+"px;width:"+columnWidth+";height:"+heightVal+"px;z-index:1' fillcolor='"+columnColor.color1+"'></v:rect>"); eleRect.appendChild(document.createElement("<v:fill color2='"+columnColor.color2+"' rotate='t' type='gradient'/>")); eleRect.appendChild(document.createElement("<o:extrusion v:ext='view' backdepth='20pt' color='"+columnColor.color1+"' on='t'/>")); //画柱状图上面的数据 eleShape = document.createElement("<v:shape style='position:absolute;left:"+leftStart+"px;top:" +eval(topVal-25)+ "px;width:" + (columnWidth+15) + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='center'>" + oldData[j] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleRect); divImage.appendChild(eleShape); leftStart += columnWidth; } //画柱状图下面标示的名称 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(leftStart - columnWidth*columnCount) + "px;top:" + eval(canvasHeight + offsetTop) + "px;width:" + eval(columnWidth*columnCount +columnSpan) + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML= "<table cellspacing='3' cellpadding='0'><tr><td align='center'>" + groupDesc[i] + "</td></tr></table>" eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); leftStart += columnSpan; } //显示数据描述信息 var rectWidth = 120; //信息框的长度 if(vmlImage.position.toLowerCase()=="right") { var x1= offsetLeft + canvasWidth; var y1= offsetTop + 30; for(var i=0;i<columnCount;i++) { var color = getColor(i); eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(x1+10)+ "px;top:" + (y1+ i*30) + "px;width:80px;height:" + 30 + "px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + dataDesc[i] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); divImage.appendChild(document.createElement("<v:rect style='position:absolute;left:" + eval(x1+ rectWidth) + "px;top:" + eval(y1+ i * 30 +3) + "px;width:30px;height:20px;z-index:1' fillcolor='" +color.color1 + "'></v:rect>")); } } else { var x1= offsetLeft ; var y1= offsetTop+canvasHeight+30; var rowNum = 1; for(var i=0;i<columnCount;i++) { var color = getColor(i); eleShape = document.createElement("<v:shape style='position:absolute;left:" + x1+ "px;top:" + y1 + "px;width:"+eval(rectWidth+40)+"px;height:" + 30 + "px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + dataDesc[i] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); divImage.appendChild(document.createElement("<v:rect style='position:absolute;left:" + eval(x1+rectWidth) + "px;top:" + eval(y1+5) + "px;width:30px;height:20px;z-index:1' fillcolor='" +color.color1 + "'></v:rect>")); if(rectWidth * (i+1) +50 >=canvasWidth) { x1 = offsetLeft; rowNum ++; y1 += rowNum * 30; } else x1 += rectWidth + 50; } } document.body.appendChild(divImage); } /********************************************************** 函数名称:drawLines 函数说明:画折线图 传入参数: vmlImage :VMLImage对象,包含图形的宽度,高度,边距参数 dataDesc :数据信息描述 groupDesc :分组信息描述 dataArray :二维数组,内容保存点数据的数组 返回:无 ***********************************************************/ function drawLines(vmlImage,dataDesc,groupDesc,dataArray) { if(dataArray==null || dataArray.length==0) return; offsetLeft = vmlImage.left; offsetTop = vmlImage.top; canvasWidth = vmlImage.width; canvasHeight = vmlImage.height; xDesc = vmlImage.xDesc; yDesc = vmlImage.yDesc; var yCoordCount = 10; //对Y轴进行均分的数目 var spaceSpan = 15; //距离坐标轴右端的空间 var maxValue=0; for(var i=0;i<dataArray.length;i++) { var tmpMaxValue = getMaxValue(dataArray[i]); if(tmpMaxValue > maxValue) maxValue = tmpMaxValue; } var minValue =dataArray[0][0]; for(var i=0;i<dataArray.length;i++) { var tmpMinValue = getMinValue(dataArray[i]); if(tmpMinValue < minValue) minValue = tmpMinValue; } //判断是否从0开始算坐标 var baseValue=0; if(!vmlImage.zeroBased) { baseValue = minValue-((maxValue - minValue)/(yCoordCount-1)); if(baseValue==maxValue) baseValue=0; } var divImage = document.createElement("<div style='z-index:100;' width:"+eval(canvasWidth-50)+"px;height:"+eval(canvasHeight+50)+"px></div>"); var eleRect = null; //画背景图 eleRect = document.createElement("<v:rect style='position:absolute;left:"+offsetLeft+"px;top:"+offsetTop+"px;width:"+canvasWidth+"px;height:"+canvasHeight+"px;z-index:-1' fillcolor='#9cf' stroked='f'></v:rect>"); eleRect.appendChild(document.createElement("<v:fill rotate='t' angle='-45' focus='100%' type='gradient'/>")); divImage.appendChild(eleRect); //The plus 20px used for end arrow var originalPoint = new Point(offsetLeft,canvasHeight+offsetTop); var xEndPoint = new Point(offsetLeft + canvasWidth + 20,originalPoint.y); var yEndPoint = new Point(offsetLeft,offsetTop-20); var eleShape=null; var eleTextBox = null; //画横坐标轴 X轴 var eleLine = document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+"px,"+originalPoint.y+"px' to='"+xEndPoint.x+"px,"+xEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke endarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注X轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+canvasWidth) + "px;top:" + eval(offsetTop+canvasHeight+10) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + xDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); //画纵坐标轴 Y轴 eleLine = document.createElement("<v:line alt='' style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+originalPoint.x+","+originalPoint.y+"px' to='"+yEndPoint.x+"px,"+yEndPoint.y+"px'></v:line>"); eleLine.appendChild(document.createElement("<v:stroke startarrow='classic' weight='1px'/>")); divImage.appendChild(eleLine); //标注Y轴的描述 eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft+10) + "px;top:" + eval(offsetTop-30) + "px;width:" + 60 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + yDesc + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); //画纵坐标 Y轴,均分为10等份 var stepHeight = canvasHeight / yCoordCount; var leftEnd = offsetLeft -8;//坐标刻度的长度 for(var i=1;i<= yCoordCount ;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i; divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+spanHeight+"px' to='"+eval(canvasWidth+offsetLeft)+"px,"+spanHeight+"px' strokecolor='#69f'/>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;flip:y;z-index:-1' from='"+offsetLeft+"px,"+spanHeight+"px' to='"+leftEnd+"px,"+spanHeight+"px'/>")); } /****************************** 画折线图的主体部分 ******************************/ //获得数据的缩放比率 var ratio = canvasHeight/ maxValue; /********************************************** 标示数据在纵坐标轴 **********************************************/ if(baseValue>0) maxValue -= baseValue; var stepValue = maxValue / yCoordCount; for(var i=0;i<=yCoordCount;i++) { var spanHeight = offsetTop + canvasHeight - stepHeight*i-10 ; eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(offsetLeft-70) + "px;top:" + spanHeight + "px;width:" + 50 + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML ="<table cellspacing='3' border='0' cellpadding='0' width='100%' height='100%'><tr><td align='right'>" + Math.round(eval(stepValue*i+baseValue)) + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); } //坐标点个数,必须确保所有传入的数组长度一致!!! var dotCount = dataDesc.length; //横坐标之间的坐标点宽度 var stepWidth = (canvasWidth - spaceSpan)/(dotCount-1); //开始画折线 for(var i=0;i<dataArray.length;i++) { var newData = resetValue(ratio,baseValue,dataArray[i]); var color = getColor(i); for(var j=0;j<dotCount-1;j++) { var x1 = offsetLeft+j*stepWidth; var y1 = offsetTop+canvasHeight - newData[j]; var x2 = offsetLeft+(j+1)*stepWidth; var y2 = offsetTop+canvasHeight - newData[j+1]; divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;z-index:1' from='" + x1 + "px," + y1 + "px' to='" + x2 + "px," + y2 + "px' coordsize='21600,21600' strokecolor='" + color.color1 + "' strokeweight='2px'></v:line>")); //在线上打实心点 divImage.appendChild(document.createElement("<v:oval style='position:absolute;left:" + (x1 - 2) + "px;top:" + (y1 - 2) + "px;width:4px;height:4px;z-index:1' fillcolor='" + color.color1 + "' strokecolor='" + color.color1 + "'/>")); } } //在坐标轴下画刻度,标数据 for(var j=0;j<dotCount;j++) { var x1 = offsetLeft+j*stepWidth; var y1 = offsetTop+canvasHeight; divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;z-index:1' from='" + x1 + "px," + y1 + "px' to='" + x1 + "px," + eval(y1+8) + "px' strokecolor='#000000'></v:line>")); eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(x1- stepWidth/2)+ "px;top:" + eval(y1+8) + "px;width:" + stepWidth + "px;height:18px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:shape>"); eleTextBox.innerHTML ="<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='center'>" + dataDesc[j] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); } //显示描述信息 var rectWidth = 120; //信息框的长度 if(vmlImage.position.toLowerCase()=="right") { var x1= offsetLeft + canvasWidth; var y1= offsetTop + 30; for(var i=0;i<groupDesc.length;i++) { var color = getColor(i); eleShape = document.createElement("<v:shape style='position:absolute;left:" + eval(x1+10)+ "px;top:" + (y1+ i*30) + "px;width:80px;height:" + 30 + "px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + groupDesc[i] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); divImage.appendChild(document.createElement("<v:rect style='position:absolute;left:" + eval(x1+ rectWidth) + "px;top:" + eval(y1+ i * 30 +3) + "px;width:30px;height:20px;z-index:1' fillcolor='" +color.color1 + "'></v:rect>")); } } else { var x1= offsetLeft ; var y1= offsetTop+canvasHeight+30; var rowNum = 1; for(var i=0;i<groupDesc.length;i++) { var color = getColor(i); eleShape = document.createElement("<v:shape style='position:absolute;left:" + x1+ "px;top:" + y1 + "px;width:"+eval(rectWidth+40)+"px;height:" + 30 + "px;z-index:1'></v:shape>"); eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' cellpadding='0' width='100%' height='100%'><tr><td align='left'>" + groupDesc[i] + "</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); divImage.appendChild(document.createElement("<v:rect style='position:absolute;left:" + eval(x1+rectWidth) + "px;top:" + eval(y1+5) + "px;width:30px;height:20px;z-index:1' fillcolor='" +color.color1 + "'></v:rect>")); if(rectWidth * (i+1) +50 >=canvasWidth) { x1 = offsetLeft; rowNum ++; y1 += rowNum * 30; } else x1 += rectWidth + 50; } } document.body.appendChild(divImage); } /********************************************************** 函数名称:drawPie 函数说明:画饼状图 传入参数: vmlImage :VMLImage对象,包含图形的宽度,高度和边距参数 dataDesc :数组,描述每个数据代表的意义 dataArray :绘制图形的数据值 返回:无 ***********************************************************/ function drawPie(vmlImage,dataDesc,dataArray) { offsetLeft = vmlImage.left; offsetTop = vmlImage.top; canvasWidth = vmlImage.width; canvasHeight = vmlImage.height;  var dataCount = dataDesc.length; 
            var totalValue = sumArray(dataArray); var divImage = document.createElement("<div style='z-index:100;' width:"+eval(canvasWidth-50)+"px;height:"+eval(canvasHeight+50)+"px></div>"); var PreAngle = 0; var eleShape = null; var eleTextBox = null; for(var i=0;i<dataCount;i++) { var color = getColor(i); eleShape = document.createElement("<v:shape style='position:absolute;left:" + offsetLeft + "px;top:" + offsetTop + "px;width:" + canvasWidth + "px;height:" + canvasHeight + "px;z-index:1' coordsize='1500,1400' o:spt='100' adj='0,,0' path='m750,700ae750,700,750,700," + parseInt(23592960*PreAngle) + "," + parseInt(23592960*dataArray[i]/totalValue) + "xe' fillcolor='" + color.color1 + "' strokecolor='#FFFFFF'></v:shape>"); eleShape.appendChild(document.createElement("<v:fill color2='" + color.color2 + "' rotate='t' focus='100%' type='gradient'/>")); eleShape.appendChild(document.createElement("<v:stroke joinstyle='round'/>")); eleShape.appendChild(document.createElement("<v:formulas/>")); eleShape.appendChild(document.createElement("<v:path o:connecttype='segments'/>")); eleShape.appendChild(document.createElement("<v:extrusion type='view' on='t' backdepth='20' brightness='0.2' rotationangle='0,0' />")); divImage.appendChild(eleShape); PreAngle += dataArray[i] / totalValue; }  var pie = Math.PI; 
            var TempPie = 0; var startX = offsetLeft + canvasWidth/2; var startY = offsetTop + canvasHeight/2; for(var i=0;i<dataCount;i++) { var TempAngle = pie * 2 * (dataArray[i] / (totalValue * 2) + TempPie); var x1 = startX + Math.cos(TempAngle) * canvasWidth * 3/8; var y1 = startY - Math.sin(TempAngle) * canvasHeight * 3/8; var x2 = startX + Math.cos(TempAngle) * canvasWidth * 3/4; var y2 = startY - Math.sin(TempAngle) * canvasHeight * 3/4; if(x2>offsetLeft + canvasWidth/2) { x3 = x2 + 20; x4 = x3; } else { x3 = x2 - 20; x4 = x3 - 100; } divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;z-index:1' from='" + x1 + "px," + y1 + "px' to='" + x2 + "px," + y2 + "px' coordsize='21600,21600' strokecolor='#111111' strokeweight='1px'></v:line>")); divImage.appendChild(document.createElement("<v:line style='position:absolute;left:0;text-align:left;top:0;z-index:1' from='" + x2 + "px," + y2 + "px' to='" + x3 + "px," + y2 + "px' coordsize='21600,21600' strokecolor='#111111' strokeweight='1px'></v:line>")); eleShape = document.createElement("<v:shape style='position:absolute;left:" + x4 + "px;top:" + (y2 - 10) + "px;width:100px;height:20px;z-index:1'></v:shape>") eleTextBox = document.createElement("<v:textbox inset='0px,0px,0px,0px'></v:textbox>"); eleTextBox.innerHTML = "<table cellspacing='3' border=0 cellpadding='0' width='100%' height='100%'><tr><td align='center'>" + dataDesc[i] + " " + Math.round(parseFloat(dataArray[i] * 100/ totalValue)*100)/100 + "%</td></tr></table>"; eleShape.appendChild(eleTextBox); divImage.appendChild(eleShape); TempPie += dataArray[i]/totalValue; } document.body.appendChild(divImage); } /********************************** 函数名称:Point 函数说明:定义点坐标类 传入参数: 返回: **********************************/ function Point(x,y) { this.x=x; this.y=y; return this; } /********************************** 函数名称:Color 函数说明:定义颜色类 传入参数: 返回: **********************************/ function Color(color1,color2) { this.color1 = color1; this.color2 = color2; return this; } /********************************** 
            函数名称:getMaxValue 函数说明:获得数组中的最大值 传入参数: dataArray:查找最大值的数组 返回:数组中的最大值 **********************************/ function getMaxValue(dataArray) { if(null==dataArray || dataArray.length==0) return 0; var maxValue = 0; for(var i=0;i<dataArray.length;i++) { if(dataArray[i]>maxValue) maxValue = dataArray[i]; } return maxValue; } /********************************** 函数名称:getMinValue 函数说明:获得数组中的最小值 传入参数: dataArray:查找最小值的数组 返回:数组中的最小值 **********************************/ function getMinValue(dataArray) { if(null==dataArray || dataArray.length==0) return null; var minValue = dataArray[0]; for(var i=0;i<dataArray.length;i++) { if(dataArray[i]<minValue) minValue = dataArray[i]; } return minValue; } /********************************** 函数名称:resetValue 函数说明:对数组中的值按比率缩放 传入参数: ratio:比率值 baseValue:要减去的值 dataArray:进行缩放数据的数组 返回:缩放后的新数组 **********************************/ function resetValue(ratio,baseValue,dataArray) { if(null==dataArray || dataArray.length==0) return; var newArray = new Array(); for(var i=0;i<dataArray.length;i++) { newArray[i] = (dataArray[i]-baseValue)*ratio; } return newArray; } /***************************************** 
            函数名称:getColor 函数说明:获取指定位置的颜色值 传入参数:颜色值索引 返回:颜色变量对象 *****************************************/ function getColor(index) { var color = new Color(); switch(index) { case 0: { color.color1 = "#00ff00"; color.color2 = "#d1ffd1"; } break; case 1: { color.color1 = "#ff0000"; color.color2 = "#ffbbbb"; } break; case 2: { color.color1 = "#ff9900"; color.color2 = "#ffbbbb"; } break; return "#ffe3bb"; case 3: { color.color1 = "#33cccc"; color.color2 = "#cff4f3"; } break; case 4: { color.color1 = "#666699"; color.color2 = "#d9d9e5"; } break; case 5: { color.color1 = "#993300"; color.color2 = "#ffc7ab"; } break; case 6: { color.color1 = "#99cc00"; color.color2 = "#ecffb7"; } break; case 7: { color.color1 = "#ff0000"; color.color2 = "#FF0000"; } break; default: return ""; } return color; } /***************************************** 函数名称:sumArray 函数说明:对数组中的值进行求和 传入参数:进行求和的数组 返回:求和后的值 *****************************************/ function sumArray(dataArray) { var sumValue = 0; for(var i=0;i<dataArray.length;i++) sumValue = eval(sumValue+dataArray[i]); return sumValue; }  | 
        ||||
| 
             | 
        ||||
            
  | 
        ||||
| 
            
            
             | 
        ||
| 2005/11/4 | ||||
| ASP.Net绘制柱状图和曲线图示例 | ||||
| 
             本周对ASP.Net绘制图形做了番学习,学会了如何用C#代码在页面上输出代码图形,但是效果不怎么好。示例如下。 
            public class WebForm1 : System.Web.UI.Page 
            { private void Page_Load(object sender, System.EventArgs e) { //This is the interface to outer usage int widthValue = 800; int heightValue = 500; String xTitle,yTitle;    int offsetX = 20; 
            int offsetY = 20; //柱状图之间的间距 int spaceSpan = 15;    xTitle = "Time"; 
            yTitle = "Sum"; Bitmap imgBitmap = new Bitmap(widthValue+5*offsetX,heightValue+offsetY*2,PixelFormat.Format32bppPArgb); Graphics g = Graphics.FromImage(imgBitmap);    g.Clear(Color.Snow); 
            Pen linePen = new Pen(Color.Black); linePen.Width = 2; //Draw Title Font txtFont = new Font("Courier",10,GraphicsUnit.Point); String title= "This is the title to be displayed"; g.DrawString(title,txtFont,Brushes.Blue,new PointF(imgBitmap.Width/2,0));    Point original = new Point(offsetX,heightValue+offsetY); 
            Point xEndPonit = new Point(widthValue+offsetX ,heightValue+offsetY); Point yEndPonit = new Point(offsetX,0); //X coordinate g.DrawLine(linePen,original,xEndPonit); //Y Coordinate g.DrawLine(linePen,original,yEndPonit);    //Draw arrows 
            Point leftArrowStart = new Point(offsetX*3/4 ,offsetY/3); Point rightArrowEnd = new Point(offsetX*5/4,offsetY/3); g.DrawLine(linePen,leftArrowStart,yEndPonit); g.DrawLine(linePen,yEndPonit,rightArrowEnd); Point topArrowStart = new Point(widthValue + offsetX*3/4,heightValue + offsetY*3/4); Point bottomArrowEnd = new Point(widthValue+ offsetX*3/4,heightValue + offsetY*5/4);    g.DrawLine(linePen,topArrowStart,xEndPonit); 
            g.DrawLine(linePen,xEndPonit,bottomArrowEnd); //Draw X-Title g.DrawString(xTitle,txtFont,Brushes.Blue,new PointF(bottomArrowEnd.X -g.MeasureString(xTitle,txtFont).Width,topArrowStart.Y +10)); StringFormat f = new StringFormat(); //f.Alignment = StringAlignment.Center; //Draw Y-Title f.LineAlignment = StringAlignment.Center; g.DrawString(yTitle,txtFont,Brushes.Blue,new PointF(offsetX * 5/3,15),f); //画单个柱状图的代码 //测试数据 /** int[] staticData = new int[]{20,30,80,50,200,120,20,30,80,50,200,120,60,90,140}; int maxValue = MaxValue(staticData); int ratio = heightValue/maxValue; int groupCount = staticData.Length; //柱状图组数 ResetValue(staticData,ratio); int rectWidth = (widthValue - (groupCount +1)*spaceSpan )/ groupCount; Rectangle rect; int startX = offsetX + spaceSpan; //起始坐标点 for(int i=0;i<staticData.Length;i++) { rect = new Rectangle(startX,heightValue +offsetY - staticData[i],rectWidth,staticData[i]); g.DrawRectangle(Pens.Green,rect); g.FillRectangle(Brushes.Green,rect); startX = startX + rectWidth + spaceSpan; } **/ // Type t = dataList.GetType(); // if(t.IsArray) // { // } //画分组柱状图代码 ArrayList dataList = new ArrayList(); int[] data1= new int[]{20,30,50,100}; int[] data2 = new int[]{50,60,30,30}; int[] data3 = new int[]{80,50,60,85}; int[] data4= new int[]{20,30,90,58}; int[] data5 = new int[]{50,60,30,30}; int[] data6 = new int[]{80,50,60,85}; int[] data7= new int[]{20,30,90,58}; dataList.Add(data1); dataList.Add(data2); dataList.Add(data3); dataList.Add(data4); dataList.Add(data5); dataList.Add(data6); dataList.Add(data7); int maxValue = MaxValue(dataList); int ratio = heightValue/maxValue; int groupCount = dataList.Count; //柱状图组数 ResetValue(dataList,ratio); //根据比率画坐标 //Draw X-Grids, The height value is divided into 10 parts int heightStep = heightValue/10; Point point1,point2; for(int i=1;i<=10;i++) { point1 = new Point(offsetX*3/4,offsetY+heightValue - heightStep*i); point2 = new Point(offsetX,point1.Y); g.DrawLine(Pens.Black,point1,point2); String text = maxValue/10*i+""; g.DrawString(text,txtFont,Brushes.Blue,new PointF(-2,point1.Y)); } //画坐标结束    int rectWidth = (widthValue - (groupCount +1)*spaceSpan )/ groupCount; 
            int innerGroupCount = GetInnerGroupCount(dataList); int innerWidth = rectWidth / innerGroupCount; Rectangle rect; int startX = offsetX + spaceSpan; //起始坐标点 for(int i=0;i<dataList.Count;i++) { int[] staticData = (int[])dataList[i]; for(int j=0;j<staticData.Length;j++) { rect = new Rectangle(startX,heightValue +offsetY - staticData[j],innerWidth,staticData[j]); g.DrawRectangle(GetPenColor(j),rect); g.FillRectangle(GetBrushColor(j),rect); startX = startX + innerWidth; } startX = startX + spaceSpan; }    //画曲线 
            Point pnt1 = new Point(200+offsetX,heightValue+offsetY-300); Point pnt2 = new Point(300+offsetX,heightValue+offsetY-500); Point pnt3 = new Point(400+offsetX,heightValue+offsetY-300); Point pnt4 = new Point(600+offsetX,heightValue+offsetY-600); g.DrawCurve(Pens.Purple,new Point[]{pnt1,pnt2,pnt3,pnt4}); //画饼图 g.DrawPie ( Pens.Red , 50 , 50 , 150 , 150 , 0 , 30 ) ; imgBitmap.Save(Response.OutputStream,ImageFormat.Gif); } 代码中涉及到的函数如下: 
            private int MaxValue(int[] data) 
            { int maxValue = 0; for(int i=0;i<data.Length;i++) { if(data[i]>maxValue) maxValue = data[i]; } return maxValue; }   private int MaxValue(ArrayList dataList) 
            { int maxValue = 0; for(int i=0;i<dataList.Count;i++) { int newMaxValue = MaxValue((int[])dataList[i]); if( newMaxValue>maxValue) maxValue = newMaxValue; } return maxValue; } private void ResetValue(int[] data,int ratio) { for(int i=0;i<data.Length;i++) data[i] *= ratio; }   private void ResetValue(ArrayList dataList,int ratio) 
            { for(int i=0;i<dataList.Count;i++) { ResetValue((int[])dataList[i],ratio); } }   private int GetInnerGroupCount(ArrayList dataList) 
            { int groupCount = 0; for(int i=0;i<dataList.Count;i++) { int count = ((int[])dataList[i]).Length; if(count>groupCount) groupCount = count; } return groupCount; } private Pen GetPenColor(int index) { Pen linePen = new Pen(Color.Black); linePen.Width = 1; linePen.CompoundArray = new float[]{0.0F,0.2F}; switch(index) { case 0: linePen.Color = Color.Gray; break; case 1: linePen.Color = Color.Green; break; case 2: linePen.Color = Color.Blue; break; case 3: linePen.Color = Color.Purple; break; } return linePen; } private Brush GetBrushColor(int index) { switch(index) { case 0: return Brushes.Gray; case 1: return Brushes.Green; case 2: return Brushes.Blue; case 3: return Brushes.Purple; } return Brushes.Red; } ------------------------------------------------------------ 
            运行结果见附图。 
             | 
        ||||
| 
             | 
        ||||
            
  | 
        ||||
| 
            
            
             | 
        ||
| 2005/8/27 | ||||
| Persia & Gregorian Convert 公历和伊朗历法转换(Calendar convertor between Persian and Gregorian) | ||||
| 
             /********************************************************** /********************************************************** /********************************************************** function div(a,b) function mod(a,b) function y(r) function m(r) function d(r) ------------------------------------------------- 返回日期值时一定要注意:getYear(),getMonth(),getDate(),而不是使用getDay()! 说明:将公历转换为波斯历(Persian Calendar)时,调用方法calendarToPersian(); 将波斯历转换为公历时,调用方法persianToGregorian(),传入的日期格式为:YYYY-MM-DD,如: calendarToPersian("2005-08-30"); persianToGregorian("1384-06-08"); PS:源码作者保留算法拥有的权利。本人只对原Java代码翻译为Javascript表达。  | 
        ||||
| 
             | 
        ||||
            
  | 
        ||||
| 
            
            
             | 
        ||
| 2005/7/18 | ||||
| Linux学习 | ||||
| 
              设置telnet-server的启动运行 
            telnet server不作为独立的服务器程序运行,而是受xinetd程序的控制,启动配置文件为/etc/xinetd.d/telnet,默认xinetd程序并不启动该服务,可在chkconfig --list看出telnet是关闭的,/etc/xinetd.d/telnet中disable=yes可通过下面的方式启动telnet server: 1) chkconfig telnet on //该命令修改了/etc/xinetd.d/telnet的配置,设置disable=no 2) service xinetd restart 再次chkconfig --list看到telnet server已经启动。 ------------------------------------------------------------ 
            修改Linux 的IP地址: 
            netconfig 
            停止网卡:ifdown eth0 
            启动网卡:ifup eth0 
            查看本机IP地址:ifconfig 
            ------------------------------------------------------------- 
            native2ascii -encoding gb2312 aaa.properties bb.properties ----将GB2312格式的资源文件转换为UTF8格式 
            native2ascii -reverse -encoding gb2312 bb.properties aaa.properties --将UTF8格式的资源文件转换为中文格式 
            
 ---------------------- Linux 中加载NTFS文件系统时需要下载的RPM包位置:  | 
        ||||
| 
             | 
        ||||
            
  | 
        ||||
| 
            
            
             | 
        ||
| 2005/7/14 | ||||
| 炼狱:window.createPopup()弹出提示tips | ||||
| 
             CCBS 系统增加了新的需求,给界面上的Text文本输入框和Select下拉框增加信息提示。 
            对于Text输入框来说,实现起来并不难:重载Text文本框的onmouseover事件,然后显示出Text文本框的title也就可以了。 
            但是,对于Select控件来说就远远没有这么简单了。首先Select本身没有Title属性!无疑增加了实现的难度。 
            在网上找了点资料后,发现window.createPopup()函数可以实现弹出式的tips,而且微软的技术支持网站也有这方面的例子(参见:http://msdn.microsoft.com/workshop/samples/author/dhtml/popup/usingpopup.htm)。但是实现起来并不是那么一帆风顺的事情。 
            首先,window.createPopup()生成的窗口在显示的时候要手动指定该窗口的位置(x,y坐标),窗口的宽度和高度。而显示的内容是变化的,显示的字符串有长有短,窗口的长度和宽度也要跟着变化,如何实现呢? 
            其次,windows网页上的title属性在显示提示信息的时候是永远不会换行的,哪怕你显示的信息超过屏幕的显示范围它也不会顾忌到你的感受。windows标准就是我们的标准,我们也只能仿效了。 
            上面的两个问题着实让我困惑了一阵子,应该说是一个下午吧。不过最后问题还是得到解决了,虽然过程颇有些周折。 
            首先解决的是弹出窗口的指定位置,宽度和高度问题。窗口的位置就是响应鼠标事件的位置,但是该位置一定要区分清楚,鼠标如下几个位置的参数:clientX,clientY;offsetX,offsetY,screenX,screenY,x,y等。(具体每个位置的意义有单独的文章来解释)在这里应该是相对于响应控件的位置,使用的是offsetX,offsetY值。 
            要控制createPopuo()生成的窗口的宽度和高度,必须使用一个比较“土”的方法:首先调用oPopup.show(0,0,width,height)方法,马上获得该窗体的scrollWidth,scrollHeight,然后对该窗体隐藏:oPopup.hide()。获得具体的宽度和高度之后,再在具体的位置上显示真正的提示信息: 
            oPopup.show(x,y,scrollWidth,scrollHeight)。也就是说:在真正显示tips之前要调用一次显示方法获得实际的宽度和高度!这是解决问题的重点!!! 
            让显示的信息不换行的问题解决过程说难也不难,重要的是要能够想到该方法:使用table中的td不允许换行的属性:nowrap,那么包含在td中的内容就会一直显示出来,永远都不会换行了!!! 
            代码的范例如下: 
            var winPopup = window.createPopup(); //Create the window to popup 
            var winstr="<table style=\" border: 1 solid #FFA6CA\" border=\"0\" width=\"100%\" height=\"100%\" cellpadding=\"0\" cellspacing=\"0\" background=\"\" >"; winstr+="<tr><td align=\"center\"><table width=\"100%\" height=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"; winstr+="<tr><td nowrap id=\"tdMsg\" valign=\"center\" style=\"font-size:12px; color: red; face: Tahoma\"></td></tr></table></td></tr></table>"; winPopup.document.body.innerHTML = winstr; var eventElement = null; var xPos = 0; var yPos = 0; var timer = null; /************************************************************************* Function Name:showPopupHelp Description:Popup a window that shows the content of text or select Input Parameter:None Output :None Return:None ***********************************************************************/ function showPopupHelp(helpMsg) { initPopupWindow(helpMsg); eventElement = event.srcElement; xPos= window.event.offsetX; yPos= window.event.offsetY; timer = setTimeout("showPopupWindow()",1000); } /************************************************************************* Function Name:hidePopupHelp Description:Invisible the popup window Input Parameter:None Output :None Return:None ***********************************************************************/ function hidePopupHelp() { clearTimeout(timer); winPopup.hide(); } /************************************************************************* Function Name:initPopupWindow Description:Initilize the popup window,draw the frame Input Parameter:String to show Output :None Return:None ***********************************************************************/ function initPopupWindow(msgstr) { winPopup.document.all('tdMsg').innerText = msgstr; } /************************************************************************* Function Name:showPopupWindow Description:Visible the popup window Input Parameter:None Output :None Return:None ***********************************************************************/ function showPopupWindow() { winPopup.show(0,0,10,10); var h = winPopup.document.body.scrollHeight; var w = winPopup.document.body.scrollWidth; winPopup.hide(); //var w = eventElement.offsetWidth; //var h = winPopup.document.body.scrollHeight; //var x = eventElement.style.left; //var y = eventElement.style.top + eventElement.offsetHeight; var x = xPos + 3; var y = yPos + 3; winPopup.show(x,y,w,h,eventElement); delete eventElement; }  | 
        ||||
| 
             | 
        ||||
            
  | 
        ||||
| 
            
            
             | 
        ||
| 2005/7/6 | 
| 经典网页代码 | 
| 
             1.使网页不能被“另存为”   | 
        
                    
                
                
            
        
浙公网安备 33010602011771号