1,选择框架
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.2</version>
</dependency>
2,问题
-
我们时间绘制走势图的时候,框架会自动计算间隔,并在横坐标显示出计算之后的日期
-
但是往往自动计算出来展示在 X 周的坐标并不是你想要的,他可能是你根本没有注入数据的一个日期
-
笔者就遇到了客户要求把走势图的开始日期和结束日期展示出来,这些都是自动计算做不到的
3,解决办法
这时我们一般会选择设置步数,我们在代码里控制显示的时间间隔,代码片段如下:
// 设置间隔时间
((DateAxis) domainAxis).setTickUnit(new DateTickUnitGai(DateTickUnitType.DAY, interval));
-
这样设置之后,刻度之间的间隔就是我们设置的 interval 这个值了,以上的代码 代表天数
-
但是这样设置之后出现了一个很坑的问题,初始值不见了,对第一个值 不显示了,整个 X 轴第一个值没了!!!各种百度,查阅文档,没有找到解决办法,
-
笔者只好阅读源码:发现 DateAxis 类型的横坐标显示哪些值是有以下这个方法的返回值决定的:
-
既然找到了这个方法,那就好办了,我们只需要继承这个类,重写该方法返回我们想要的就好了
package com.xctech.xhe.provider.aspose;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTick;
import org.jfree.chart.axis.TickType;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.chart.ui.TextAnchor;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DateAxisGai extends DateAxis {
private final Date min;
private final Date max;
public DateAxisGai(Date min, Date max) {
this.min = min;
this.max = max;
}
/**
* 该方法返回需要在 横坐标 显示的刻度
*/
@Override
protected List<DateTick> refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List<DateTick> dates = new ArrayList<>();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
if (min != null) {
dates.add(new DateTick(TickType.MAJOR, min, dateFormat.format(min), TextAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, 0.0));
}
if (max != null && !max.equals(min)) {
dates.add(new DateTick(TickType.MAJOR, max, dateFormat.format(max), TextAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, 0.0));
}
return dates;
}
}
- 生成横坐标的时候调用上面的类,代码片段如下:其中 maximumDate,minimumDate 为数据中计算而来的最大日期和最小日期
DateAxis domainAxis = new DateAxisGai(minimumDate, maximumDate);
domainAxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd")); // X 轴的格式
domainAxis.setTickLabelFont(new Font("黑体", Font.PLAIN, 12)); // X 轴的字体
plot.setDomainAxis(domainAxis);
4,结果和扩展思路:
1,通过上面的修改,终于顺利的展示出来了开始日期和结束日期
2,扩展,
笔者这里由于只是要求展示展示出来开始和结束,如果有更多的需求,我们都可以在 refreshTicksHorizontal 方法里修改得到,至于问:
new DateTick(TickType.MAJOR, min, dateFormat.format(min), TextAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, 0.0)
这句代码各个参数是怎么来的:
当然是在原来的类方法上打断点,查看运行结果搬过来的喽: