JFreechart的学习记录文档
其中很多内容是原作者的 留在这里只为了方便...
<!-- [if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->
1?定制图表(Customising?Charts)1.1?简介
JFreeChart的设计的定制功能是非常灵活的。我们可以使用非常多的属性来设置我们图表的外观。主要包括以下几个方面
1)pie?charts?(2D?and?3D):饼图(平面和立体)
2)bar?charts?(regular?and?stacked,?with?an?optional?3D?effect):柱状图
?
?
3)line?and?area?charts:曲线图
?
?
?
?
?
4)scatter?plots?and?bubble?charts
5)time?series,?high/low/open/close?charts?and?candle?stick?charts:时序图
?
6)combination?charts:复合图
?
7)Pareto?charts?Pareto图
8)Gantt?charts:甘特图
9)wind?plots,?meter?charts?
?
1.2?图表相关包介绍:
通过ChartFactory的工厂方法可以得到对应图表形式
核心类主要有:
org.jfree.chart.JFreeChart:图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象
org.jfree.data.category.XXXDataSet:数据集对象,用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类
org.jfree.chart.plot.XXXPlot:图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis、Renderer以及数据集对象的支持
Org.jfree.chart.axis.*:用于处理图表的两个轴:纵轴和横轴
Org.jfree.chart.render.*:负责如何显示一个图表对象
Org.jfree.chart.urls.*:用于生成Web图表中每个项目的鼠标点击链接
XXXXXToolTipGenerator:用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类
?
1.3?图表属性
我们可以使用JFreeChart类方法从更高的层次来定制我们图表的外观。可控制的属性有:
在下面的章节中将详细描述这些内容。
JFreeChart可以在图表的外围画出一个边框。默认状态下,JFreeChart是不画出边框的,但我们可以使用方法setBorderVisible()来设置。边框的颜色和线条风格可使用方法setBorderPaint()和setBorderStroke()来控制。
注意:如果我们在一个ChartPanel里面显示我们的图表,那么我们可能更愿意使用Swing提供的边框。
Add:
图表的大小可通过setPreferredSize()来设置参数为Dimension类型;
图表有一个标题,显示在图表的顶部、底部、左侧或右侧(同时,我们也可以添加副标题,见下章讲述)。标题使用一个TextTitle的实例对象。我们可以使用getTitle()方法来获得标题的引用。
修改标题文本(不修改字体和位置)的代码如下:
题头放置在图表的顶部、底部、左侧或右侧的设置,使用标题本书属性设置来完成。下面代码显示的是将标题移植到图表的底部。
如果在我们图表上,我们不希望显示标题,则将标题设置为null即可。
?
Add:
设置标题的字体
可以在初始化的时候使用TextTitle(String?text,?Font?font)构造
也可以使用对象的setFont()方法设置
图表可以拥有任何数量的副标题。添加副标题,需要先创建一个副标题对象(任何Title类的子类),然后将该对象加到图表上即可。代码如下:
我们可以在图表上添加任何数量的副标题,但是紧急我们添加的副标题越多,图表画图的区域就越小。
修改一个已有的副标题,我们需要先获得副标题的一个引用。代码如下:
在我们改变副标题属性之前,我们需要将Title的引用转换成我们需要的适当的子类类型。
我们可以使用getSubtitleCount()方法获得副标题的数量。
Add:
也可以使用getSubtitles()?得到副标题List
可以使用clearSubtitles()清除所有副标题
使用removeSubtitle(Title?title)?移除指定副标题
我们可以使用setBackgroundPaint()方法设置图表的背景颜色(注意,我们也可以设置我们图区的背景颜色,这与图表的背景颜色不同)。例如:
我们可使用Paint接口的任何实现作为背景颜色的设置参数,其中有Color、GradientPaint(渐变颜色)和TexturePaint等。代码如下:
我们可以设置我们的背景颜色为null,这时推荐使用一个背景图片来设置我们的图表。
我们可以使用方法setBackgroundImage()来为我们的图表设置一幅背景图表。
默认的,图片充满图表的整个背景,图片失真。但我们可以使用setBackgroundImageAlignment()方法来改变图片不充满整个背景。代码如下:
使用setBackgroundImageAlpha()方法,我们可以控制图片的透明度。如果我们希望图片只填充我们图表的区域(区域包含轴),那么我们需要将背景图片添加到图表的图区。代码如下(以饼图为例):
JFreeChart使用java2D的API来画图表。在java2D中的API中,我们可以提供绘制建议让绘制引擎绘制图表。JFreeChart允许我们在画图表时,使用setRenderingHints()方法,将绘制建议参数传入java2D的API中。
一般抗锯齿设置代码为
jfreechart.getRenderingHints().put(RenderingHints.KEY_ANTIALIASING,?RenderingHints.VALUE_ANTIALIAS_ON);
或
jfreechart.setRenderingHints(new?RenderingHints(RenderingHints.KEY_ANTIALIASING,?jfreechart));
JFreeChart还提供了一个便利反锯齿开关方法。当反锯齿开关开时,图表会绘制出比较光滑的图表,但是花费的时间要长。代码如下:
JFreeChart画图时,默认为反锯齿开关为开。
Jfreechart可以再绘制图表时增加图例使用addLegend()方法并设置图例位置,默认位置为最上方,并默认时不带边框同样可以使用removeLegend()移除图例
代码如下:
LegendTitle?legendTitle?=?new?LegendTitle(jfreechart.getPlot());//创建图例
legendTitle.setBorder(1,?1,?1,?2);//设置四周的边距,带线框.
legendTitle.setPosition(RectangleEdge.RIGHT);??//设置图例的位置
jfreechart.addLegend(legendTitle);//图表中添加图例
?
图例所拥有的一些其他方法
setBackgroundPaint(Paint?paint)???可设置图例的背景色
setTitle(String?title)????图示标题内容
setTitleFont(Font?font)????图示标题字体
setBoundingBoxArcWidth(int?arcWidth)??图示边界圆角宽
setBoundingBoxArcHeight(int?arcHeight)??图示边界圆角高
setOutlinePaint(Paint?paint)???图示边界线条颜色
setOutlineStroke(Stroke?stroke)???图示边界线条笔触
setDisplaySeriesLines(boolean?flag)??图示项是否显示横线(折线图有效)
setDisplaySeriesShapes(boolean?flag)??图示项是否显示形状(折线图有效)
setItemFont(Font?font)????图示项字体
setItemPaint(Paint?paint)????图示项字体颜色
setAnchor(int?anchor)????图示在图表中的显示位置(参数常量在Legend类中定义)
Jfreechart可以在绘制的图表上增加监听事件,如:addChangeListener(ChartChangeListener?listener)?注册一个用于对图表的变化通知对象,addProgressListener(ChartProgressListener?listener)?注册一个有关的图表事件通知的对象。
同时可以使用removeChangeListener(ChartChangeListener?listener)和?removeProgressListener(ChartProgressListener?listener)移除监听
也可以使用常用的内部类匿名类等方法创建一个进程来监听事件fireChartChanged()方法,此方法可以监听创建图表的时候的数据变化,并对图表进行重绘.
代码如下:
//设置新的数据集
jfreechart.getCategoryPlot().setDataset(createDataset());;
//通知Jfreechart?数据发生了改变,重新绘制柱状图
if?(jfreechart?!=?null)?{
???????jfreechart.fireChartChanged();
}
?
1.4?图区属性
JFreeChart类在绘制图表时,将大部分工作交给了Plot类(图形绘制结构)或Plot的子类。JFreeChart类的getPlot()方法返回了一个图表创建的图区(plot)的引用。
??Plot?plot?=?jfreechart.getPlot();
我们需要将该引用转化成Plot的一个具体子类。例如:
CategoryPlot?plot?=?jfreechart.getCategoryPlot();
??或
??????XYPlot?plot?=?jfreechart.getXYPlot();
注意:如果plot不是相应的类,则在转化的时候,会抛出ClassCastException类型转制异常。
JFreeChart?中有?18?种?Plot?抽象类的具体实现类。?Plot?的具体实现类主要由以下重要对象组成:?Renderer?对象(图形的绘制单元——绘图域)?Datset?(图形的数据源),?DomainAxis?(区域轴,相当于?x?轴),?RangeAxis?(范围轴,相当于?y?轴)。不同的?Plot?对象组成方式不尽相同。比如饼状图相关的?Plot?对象(?MultiplePiePlot?、?PiePlot?、?PiePlot3D?、?RingPlot?)中都不含有?Renderer?对象、?DomainAxis?对象、?RangeAxis?对象。
一般来说,??对象存储数据模型,?Renderer?对象存储显示模型,?Plot?对象根据??对象、?Renderer?对象完成画图操作。
仍以上面的图形讲解?Plot?对象的组成。
上图的中间区域是是一个?XYPlot?对象。其中的折线部分即是图形的绘制单元?Renderer?对象。?X?轴是?DomainAxis?,?y?轴是?RangeAxis?,其中?Datset?对象属于数据模型范畴,是?UI?不可见对象。该图中的?plot?背景色、网格线的各种设置可以通过?XYPlot?对象本身完成。
在图表连接数据确没有数据可显示的可通过设置一些Plot的属性来设置所显示的消息:setNoDataMessage(String?message)???没有数据时显示的消息
setNoDataMessageFont(Font?font)???没有数据时显示的消息字体
setNoDataMessagePaint(Paint?paint)???没有数据时显示的消息颜色
?
对于CategoryPlot类在图表显示数据时刻对数据区的分类轴进行操作达到独特的效果
setDomainAxis(CategoryAxis?axis)???数据区的分类轴
setAxisOffset(Spacer?offset)???坐标轴到数据区的间距
setDomainAxisLocation(AxisLocation?location)?分类轴的位置(参数常量在org.jfree.chart.axis.AxisLocation类中定义)
setDomainGridlinesVisible(boolean?visible)??分类轴网格是否可见
setDomainGridlinePaint(Paint?paint)??分类轴网格线条颜色
setDomainGridlineStroke(Stroke?stroke)??分类轴网格线条笔触
setRangeAxis(ValueAxis?axis)???数据区的数据轴
setRangeAxisLocation(AxisLocation?location)?数据轴的位置(参数常量在org.jfree.chart.axis.AxisLocation类中定义)
setRangeGridlinesVisible(boolean?visible)??数据轴网格是否可见
setRangeGridlinePaint(Paint?paint)???数据轴网格线条颜色
setRangeGridlineStroke(Stroke?stroke)??数据轴网格线条笔触
?
对于PiePlot类在数据区可对饼图和分类标签进行操作
setCircular(boolean?flag)????饼图是否一定是正圆
setStartAngle(double?angle)???饼图的初始角度
setDirection(Rotation?direction)???饼图的旋转方向
setShadowPaint(Paint?paint)???饼图的阴影颜色
setShadowXOffset(double?offset)???饼图的阴影相对图的水平偏移
setShadowYOffset(double?offset)???饼图的阴影相对图的垂直偏移
setPieIndex(int?index)????饼图的索引(复合饼图中用到)
setSectionOutlinePaint(int?section,Paint?paint)?指定分类饼的边框颜色
setSectionOutlineStroke(int?section,Stroke?stroke)?指定分类饼的边框笔触
setSectionPaint(int?section,Paint?paint)??指定分类饼的颜色
setExplodePercent(int?section,double?percent)?抽取的那块(1维数据表的分类下标)以及抽取出来的距离(0.0~1.0),3D饼图无效
setLabelBackgroundPaint(Paint?paint)??分类标签的底色
setLabelFont(Font?font)????分类标签的字体
setLabelPaint(Paint?paint)????分类标签的字体颜色
setLabelLinkMargin(double?margin)???分类标签与图的连接线边距
setLabelLinkPaint(Paint?paint)???分类标签与图的连接线颜色
setLabelLinkStroke(Stroke?stroke)???分类标签与图的连接线笔触
setLabelOutlinePaint(Paint?paint)???分类标签边框颜色
setLabelOutlineStroke(Paint?paint)???分类标签边框笔触
setLabelShadowPaint(Paint?paint)???分类标签阴影颜色
setMaximumLabelWidth(double?width)???分类标签的最大长度(0.0~1.0)
setLabelGenerator(PieSectionLabelGenerator?generator)?分类标签的格式,设置成null则整个标签包括连接线都不显示
PiePlot3D(PiePlot)类:
setDepthFactor(double?factor)???3D饼图的Z轴高度(0.0~1.0)
?
获得Plot后可根据setDataAreaRatio(double?ratio)???设置数据区占整个图表区的百分比
我们可以使用方法setBackgroundPaint()设置图区的背景颜色。例如:
我们可使用Paint接口的任何实现作为背景颜色的设置参数,其中有Color、GradientPaint(渐变颜色)和TexturePaint等。同时,我们也可以设置背景颜色为null。
setBackgroundAlpha(float?alpha)???数据区的背景透明度(0.0~1.0)
setForegroundAlpha(float?alpha)???数据区的前景透明度(0.0~1.0)
setOutLinePaint(Paint?paint)???数据区的边界线条颜色
setOutLineStroke(Stroke?stroke)???数据区的边界线条笔触
我们可以使用方法setBackgroundImage()为图区设置备有图片。
默认的,图片充满图表的整个背景,图片失真。但我们可以改变图片不充满整个背景,使用方法是setBackgroundImageAlignment()。
使用setBackgroundImageAlpha()方法,我们可以控制图片的透明度。如果我们希望图片充满这个图表区域,那么我们需要将背景图片添加到JFreeChart对象上(前面已经介绍过)。
Renderer?对象是图形的绘制单元。?JFreeChart?提供了两个接口?CategoryItemRenderer?和?XYItemRenderer?、?1?个抽象类?AbstractRenderer?供具体的?Renderer?类实现,给出了将近?50?种具体实现类。
一般来说?Renderer?对象可进行的操作有:对?item?label?(下图中的柱状图上的红色数字即为?item?label?的示例)的默认设置(?item?label?的产生方式、是否可见、字体、?Paint?、正反向?item?label?的位置设置等)、绘制图形的边框默认设置(?Paint?、笔画、是否可见等)、绘制图形的默认设置(形状、笔画、是否可见、对应的图例中是否可见等,折线图还有线条是否可见、折点图形是否可见、折点图形是否填充、折点图形的形状、对应的图例中线条是否可见、图形是否可见、整体是否可见等)、以及对指定?item?label?的设置、指定绘制图形的设置。可以说和具体绘制的图形相关的属性都可以通过?Renderer?对象设置。
不同的?Renderer?的实现类实现了不同的显示方式,在含有?Renderer?对象的?JFreeChart?对象中,?R?enderer?对象决定了JFreeChart对象的显示方式。例如:柱状图的Plot对象中默认的Renderer对象是?CategoryItemRenderer?对象,通过设置?Plot?对象的Renderer对象?为?LineAndShapeRenderer?,则柱状图变为线图。使用中一般不需要显式的实例化一个?R?enderer?对象,一般通过?JFreeChart?对象的?Plot?对象调用现有的?R?enderer?对象进行重新设置等操作。
如:setDrawBarOutline(boolean);//可对图形的外轮廓线修改
setSeriesPaint()//可对图形的颜色进行修改(BarChartDemo1)
setShapesVisible(true);?//series?点(即数据点)可见??????????????
setLineVisible(true)?//series?点(即数据点)间有连线可见(LineChartDemo5)
setShapesFilled(true);?//数据点被填充即不是空心点(CrosshairDemo3)
setSeriesLinesVisible(0,?false);?//第一个XYSeries数据点间连线不可见
setSeriesShapesVisible(1,?false);//第二个XYSeries数据点不可见(LineChartDemo6)
setSeriesFillPaint(0,?Color.red);?//数据点填充为红色
setSeriesFillPaint(1,?Color.white);?//数据点填充为白色(TimeSeriesDemo3)
?
?
图形?dataset?plot?renderer
饼图?PieDataset(DefaultPieDataset)?PiePlot?无
柱状图?CatagoryDataset(DefaultCategoryDataset)?CategoryPlot?BarRenderer
折线图?CatagoryDataset(DefaultCategoryDataset)?CategoryPlot?LineAndShapeRenderer
XYDataset(XYSeriesCollection)?XYPlot?XYLineAndShapeRenderer
时间序列图?XYDataset?(TimeSeriesCollection)?XYPlot?XYLineAndShapeRenderer
1.5?轴属性
使用JFreeChart创建的大部分图表都带有两个轴。X轴和Y轴。当然对于一些图表(比如饼图)根本就没有轴。对于使用轴的图表来说,图区使用Axis对象来管理轴。
JFreeChart?提供了两种类型的坐标轴:?CategoryAxis?(等级轴)和?ValueAxis?(值轴),?ValueAxis?又有?3?个子类:?DateAxis?(时间轴)、?NumberAxis?(数字轴)、?PeriodAxis?(时期轴)。这些坐标轴还有更详细的子类,不再一一列举
Axis?对象可进行的操作有:标题的设置(内容、字体、Paint、显示角度等)、坐标线的设置(笔画、Paint、是否可见等)、刻度线的设置(是否可见、笔画、Paint、位于绘图区域的长度、位于绘图区域外的长度等)、刻度标示的设置(笔画、Paint、字体、与轴的距离等)、坐标轴范围设置等。
CategoryAxis?对象还可以进行的操作有:?刻度标示间距?设置(?最小间距、最大间距、指定间距)等。
ValueAxis?对象可进行的操作有:轴端设置(显示的图形形状)、范围设置(是否自动产生范围、自动产生的最小范围、最大范围、指定确定范围、指定范围大小等)、间隔设置(是否自动产生间隔、指定间隔)等。
DateAxis?对象还有对时间刻度显示格式的设置操作。
?
在你修改轴的属性之前,我们需要先获得一个轴的引用。图区类CategoryPlot和XYPlot类有两个方法getDomainAxis()和getRangeAxis()分别是获得X轴Y轴对象。这两个方法返回了一个ValueAxis对象的引用,除了在使用CategoryPlot的情况下,X轴使用的是CategoryAxis。代码如下:
CategoryAxis和ValueAxis类有许多不同的子类。有时我们需要将轴对象引用转化成具体的子类,为了获取更多具体的属性。如,如果我们想获得y轴为一个对象NumberAxis。代码如下:
我们使用方法setLabel()可以改变轴的标签。如果我们不想在图表的轴上有标签,那么我们就设置为null即可。
我们可以使用Axis类定义的方法setLabelFont(),?setLabelPaint(),?和?setLabelAngle()改变标签的字体、颜色和坐标轴标题旋转角度(纵坐标可以旋转)内容。
当图区在左侧或右侧画一个轴(水平轴)时,轴标签会自动旋转90度,以满足小空间的需要。如果我们希望标签也水平,我们需要修改标签的角度:
注意角度的表示使用弧度(PI为180度)。
setVerticalTickLabels(boolean?flag)??数据轴数据标签是否旋转到垂直
void?setInverted(boolean?flag)????数据轴是否反向(默认为false)
隐藏某个轴的刻度标签:
对于CategoryAxis,方法setTickLabelsVisible(false)隐藏种类标签。
隐藏某个轴的刻度符号:
注意category轴没有刻度符号。
默认的,数值和日期会自动选择一个刻度尺寸,以便刻度标签不会重复显示。但我们也可以使用setTickUnit()方法设置我们自己的饿刻度单位。
setLowerBound(double?min)????数据轴上的显示最小值
setUpperBound(double?max)????数据轴上的显示最大值
?
在NumberAxis类中,方法允许我们设置我们自己的刻度单位替代系统自动选择刻度danwi的机制。最普通的应用就是我们有一个仅仅显示整数的数轴。在实例中,我们不想让0.5或者0.25作为刻度单位。在NumberAxis类中有一个静态方法返回一系列的标准整数刻度单位:
如果我们想控制标准的刻度单位时,我们可以自由定制自己的TickUnits集合。
setAutoRange(boolean?auto)????自动设置数据轴数据范围
setAutoRangeMinimumSize(double?size)??自动设置数据轴数据范围时数据范围的最小跨度
setAutoTickUnitSelection(boolean?flag)??数据轴的数据标签是否自动确定(默认为true)
setFixedAutoRange(double?length)???数据轴固定数据范围(设置100的话就是显示MAXVALUE到MAXVALUE-100那段数据范围)
setAutoRangeIncludesZero(boolean?flag)??是否强制在自动选择的数据范围中包含0
setAutoRangeStickyZero(boolean?flag)??是否强制在整个数据轴中包含0,即使0不在数据范围中
类似于上一节内容,DateAxis类也有一个setStandardTickUnits()方法,来设置我们的刻度单位。方法createStandardDateTickUnits()为DateAxis返回了一个缺省的集合。同时我们也可以创建我们自己的标准日期刻度单位。
Add:
setUpperMargin()可设置留白的大小比例,当设置为1时图大小与空白大小相当,数值越小留白越小,数值类型为Double
setMaximumDate(Date?maximumDate)???日期轴上的最大日期
setMinimumDate(Date?minimumDate)??日期轴上的最小日期
对于所有坐标轴Axis对象可设置:
setAxisLinePaint(Paint?paint)???坐标轴线条颜色(3D轴无效)
setAxisLineStroke(Stroke?stroke)???坐标轴线条笔触(3D轴无效)
setAxisLineVisible(boolean?visible)??坐标轴线条是否可见(3D轴无效)
setTickLabelFont(Font?font)???坐标轴标尺值字体
setTickLabelPaint(Paint?paint)???坐标轴标尺值颜色
setTickMarkPaint(Paint?paint)???坐标轴标尺颜色
setTickMarkStroke(Stroke?stroke)???坐标轴标尺笔触
setTickMarksVisible(boolean?flag)???坐标轴标尺是否显示
ValueAxis(Axis)类:
setLowerMargin(double?margin)???数据轴下(左)边距
setUpperMargin(double?margin)???数据轴上(右)边距
setPositiveArrowVisible(boolean?visible)??是否显示正向箭头(3D轴无效)
setNegativeArrowVisible(boolean?visible)??是否显示反向箭头(3D轴无效)
NumberAxis(ValueAxis)类:
setNumberFormatOverride(NumberFormat?formatter)?数据轴数据标签的显示格式
2?图表工具条(Tooltips)
2.1?概述
JFreeChart为图表的每个组件提供了一套产生、收集和显示工具条的机制。图表工具条主要是嵌入到图片中,显示提示信息用。本章主要介绍:
2.2?创建图表工具条
如果我们需要使用图表工具条,我们首先确保所画的图表中已经产生图表工具条。我们可以为我们的图区或图区条目设置图表工具条产生器。在下面的相关章节里面,我们将了解如何为一个图表设置一个图表工具条。
饼图类PiePlot使用PieToolTipGenerator接口产生接口图表工具条。系统通过了该接口的一个标准实现类StandardPieToolTipGenerator。PiePlot设置图表工具条的方法如下:
该方法可以为饼图设置工具条产生器,如果设置null,则表示没有工具条。
种类图表—包括JFreeChart创建最多的直方条形图—基于CategoryPlot类并使用CategoryItemRenderer来画每一个数据条目。Renderer使用接口CategoryToolTipGenerator的指定方法来获得图表工具条。为种类图区条目设置图表工具条产生器,使用类AbstractCategoryItemRenderer的方法:
该方法可以为饼图设置工具条产生器,如果设置null,则表示没有工具条。
Add:
CategoryPlot类中可获得CategoryAxis对象对坐标轴增加tooltipf方法为:
addCategoryLabelToolTip(String?);
XY图表—包括JFreeChart创建的散点图和时序图—基于类XYPlot并使用XYItemRenderer画出每一个数据条目。Renderer使用一个XYToolTipGenerator产生图表工具条。
设置XY图区条目的工具条,使用在AbstractXYItemRenderer定义的方法:
如果设置产生器为null,表示没有图表工具条产生器。
柱状图可通过BarRenderer的setBaseToolTipGenerator((CategoryToolTip
Generator?generator))方法定义和设置tooltips;
例如setBaseToolTipGenerator(new?StandardCategoryToolTipGene
rator());
也可以通过setLegendItemToolTipGenerator()方法添加图例的工具条,并设置
定义方法为:
setLegendItemToolTipGenerator(new?StandardCategorySeriesLabelGenerator(String?format));
?
折线图可通过LineAndShapeRenderer对象的setBaseToolTipGenerator((Category
ToolTipGenerator?generator))方法定义和设置tooltips;
例如lineandshaperenderer.setBaseToolTipGenerator(new?StandardCategoryToolTipGenerator());
2.3?显示图表工具条
使用ChartPanel类创建我们的图表时,图表工具条会自动显示出来。并且你可以为图区(或者图区的renderer)设置一个图表工具条。
我们可是使用类的方法设置显示或隐藏图表工具条。方法如下:
??????
2.4?隐藏图表工具条
最有效的方式就是将图表工具条设置为null。确保没有任何图表工具条信息产生,这样可以节省内存同时提供处理速度(特别是对于大数据源时,非常有好处)。
我们可是使用上节讲的方法使用ChartPanele类设置图表工具条的隐藏。
3?图表条目标签(Item?Label)
3.1?简介
对于大多数的图表类型来说,JFreeChart允许我们在图表的每个条目上、或者内部、或者附近显示条目标签。例如,下图12.1?在每个条形图上显示出了真实的值。
图12.1?显示数组的条形图(参考:)
本章主要讲述:
忠告:我们使用上面的特征时,要谨慎。图表是期望用来分析总结数据的——如果我们觉得在图表上显示真实数据是非常有必要的话,那我们的数据应使用一个表格格式显示更为合适。
在当前版本JFreeChart中,条目标签的使用是有很多局限性的:
相信,在以后的JFreeChart版本中,这些限制问题将被解决。
3.2?显示条目标签
条目标签默认是不显示的,因此我们需要使用renderer进行创建和显示条目标签。这主要有以下两个步骤:
此外,我们可以定制条目标签的位置、字体和颜色。在下面的章节里我们将详细的介绍。
使用renderer分配的一个标签产生器创建条目标签(这与图表工具条的机制是相同的)。
下面代码说了将一个标签产生器指派给CategoryItemRenderer:
同样的,将一个产生器指派给XYItemRenderer,代码如下:
我们可以在标准产生器的构造函数中定制不同的行为。当然了,我们也可以创建我们总计的产生器,详见12.5.2章节。
方法renderer.setBaseItemLabelsVisible(false)是控制着条目标签的显示。对于CategoryItemRenderer:
同样对于:XYItemRenderer
一旦设置,这个标志优先管理我们在所有地方对每一系列做的设置,主要为了应用每一系列的设置。我们可以设置个标志为null(见12.2.4章节)
我们可以控制图表的每一个系列的条目标签是否显示。例如:如下图12.2仅显示第一系列条目标签。
如图12.2显示第一系列条目标签
下面代码可以设置如上效果:
注意:上面代码中对全部的系列设置为null—这一点非常重要,因为全部系列的标志控制每一个系列的标志。
?
3.3?条目标签外观
我们可以通过改变条目的颜色、字体来改变图表条目标签的外观。正如其他renderer属性一样,属性的设置可以是全部的系列,可以是具体某一系列。
在JFreeChart目前的版本中,标签是月年个一个透明的背景画出来的。我们不能设置标签的背景颜色,也不能指定标签的边框。这些在以后的版本中会得到解决。
为了在所有的系列中改变条目标签的字体,我们可以使用下面的代码:
同样,也可以为单个系列设置字体:
注意:renderer.setBaseItemLabelFont(null)方法会出错。开发指南显示的代码有错误。
改变条目标签的颜色,我们可以使用下面的代码:
同样的,可以为单独每一系列设置颜色:
注意:renderer.setBaseItemLabelPaint(null);方法会出错。开发指南显示的代码有错误。
3.4?条目标签位置?(DrawStringDemo.java)
条目标签的位置是通过ItemLabelPosition对象的四个属性来控制的。
我们可以通过接口CategoryItemRenderer的方法来独立定义条目标签的正负点位置:
理解这些属性如何影响独立标签的最终位置的关键是了解JFreeChart里面条目标签的特征。四个特征是:
这些的详细描述在下一章详细介绍。
设置条目标签位置的目的,主要是为了找出标签在图表上贴向数据条目的一个点(x,y)位置。同时在画图表时,该标签也被画在该点处。
?setItemLabelPosition(ItemLabelPosition?position)????数据标签位置
?setPositiveItemLabelPosition(ItemLabelPosition?position)???正数标签位置
?setNegativeItemLabelPosition(ItemLabelPosition?position)???负数标签位置
?setSeriesItemLabelPosition(int?series,ItemLabelPosition?position)??数据标签位置
?setSeriesPositiveItemLabelPosition(int?series,ItemLabelPosition?position)?正数标签位置
?setSeriesNegativeItemLabelPosition(int?series,ItemLabelPosition?position)?负数标签位置
在标签上定义了一个旋转点,用于旋转标签。在DrawStringDemo实例中很好演示了这个特征。通过setRotationAnchor(TextAnchor?textanchor)可设置旋转描点。
?
?旋转角度定义了标签沿旋转点旋转的角度。该角度为弧度。方法为setAngle(double?d)。
?
通过render的setAnchor(TextAnchor?textanchor)可设置描点,setItemLabelAnchorOffset(double?offset)?方法数据标签的与数据点的偏移
3.5?定制条目标签文本
定制条目标签文本,我们需要依赖用JFreeChart里的标签产生器来为条目标签创建文本。如果要想完全控制标签文本的控制,我们就需要编写自己的标签产生器,需要实现接口CategoryItemLabelGenerator。
在本章节里,我们对自定义标签器技术做了简要的讲述,然后用两个实例来说明该技术过程。
开发一个自定义标签产生器,我们需要写一个类,该类必须实现CategoryItemLabelGenerator接口里的方法。
该renderer调用该方法获得一个标签的字符串,并且将该字符串传入到当前条目的CategoryDataset、序列和种类。这就意味着创建这个标签时,我们拥有完全的访问权限。
该方法可以返回任意字符串,因此我们格式化这个字符串。如果我们不想显示标签,可以设置为null。
?
4?多轴和数据源图表(Multi?Axis?and?Dataset)
4.1?简介
J?FreeChart在CategoryPlot和XYPlot类中支持多轴和数据源显示。我们利用这个特征可以在一个图表上显示两个或多个数据源数据,但对于数据包含的数据有巨大差距时留有一定的余地。如图13.1所示。
图13.1?具有多轴的图表
典型的,使用JFreeChart构建图表时,图表有一个单数据源、单renderer、单X/Y轴的图区最为常见。然而,在一个图区上添加多个数据源、多个renderer和多个轴也是可能的。在本章的实例中,展示了如何在一个图区上显示其他额外的数据源、renderer和轴。
4.2?实例
MultipleAxisDemo1.java例子提供了一个很好的实例演示如何在一个图表上创建多轴的应用。本章在每一步的代码中提供了很多建议,详见后面的章节。
创建一个具有多轴、多数据源、多renderer的图表,我们首先要创建一个常规的图表(例如使用ChartFactory类创建)。在本实例中,创建了一个时序图,代码如下:
?
如果在图区上添加额外的轴,我们使用setRangeAxis()方法来添加:
方法setRangeAxis()是用来添加图区的轴,注意轴的索引1已经被使用——我们添加其他轴时,通过增加该索引来添加新轴。方法setRangeAxisLocation()允许我们指定轴出现的位置(使用AxisLocation类)。我们添加的轴可以跟主坐标轴同一边,或者在对立边。例如:如果指定的是AxisLocation.BOTTOM_OR_LEFT,这意味着如果图区的方向是垂直的话,将在右边添加了一个Y轴,如果图区的方向是水平的话,将在底部添加一个Y轴。
在这里,图表上每一添加多余的数据源,因此如果我们显示该图表,我们将看到图上显示多轴,但轴上无数据显示。
在图区上添加一个额外的数据源,使用setDataset()方法:
缺省的,数据源将使用主轴来显示数据。如果使数据源在另外的轴上显示数据,需使用方法mapDatasetToDomainAxis()和mapDatasetToRangeAxis()。这两个方法接受两个参数,第一个参数是数据源的索引,第二个是轴的索引。
当我们添加一个数据源时,通常为该数据源添加一个附加的renderer也是非常有意义的。使用方法setRenderer():
方法的第一个参数为上节中添加的数据源的索引。注意:如果我们不想为数据源指定一个附加的rendere,系统将默认使用主renderer,这样系列的颜色就会在主数据源和附加数据源之间共享。
5?组合图表(Combined?Charts)
5.1?简介
JFreeChart支持几个图区类(可以管理着多个子类)组合而成的图表。图区类可以管理几个子类:
????本章使用几个实例说明了JFreeChart创建组合图表时的便利性。
5.2?组合X种类图区
组合主域种类图区就是在一个图区上显示两个或者多个子图区(CategoryPlot实例),共享一个X轴的图区。每个子图区维护自己的Y轴。实例如图14.1所示。
如图14.1?组合X种类图区(共享X轴)
显示图表可以是水平的,也可以是垂直方向的——实例演示的是垂直的图表。
提供了一个很好的例子,演示如何创建该图表的类型。关键的步骤是创建CombinedDomainCategoryPlot实例,然后添加两个子图区:
注意,我们subplot1添加码值时是2(方法add()的第二个参数),而subplot1添加的是1呢?因为这控制着分配给各个图区的空间大小。
子图区的CategoryPlot实例对象将它们的X轴设置为null。例如在演示的实例中,代码如下:
5.3?组合Y种类图区
一个组合Y种类图区就是一个图区显示两个或两个以上的子图区(CategoryPlot实例),共享Y轴。如果14.2.
图14.2?组合Y种类图区
该图表可以水平显示也可以垂直显示(本例是垂直显示)。
实例演示了如何创建该类型图表。关键的步骤是创建一个实例,然后添加两个子图区:
注意添加的子图区subplot1什么码值是3而子图区subplot2码值是2呢。这是因为该值控制这两个子图区分配的空间大小。
子图区是CategoryPlot实例,将Y轴设置为null。例如,在本实例演示的代码如下:
5.4?组合X-XY图区
组合X-XY图区就是一个图区显示两个或者多个子图区(XYPlot实例),共享一个X轴。每一个子图区维护自己的Y轴。如下图14.3所示.
图14.3?组合X-XY图区(参见:CombinedXYPlotDemo5.java)
????图区可能水平显示也可能垂直显示(本例子中垂直显示)。
???CombinedXYPlotDemo5.java实例演示了如何创建该类型的图表。关键的步骤是创建一个实例CombinedDomainXYPlot,并在该实例上添加两个子图区:
图区的码值1是代表每个图区分配的空间大小因为该数值控制着每个图区分配的空间大小。
子图区是XYPlot实例,将自己的X轴设置为null。例如,下面的代码演示了这个特征:
5.5?组合Y-XY图区
???组合Y-XY图区就是一个图区显示两个或者多个子图区(XYPlot实例),共享一个Y轴。每一个子图区维护自己的X轴。如下图14.4所示.
图14.4?组合Y-XY图区(参见:CombinedXYPlotDemo5.java)
????图区可能水平显示也可能垂直显示(本例子中垂直显示)。
???CombinedXYPlotDemo2java实例演示了如何创建该类型的图表。关键的步骤是创建一个实例CombinedRangeXYPlot,并在该实例上添加两个子图区:
图区的码值1是代表每个图区分配的空间大小因为该数值控制着每个图区分配的空间大小。
子图区是XYPlot实例,将自己的X轴设置为null。例如,下面的代码演示了这个特征:
?
?