ZedGraph版本:5.1.4
开发环境:.net2.0,vs2008
在它的内置对象中,linechar对象的x轴的值是跟随值变化的,但是在以周为x轴坐标时,当遇到跨年的问题时,问题就来了,我们希望
50,51,52,1,2,3,4的排列,但是如果这样赋值的话,zedgraph会按照值的大小把其排序:
1,2,3,4,50,51,52
当然不能让这样的事情发生,所以我用了一个绝对的周数来做x轴:
50,51,52,53,54,55,56
但是这样一来,看图片的用户就会很郁闷的去转换你的绝对周到底是相对于哪一年的哪一周。
格式化X轴文本zedgraph只提供了一种方法,我们可以给它加上“周”这个字:
myPane.XAxis.Scale.Format = "0周";
没有效果图,凑合一个Y轴的来看看(myPane.YAxis.Scale.Format = "第0名";):
但是这并不能把显示出来的53周转换成1周,于是想到了去改源代码:
1,在Type.cs中
public enum AxisType
publicenumAxisType
{
/**An ordinary, cartesian axis
Linear,
/**A base 10 log axis
Log,
/**A cartesian axis with calendar dates or times
Date,
/**An ordinal axis with user-defined text labels. An ordinal axis means that
///all data points are evenly spaced at integral values, and the actual coordinate values
///for points corresponding to that axis are ignored. That is, if the X axis is an
///ordinal type, then all X values associated with the curves are ignored.
///
///
///
Text,
/**An ordinal axis with regular numeric labels. An ordinal axis means that
///all data points are evenly spaced at integral values, and the actual coordinate values
///for points corresponding to that axis are ignored. That is, if the X axis is an
///ordinal type, then all X values associated with the curves are ignored.
///
///
Ordinal,
/**An ordinal axis that will have labels formatted with ordinal values corresponding
///to the number of values in each.
///
///
///Thedata points will be evenly-spaced at ordinal locations, and the
///actual data values are ignored.
///
///
DateAsOrdinal,
/**An ordinal axis that will have labels formatted with values from the actual data
///values of the firstin the.
///
///
///Although the tics are labeled with real data values, the actual points will be
///evenly-spaced in spite of the data values. For example, if the X values of the first curve
///are 1, 5, and 100, then the tic labels will show 1, 5, and 100, but they will be equal
///distance from each other.
///
///
LinearAsOrdinal,
/**An exponential axis
Exponent,
/**
///add
///
Weekly
}
枚举类型中添加一个新类型Weekly:
2,在Scale.cs文件中,MakeNewScale方法中添加实例化的分支:
MakeNewScale
publicScale MakeNewScale( Scale oldScale, AxisType type )
{
switch( type )
{
caseAxisType.Linear:
returnnewLinearScale( oldScale, _ownerAxis );
caseAxisType.Date:
returnnewDateScale( oldScale, _ownerAxis );
caseAxisType.Log:
returnnewLogScale( oldScale, _ownerAxis );
caseAxisType.Exponent:
returnnewExponentScale( oldScale, _ownerAxis );
caseAxisType.Ordinal:
returnnewOrdinalScale( oldScale, _ownerAxis );
caseAxisType.Text:
returnnewTextScale( oldScale, _ownerAxis );
caseAxisType.DateAsOrdinal:
returnnewDateAsOrdinalScale( oldScale, _ownerAxis );
caseAxisType.LinearAsOrdinal:
returnnewLinearAsOrdinalScale( oldScale, _ownerAxis );
case AxisType .Weekly :
return new WeeklyScale(oldScale, _ownerAxis);
default:
thrownewException("Implementation Error: Invalid AxisType");
}
}
3,添加WeeklyScale.cs文件,内容如下:
Code
//============================================================================
//ZedGraph Class Library - A Flexible Line Graph/Bar Graph Library in C#
//Copyright ?2005 John Champion
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public
//License along with this library; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//=============================================================================
usingSystem;
usingSystem.Collections;
usingSystem.Text;
usingSystem.Drawing;
usingSystem.Runtime.Serialization;
usingSystem.Security.Permissions;
namespaceZedGraph
{
/**
///The WeeklyScale class inherits from theclass, and implements
///the features specific to.
///
///
///Weekly is an ordinal axis that will have labels formatted with values from the actual data
///values of the firstin the.
///Although the tics are labeled with real data values, the actual points will be
///evenly-spaced in spite of the data values. For example, if the X values of the first curve
///are 1, 5, and 100, then the tic labels will show 1, 5, and 100, but they will be equal
///distance from each other.
///
///
///John Champion
///$Revision: 1.10 $ $Date: 2007/04/16 00:03:02 $
[Serializable]
classWeeklyScale : Scale, ISerializable//, ICloneable
{
constructors#regionconstructors
/**
///Default constructor that defines the owner
///(containing object) for this new object.
///
///The owner, or containing object, of this instance
publicWeeklyScale(Axis owner)
:base(owner)
{
}
/**
///The Copy Constructor
///
///Theobject from which to copy
///Theobject that will own the
///new instance of
publicWeeklyScale(Scale rhs, Axis owner)
:base(rhs, owner)
{
}
/**
///Create a new clone of the current item, with a new owner assignment
///
///The newinstance that will be
///the owner of the new Scale
///A newclone.
publicoverrideScale Clone(Axis owner)
{
returnnewWeeklyScale(this, owner);
}
#endregion
properties#regionproperties
/**
///Return thefor this, which is
///.
///
publicoverrideAxisType Type
{
get
{returnAxisType.Weekly; }
}
#endregion
methods#regionmethods
/**
///Select a reasonable ordinal axis scale given a range of data values, with the expectation that
///linear values will be displayed.
///
///
///This method only applies totype axes, and it
///is called by the generalmethod. For this type,
///the first curve is the "master", which contains the dates to be applied.
///On Exit:
///is set to scale minimum (if= true)
///is set to scale maximum (if= true)
///is set to scale step size (if= true)
///is set to scale minor step size (if= true)
///is set to a magnitude multiplier according to the data
///is set to the display format for the values (this controls the
///number of decimal places, whether there are thousands separators, currency types, etc.)
///
///A reference to theobject
///associated with this
///
///A graphic device object to be drawn into. This is normally e.Graphics from the
///PaintEventArgs argument to the Paint() method.
///
///
///The scaling factor to be used for rendering objects. This is calculated and
///passed down by the parentobject using the
///method, and is used to proportionally adjust
///font sizes, etc. according to the actual size of the graph.
///
///
///
overridepublicvoidPickScale(GraphPane pane, Graphics g,floatscaleFactor)
{
//call the base class first
base.PickScale(pane, g, scaleFactor);
//First, get the date ranges from the first curve in the list
doublexMin;//= Double.MaxValue;
doublexMax;//= Double.MinValue;
doubleyMin;//= Double.MaxValue;
doubleyMax;//= Double.MinValue;
doubletMin=0;
doubletMax=1;
foreach(CurveItem curveinpane.CurveList)
{
if((_ownerAxisisY2Axis&&curve.IsY2Axis)||
(_ownerAxisisYAxis&&!curve.IsY2Axis)||
(_ownerAxisisX2Axis&&curve.IsX2Axis)||
(_ownerAxisisXAxis&&!curve.IsX2Axis))
{
curve.GetRange(outxMin,outxMax,outyMin,outyMax,false,false, pane);
if(_ownerAxisisXAxis||_ownerAxisisX2Axis)
{
tMin=xMin;
tMax=xMax;
}
else
{
tMin=yMin;
tMax=yMax;
}
}
}
doublerange=Math.Abs(tMax-tMin);
//Now, set the axis range based on a ordinal scale
base.PickScale(pane, g, scaleFactor);
OrdinalScale.PickScale(pane, g, scaleFactor,this);
SetScaleMag(tMin, tMax, range/Default.TargetXSteps);
}
/**
///Make a value label for an.
///
///
///A reference to theobject that is the parent or
///owner of this object.
///
///
///The zero-based, ordinal index of the label to be generated. For example, a value of 2 would
///cause the third value label on the axis to be generated.
///
///
///The numeric value associated with the label. This value is ignored for log ()
///and text () type axes.
///
///The resulting value label as a
overrideinternalstringMakeLabel(GraphPane pane,intindex,doubledVal)
{
if(_format==null)
_format=Scale.Default.Format;
doublescaleMult=Math.Pow((double)10.0, _mag);
if((dVal/scaleMult-(DateTime.Now.Year-2007)*52)>0)
returnstring.Format("{0:yy}年第{1}周", DateTime.Now,
(dVal/scaleMult-(DateTime.Now.Year-2007)*52).ToString(_format));
else
returnstring.Format("{0:yy}年第{1}周", DateTime.Now.AddYears(-1),
(dVal/scaleMult).ToString(_format));
}
#endregion
Serialization#regionSerialization
/**
///Current schema value that defines the version of the serialized file
///
publicconstintschema2=10;
/**
///Constructor for deserializing objects
///
///Ainstance that defines the serialized data
///
///Ainstance that contains the serialized data
///
protectedWeeklyScale(SerializationInfo info, StreamingContext context)
:base(info, context)
{
//The schema value is just a file version parameter. You can use it to make future versions
//backwards compatible as new member variables are added to classes
intsch=info.GetInt32("schema2");
}
/**
///Populates ainstance with the data needed to serialize the target object
///
///Ainstance that defines the serialized data
///Ainstance that contains the serialized data
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
publicoverridevoidGetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("schema2", schema2);
}
#endregion
}
}
4,在web代码中只加一句:
myPane.XAxis.Type=AxisType.Weekly;
就可以了:
PS:在官方网站上其实有另外一个方法,就是重写XAixs的ScaleFormatEvent 方法:自定义刻度的格式
文中指出,在使用中加入如下代码:
z1.GraphPane.XAxis.ScaleFormatEvent+=newAxis.ScaleFormatHandler( XScaleFormatEvent );
就可以重写刻度显示:
publicstringXScaleFormatEvent( GraphPane pane, Axis axis,doubleval,intindex )
{
return(val+50).ToString();
}
但是我无论如何也找不到z1.GraphPane.XAxis后面的ScaleFormatEvent 事件,也许我使用的版本已经不支持这样的写法了?
希望本文能对您有所帮助
fhmsha