当前JFreechart版本1.5.0
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.0</version>
</dependency>
A股交易时间为9:30-11:30,13:00-15:00,11:31-12:59分之间是没有数据的,X轴时间刻度也只显示9:30、10:30、11:30、14:00、15:00这5个刻度值。
要实现这个时间显示效果有两种方式:
1、直接使用ChartFactory.createTimeSeriesChart()实现,由于默认下显示的时间是连续的,11:31-12:59没有数值,会显示成一条直线,为了实现数据的连续,需要把13:00-15:00换算成11:31-13:30的数值,实现代码:
package test.jfreechar;
import com.penngo.utils.DateUtil;
import com.penngo.utils.ToolUtil;
import org.apache.commons.io.FileUtils;
import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.ui.*;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.*;
public class Time1Data extends ApplicationFrame {
public Time1Data(String title) {
super(title);
XYDataset xydataset = createDataSet();
JFreeChart jfreechart = createChart(xydataset);
ChartPanel chartpanel = new ChartPanel(jfreechart);
chartpanel.setPreferredSize(new Dimension(865, 250));
setContentPane(chartpanel);
}
public List<List<String>> getJsonData(){
List<List<String>> list = new ArrayList<>();
try{
String content = FileUtils.readFileToString(new File("template/eastmoney/eastmoney.json"), "UTF-8");
Map<String, Object> resultMap = ToolUtil.strToMap(content);
Map<String, Object> data = (Map<String, Object>)resultMap.get("data");
List<String> s2nList = (List<String>)data.get("s2n");
for(String s2n:s2nList) {
String[] strs = s2n.split(",");
String timeStr = strs[0];
String shIn = strs[1];
double shInFloat = shIn.equals("-") ? -10000 : Double.valueOf(shIn) / 10000;
shInFloat = new BigDecimal(shInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
String szIn = strs[3];
double szInFloat = szIn.equals("-") ? -10000 : Double.valueOf(szIn) / 10000;
szInFloat = new BigDecimal(szInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
String totalIn = strs[5];
double totalInFloat = totalIn.equals("-") ? -10000 : Double.valueOf(totalIn) / 10000;
totalInFloat = new BigDecimal(totalInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
list.add(Arrays.asList(timeStr, String.valueOf(totalInFloat), String.valueOf(shInFloat), String.valueOf(szInFloat)));
}
}
catch(Exception e){
e.printStackTrace();
}
return list;
}
private String saveImage(JFreeChart jfreechart){
String imgBase64 = null;
FileOutputStream fos_jpg=null;
try {
File img = new File("template/eastmoney/char_time1.png");
fos_jpg = new FileOutputStream(img,false);
// 将报表保存为png文件
ChartUtils.writeChartAsPNG(fos_jpg, jfreechart, 865, 250);
fos_jpg.close();
imgBase64 = ToolUtil.img2base64(img);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos_jpg.close();
} catch (Exception e) {
// TODO: handle exception
}
}
return imgBase64;
}
private XYDataset createDataSet(){
TimeSeries timeseries1 = new TimeSeries("指数1");
TimeSeries timeseries2 = new TimeSeries("指数2");
TimeSeries timeseries3 = new TimeSeries("指数3");
List<List<String>> list = getJsonData();
for(List<String> strs:list){
String timeStr = strs.get(0);
String dateStr = DateUtil.dateToStr(new Date(), "yyyy-MM-dd "+timeStr+":ss");
LocalDateTime localDateTime = DateUtil.strToLocalDateTime(dateStr, "yyyy-MM-dd H:mm:ss");
Number totalInFloat = strs.get(1).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(1));
Number hk2shFloat = strs.get(2).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(2));
Number hk2sFloat = strs.get(3).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(3));
Day day = new Day();
int hour = localDateTime.getHour();
int minute = localDateTime.getMinute();
if(hour > 12){
localDateTime = localDateTime.plusMinutes(-90);
hour = localDateTime.getHour();
minute = localDateTime.getMinute();
}
timeseries1.add(new Minute(minute, new Hour(hour, day)), totalInFloat);
timeseries2.add(new Minute(minute, new Hour(hour, day)), hk2shFloat);
timeseries3.add(new Minute(minute, new Hour(hour, day)), hk2sFloat);
}
TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
timeseriescollection.addSeries(timeseries1);
timeseriescollection.addSeries(timeseries2);
timeseriescollection.addSeries(timeseries3);
return timeseriescollection;
}
private static JFreeChart createChart(XYDataset xydataset)
{
StandardChartTheme standardChartTheme = new StandardChartTheme("JFree"); //或者为Legacy
standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setSmallFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setLargeFont(new Font("宋体", Font.BOLD, 12));
ChartFactory.setChartTheme(standardChartTheme);
JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("股市指数测试", "", "", xydataset, false, true, false);
TextTitle subtitle1 = new TextTitle("日期:" + DateUtil.getNowStr("yyyy年MM月dd日 "));
subtitle1.setPaint(new Color(144,144,144));
subtitle1.setPosition(RectangleEdge.TOP);
subtitle1.setHorizontalAlignment(HorizontalAlignment.RIGHT);
jfreechart.addSubtitle(subtitle1);
TextTitle subtitle2 = new TextTitle("注:资金数据仅供参考\n来自:https://my.oschina.net/penngo制图");
subtitle2.setPaint(new Color(144,144,144));
subtitle2.setPosition(RectangleEdge.BOTTOM);
subtitle2.setHorizontalAlignment(HorizontalAlignment.CENTER);
subtitle2.setMargin(4.0D, 0.0D, 2.0D, 4.0D);
jfreechart.addSubtitle(subtitle2);
jfreechart.setBorderVisible(false);
XYPlot plot = (XYPlot) jfreechart.getPlot();
plot.setBackgroundPaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.lightGray);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 20.0));
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
LegendItemCollection var5 = new LegendItemCollection();
var5.add(new LegendItem("指数1", (String)null, (String)null, (String)null, new Rectangle2D.Double(-6.0D, -3.0D, 12.0D, 12.0D), new Color(107, 57,6)));
var5.add(new LegendItem("指数2", (String)null, (String)null, (String)null, new Rectangle2D.Double(-6.0D, -3.0D, 12.0D, 12.0D), new Color(35, 131,252)));
var5.add(new LegendItem("指数3", (String)null, (String)null, (String)null, new Rectangle2D.Double(-6.0D, -3.0D, 12.0D, 12.0D), new Color(255, 91,255)));
plot.setFixedLegendItems(var5);
plot.setInsets(new RectangleInsets(5.0D, 5.0D, 5.0D, 20.0D));
LegendTitle var6 = new LegendTitle(plot);
var6.setPosition(RectangleEdge.BOTTOM);
jfreechart.addSubtitle(var6);
XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setSeriesPaint(0, new Color(107, 57,6));
renderer.setSeriesPaint(1, new Color(35, 131,252));
renderer.setSeriesPaint(2, new Color(255, 91,255));
}
plot.setDomainAxis(new CustomDateAxis());
DateAxis dateAxis = (DateAxis) plot.getDomainAxis();
Date minDate = dateAxis.getMinimumDate();
minDate.setHours(9);
minDate.setMinutes(30);
Date maxDate = dateAxis.getMaximumDate();
maxDate.setHours(13);
maxDate.setMinutes(30);
System.out.println("====minDate:" + DateUtil.dateToStr(minDate, "yyyy-MM-dd HH:mm:ss") + ", maxDate:" + DateUtil.dateToStr(maxDate, "yyyy-MM-dd HH:mm:ss"));
dateAxis.setRange(minDate, maxDate);;
//plot.setRangeAxis(new CustomNumberAxis());
NumberAxis valueAxis = (NumberAxis)plot.getRangeAxis();
return jfreechart;
}
private static class CustomNumberAxis extends NumberAxis{
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
if (RectangleEdge.isTopOrBottom(edge)) {
result = this.refreshTicksHorizontal(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
result = this.refreshTicksVertical(g2, dataArea, edge);
}
return (List)result;
}
}
private static class CustomDateAxis extends DateAxis{
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List result = null;//new ArrayList();
if (RectangleEdge.isTopOrBottom(edge)) {
Font tickLabelFont = this.getTickLabelFont();
g2.setFont(tickLabelFont);
if (this.isAutoTickUnitSelection()) {
this.selectAutoTickUnit(g2, dataArea, edge);
}
DateTickUnit unit = this.getTickUnit();
Date tickDate = this.calculateLowestVisibleTickValue(unit);
result = new ArrayList();
Map<String, String> dateMap = new LinkedHashMap<String, String>(){{
put("09:30","09:30");
put("10:30","10:30");
put("11:30","11:30");
put("12:30","14:00");
put("13:30","15:00");
}};
for(String timeStr:dateMap.keySet()){
String timeValue = dateMap.get(timeStr);
String time = DateUtil.dateToStr(tickDate, "yyyy-MM-dd " +timeStr+ ":ss");
Date date = DateUtil.strToDate(time, "yyyy-MM-dd HH:mm:ss");
Tick tick = new DateTick(date, timeValue, TextAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, 0.0);
result.add(tick);
}
} else if (RectangleEdge.isLeftOrRight(edge)) {
result = this.refreshTicksVertical(g2, dataArea, edge);
}
return result;
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
Font tickLabelFont = this.getTickLabelFont();
g2.setFont(tickLabelFont);
if (this.isAutoTickUnitSelection()) {
this.selectAutoTickUnit(g2, dataArea, edge);
}
DateTickUnit unit = this.getTickUnit();
Date tickDate = this.calculateLowestVisibleTickValue(unit);
Date upperDate = this.getMaximumDate();
boolean hasRolled = false;
while(true) {
while(tickDate.before(upperDate)) {
if (!hasRolled) {
//tickDate = this.correctTickDateForPosition(tickDate, unit, this.getTickMarkPosition());
}
long lowestTickTime = tickDate.getTime();
long distance = unit.addToDate(tickDate, this.getTimeZone()).getTime() - lowestTickTime;
int minorTickSpaces = this.getMinorTickCount();
if (minorTickSpaces <= 0) {
minorTickSpaces = unit.getMinorTickCount();
}
for(int minorTick = 1; minorTick < minorTickSpaces; ++minorTick) {
long minorTickTime = lowestTickTime - distance * (long)minorTick / (long)minorTickSpaces;
if (minorTickTime > 0L && this.getRange().contains((double)minorTickTime) && !this.isHiddenValue(minorTickTime)) {
result.add(new DateTick(TickType.MINOR, new Date(minorTickTime), "", TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0D));
}
}
if (!this.isHiddenValue(tickDate.getTime())) {
DateFormat formatter = this.getDateFormatOverride();
String tickLabel;
if (formatter != null) {
tickLabel = formatter.format(tickDate);
} else {
tickLabel = this.getTickUnit().dateToString(tickDate);
}
double angle = 0.0D;
TextAnchor anchor;
TextAnchor rotationAnchor;
if (this.isVerticalTickLabels()) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
} else {
anchor = TextAnchor.TOP_CENTER;
rotationAnchor = TextAnchor.TOP_CENTER;
}
Tick tick = new DateTick(tickDate, tickLabel, anchor, rotationAnchor, angle);
result.add(tick);
hasRolled = false;
long currentTickTime = tickDate.getTime();
tickDate = unit.addToDate(tickDate, this.getTimeZone());
long nextTickTime = tickDate.getTime();
for(int minorTick = 1; minorTick < minorTickSpaces; ++minorTick) {
long minorTickTime = currentTickTime + (nextTickTime - currentTickTime) * (long)minorTick / (long)minorTickSpaces;
if (this.getRange().contains((double)minorTickTime) && !this.isHiddenValue(minorTickTime)) {
result.add(new DateTick(TickType.MINOR, new Date(minorTickTime), "", TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0D));
}
}
} else {
tickDate = unit.rollDate(tickDate, this.getTimeZone());
hasRolled = true;
}
}
return result;
}
}
}
public static void main(String args[])
{
Time1Data timeseriesdemo10 = new Time1Data("股市9:30-15:00指数时序图");
timeseriesdemo10.pack();
timeseriesdemo10.setVisible(true);
}
}
生成图片效果:
2、直接使用自带的折线图,但是默认的X轴坐标值不能只显示9:30、10:30、11:30、14:00、15:00这5个刻度值,需要重写CategoryPlot.drawDomainGridlines、CategoryAxis.refreshTicks、CategoryAxis.drawCategoryLabels三个方法,实现代码如下:
package test.jfreechar;
import com.penngo.utils.DateUtil;
import com.penngo.utils.ToolUtil;
import org.apache.commons.io.FileUtils;
import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.entity.CategoryLabelEntity;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.text.TextBlock;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.chart.ui.HorizontalAlignment;
import org.jfree.chart.ui.RectangleEdge;
import org.jfree.chart.ui.RectangleInsets;
import org.jfree.chart.util.Args;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.math.BigDecimal;
import java.util.List;
import java.util.*;
public class Time2Data extends ApplicationFrame {
public Time2Data(String title) {
super(title);
DefaultCategoryDataset xydataset = createDataSet();
JFreeChart jfreechart = createChart(xydataset);
ChartPanel chartpanel = new ChartPanel(jfreechart);
chartpanel.setPreferredSize(new Dimension(862, 250));
setContentPane(chartpanel);
}
public List<List<String>> getJsonData(){
List<List<String>> list = new ArrayList<>();
try{
String content = FileUtils.readFileToString(new File("template/eastmoney/penngo_data.json"), "UTF-8");
Map<String, Object> resultMap = ToolUtil.strToMap(content);
Map<String, Object> data = (Map<String, Object>)resultMap.get("data");
List<String> s2nList = (List<String>)data.get("s2n");
for(String s2n:s2nList) {
String[] strs = s2n.split(",");
String timeStr = strs[0];
String shIn = strs[1];
double shInFloat = shIn.equals("-") ? -10000 : Double.valueOf(shIn) / 10000;
shInFloat = new BigDecimal(shInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
String szIn = strs[3];
double szInFloat = szIn.equals("-") ? -10000 : Double.valueOf(szIn) / 10000;
szInFloat = new BigDecimal(szInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
String totalIn = strs[5];
double totalInFloat = totalIn.equals("-") ? -10000 : Double.valueOf(totalIn) / 10000;
totalInFloat = new BigDecimal(totalInFloat).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
list.add(Arrays.asList(timeStr, String.valueOf(totalInFloat), String.valueOf(shInFloat), String.valueOf(szInFloat)));
}
}
catch(Exception e){
e.printStackTrace();
}
return list;
}
private DefaultCategoryDataset createDataSet(){
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
List<List<String>> list = getJsonData();
int count = 0;
for(List<String> strs:list){
String timeStr = strs.get(0);
Number totalInFloat = strs.get(1).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(1));
Number hk2shFloat = strs.get(2).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(2));
Number hk2szloat = strs.get(3).equals("-10000.0") ? (Number)null : Double.valueOf(strs.get(3));
dataset.addValue(totalInFloat, "指数1", timeStr);
dataset.addValue(hk2shFloat, "指数2", timeStr);
dataset.addValue(hk2szloat, "指数3", timeStr);
}
return dataset;
}
private static JFreeChart createChart(DefaultCategoryDataset xydataset)
{
StandardChartTheme standardChartTheme = new StandardChartTheme("JFree"); //或者为Legacy
standardChartTheme.setRegularFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setSmallFont(new Font("宋体", Font.BOLD, 12));
standardChartTheme.setLargeFont(new Font("宋体", Font.BOLD, 12));
ChartFactory.setChartTheme(standardChartTheme);
JFreeChart jfreechart = createLineChart(
"股市指数测试", // chart title
"时间", // domain axis label
"资金", // range axis label
xydataset, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips
false // urls
);
TextTitle subtitle1 = new TextTitle("日期:" + DateUtil.getNowStr("yyyy年MM月dd日"));
subtitle1.setPosition(RectangleEdge.TOP);
subtitle1.setHorizontalAlignment(HorizontalAlignment.RIGHT);
jfreechart.addSubtitle(subtitle1);
CategoryPlot plot = (CategoryPlot)jfreechart.getPlot();
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 20.0));
plot.setDrawSharedDomainAxis(true);
plot.setRangePannable(true);
plot.setRangeGridlinesVisible(true);
plot.setDomainGridlinesVisible(true);
plot.setRangeZeroBaselineVisible(true);
plot.setDomainAxis(new CustomCategoryAxis());
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setTickMarksVisible(false);
domainAxis.setLowerMargin(0);
domainAxis.setUpperMargin(0);
return jfreechart;
}
public static JFreeChart createLineChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
Args.nullNotPermitted(orientation, "orientation");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false);
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer){
protected void drawDomainGridlines(Graphics2D g2, Rectangle2D dataArea) {
if (this.isDomainGridlinesVisible()) {
CategoryAnchor anchor = this.getDomainGridlinePosition();
RectangleEdge domainAxisEdge = this.getDomainAxisEdge();
CategoryDataset dataset = this.getDataset();
if (dataset != null) {
CategoryAxis axis = this.getDomainAxis();
if (axis != null) {
int columnCount = dataset.getColumnCount();
for(int c = 0; c < columnCount; ++c) {
double xx = axis.getCategoryJava2DCoordinate(anchor, c, columnCount, dataArea, domainAxisEdge);
CategoryItemRenderer renderer1 = this.getRenderer();
if (renderer1 != null) {
String timeStr = dataset.getColumnKey(c).toString();
if(timeStr.equals("9:30") || timeStr.equals("10:30") || timeStr.equals("11:30")
|| timeStr.equals("14:00") || timeStr.equals("15:00")){
renderer1.drawDomainGridline(g2, this, dataArea, xx);
}
}
}
}
}
}
}
};
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
static class CustomCategoryAxis extends CategoryAxis{
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
if (dataArea.getHeight() > 0.0D && dataArea.getWidth() >= 0.0D) {
CategoryPlot plot = (CategoryPlot)this.getPlot();
List categories = plot.getCategoriesForAxis(this);
double max = 0.0D;
if (categories != null) {
CategoryLabelPosition position = this.getCategoryLabelPositions().getLabelPosition(edge);
float r = this.getMaximumCategoryLabelWidthRatio();
if ((double)r <= 0.0D) {
r = position.getWidthRatio();
}
float l;
if (position.getWidthType() == CategoryLabelWidthType.CATEGORY) {
l = (float)this.calculateCategorySize(categories.size(), dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
l = (float)dataArea.getWidth();
} else {
l = (float)dataArea.getHeight();
}
l = 30;
int categoryIndex = 0;
for(Iterator iterator = categories.iterator(); iterator.hasNext(); ++categoryIndex) {
Comparable category = (Comparable)iterator.next();
g2.setFont(this.getTickLabelFont(category));
TextBlock label = this.createLabel(category, l * r, edge, g2);
if (edge != RectangleEdge.TOP && edge != RectangleEdge.BOTTOM) {
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
max = Math.max(max, this.calculateTextBlockWidth(label, position, g2));
}
} else {
max = Math.max(max, this.calculateTextBlockHeight(label, position, g2));
}
Tick tick = new CategoryTick(category, label, position.getLabelAnchor(), position.getRotationAnchor(), position.getAngle());
ticks.add(tick);
}
}
state.setMax(max);
return ticks;
} else {
return ticks;
}
}
protected AxisState drawCategoryLabels(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
Args.nullNotPermitted(state, "state");
if (!this.isTickLabelsVisible()) {
return state;
} else {
List ticks = this.refreshTicks(g2, state, plotArea, edge);
state.setTicks(ticks);
int categoryIndex = 0;
for(Iterator iterator = ticks.iterator(); iterator.hasNext(); ++categoryIndex) {
CategoryTick tick = (CategoryTick)iterator.next();
String timeStr = tick.getCategory().toString();
g2.setFont(this.getTickLabelFont(tick.getCategory()));
g2.setPaint(this.getTickLabelPaint(tick.getCategory()));
CategoryLabelPosition position = this.getCategoryLabelPositions().getLabelPosition(edge);
double x0 = 0.0D;
double x1 = 0.0D;
double y0 = 0.0D;
double y1 = 0.0D;
if (edge == RectangleEdge.TOP) {
x0 = this.getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
x1 = this.getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
y1 = state.getCursor() - (double)this.getCategoryLabelPositionOffset();
y0 = y1 - state.getMax();
} else if (edge == RectangleEdge.BOTTOM) {
x0 = this.getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
x1 = this.getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
y0 = state.getCursor() + (double)this.getCategoryLabelPositionOffset();
y1 = y0 + state.getMax();
} else if (edge == RectangleEdge.LEFT) {
y0 = this.getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
y1 = this.getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
x1 = state.getCursor() - (double)this.getCategoryLabelPositionOffset();
x0 = x1 - state.getMax();
} else if (edge == RectangleEdge.RIGHT) {
y0 = this.getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
y1 = this.getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
x0 = state.getCursor() + (double)this.getCategoryLabelPositionOffset();
x1 = x0 - state.getMax();
}
Rectangle2D area = new Rectangle2D.Double(x0, y0, x1 - x0, y1 - y0);
Point2D anchorPoint = position.getCategoryAnchor().getAnchorPoint(area);
TextBlock block = tick.getLabel();
if(timeStr.equals("9:30") || timeStr.equals("10:30") || timeStr.equals("11:30")
|| timeStr.equals("14:00") || timeStr.equals("15:00")){
block.draw(g2, (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getLabelAnchor(), (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getAngle());
}
Shape bounds = block.calculateBounds(g2, (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getLabelAnchor(), (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getAngle());
if (plotState != null && plotState.getOwner() != null) {
EntityCollection entities = plotState.getOwner().getEntityCollection();
if (entities != null) {
String tooltip = this.getCategoryLabelToolTip(tick.getCategory());
String url = this.getCategoryLabelURL(tick.getCategory());
entities.add(new CategoryLabelEntity(tick.getCategory(), bounds, tooltip, url));
}
}
}
double w;
if (edge.equals(RectangleEdge.TOP)) {
w = state.getMax() + (double)this.getCategoryLabelPositionOffset();//.categoryLabelPositionOffset;
state.cursorUp(w);
} else if (edge.equals(RectangleEdge.BOTTOM)) {
w = state.getMax() + (double)this.getCategoryLabelPositionOffset();
state.cursorDown(w);
} else if (edge == RectangleEdge.LEFT) {
w = state.getMax() + (double)this.getCategoryLabelPositionOffset();
state.cursorLeft(w);
} else if (edge == RectangleEdge.RIGHT) {
w = state.getMax() + (double)this.getCategoryLabelPositionOffset();
state.cursorRight(w);
}
return state;
}
}
}
public static void main(String args[])
{
Time2Data timeseriesdemo10 = new Time2Data("股市9:30-15:00指数时序图");
timeseriesdemo10.pack();
timeseriesdemo10.setVisible(true);
}
}
生成图片效果: