JFreeCharts画分时图

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tufeng1992/article/details/50953380
        记录下画分时图的过程。
    

        分时图绘画过程也就是折线图和柱状图的结合,这里还是用CombinedDomainXYPlot这个类来结合画图。

        首先画折线。这里折线分为两条,一条是今日走势,一条是昨日收盘价。先说数据定义,这里因为时间范围是今天,而每一个点的数据精度到每分钟,所以在使用TimeSeries时使用Millisecond时间精准到每分钟。而昨日收盘价是一个不会变的数据,这里可以用Day,直接定义为全天范围就行了。数据定义好后,设置画图器XYLineAndShapeRenderer,先设置今日走势的折线颜色为White,然后设置昨收颜色为Red(跟国内大盘样式保持一致),然后设置setSeriesShapeVisible(false),也就是折线上面的点(小方块)不显示。
        
        画图器设置完,设置x轴,这里需要注意的是,国内大盘开盘时间为9:30-11:30(上午)13:00-15:00(下午),所以这里时间轴(x轴)自定义时间范围为9:30-15:00,11:30-13:00中间间隔时间用SegmentedTimeLine来排除addException(start,end),然后设置时间刻度间隔为30分钟。

        y轴这里需要设置两条,这里我只说一条。跟x轴一样,先关闭自动设置,然后设置好数据范围。一般情况下这样就结束了。但是,如上图所示,画股票分时图的时候就会有需要设置y轴多种颜色的情况,然而类提供的setPaint只能统一改变颜色,所以建议写一个类,去继承NumberAxis,重写里面的drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge)。这个类里在使用迭代器循环的时候TextUtilities.drawRotatedString这个函数就是写y轴的颜色。可以在这之前改变G笔的颜色setPaint就行了。至于数据,存放在ValueTick里。顺便提一下,如果要改变y轴数据坐标也是在这个函数里修改就行了。

        然后柱状图这里没什么难点,设置数据,设置画图器改颜色,设置下刻度颜色,最后用CombinedDomainXYPlot结合在一起画出来就行了。

贴下数据模型代码:
public String timeSharingChart(Map<String, String> params){
String path = null;
String data = dataService.getAStockMinData(params);//获取A股分时数据
params.put("data", data);
logger.info("timeSharingChart : params : " + params);
logger.info("timeSharingChart : data : " + data);
path = timeSharingChartPlant(params);//分时图制作工厂
return path;
}

/**
* 获取A股分时数据
*/
public String getAStockMinData(Map<String,String> params){
String secucode = (String)params.get("secucode");
// String market = (String)params.get("market");
// List<Map> dataList = jydbDataServiceImpl.getAIndexOrStockKData(secucode,true, startDate, endDate);
List dataList = getMinQuoteData(secucode);//根据证券代码、市场获取当日分时数据
// System.out.println(dataList);
logger.info("getAStockMinData : " + dataList);
Map<String,Object> newDataMap = getNewQuoteData(secucode);//根据证券代码、市场获取最新行情数据


Map map = new HashMap();
List quoteMinList = new ArrayList();//封装日行情数据
List tradVol = new ArrayList();//封装日交易量数据
String secuabbr = (String)newDataMap.get("secName");
Double openPrice = (Double)newDataMap.get("open");
Double highPrice = (Double)newDataMap.get("high");
Double lowPrice = (Double)newDataMap.get("low");
Double yClose = (Double)newDataMap.get("yClose");
// System.out.println("dataList is :"+dataList);
for(Object data : dataList){
List minData = (List)data;
Object time = minData.get(0);
    Object price = minData.get(1);
    Object tradVolData = minData.get(4);

List minQuote = new ArrayList();//分钟线数据
List minTradVol = new ArrayList();//分钟成交量数据
minQuote.add(time);
minQuote.add(price);
quoteMinList.add(minQuote);

minTradVol.add(time);
minTradVol.add(tradVolData);
tradVol.add(minTradVol);
}
map.put("title", secuabbr+"("+secucode+")");
map.put("openPrice", openPrice);
map.put("highPrice", highPrice);
map.put("lowPrice", lowPrice);
map.put("newPrice", quoteMinList);
map.put("yClose", yClose);
map.put("tradVol", tradVol);
return JsonUtil.toJson(map);
}

贴下分时图代码:
/**
* 分时图制作工厂
* @param params
* @return
*/
private String timeSharingChartPlant(Map<String, String> params) {
String path = null;
try{
//获取绘图数据
String dJson = params.get("data");
Map<String, Object> datas = (Map<String, Object>)JsonUtil.parse(dJson);
//获取标题
String title = (String) datas.get("title");


double mLow = Double.valueOf(datas.get("lowPrice").toString());//最低价
double mHigh = Double.valueOf(datas.get("highPrice").toString());//最高价
double yClose = Double.valueOf(datas.get("yClose").toString());//昨日收盘价


TimeSeriesCollection lineSeriesConllection = new TimeSeriesCollection();
TimeSeries serise1 = new TimeSeries("分时数据");
TimeSeries serise2 = new TimeSeries("昨日收盘价");


TimeSeriesCollection barSeriesCollection = new TimeSeriesCollection();//保留成交量数据的集合
TimeSeries serise3 = new TimeSeries("成交量");


//成交量数据
List<List<Object>> tradVol = (List<List<Object>>) datas.get("tradVol");


//分时数据
List<List<Object>> newPrices = (List<List<Object>>) datas.get("newPrice");
Date today = null;//今天


//循环写入数据
for(int i = 0; i < newPrices.size(); i++){
if(today == null){//记录今天时间
today = DateFormatUtils.getDate13(newPrices.get(i).get(0).toString());
}
serise1.add(new Millisecond(DateFormatUtils.getDate13(newPrices.get(i).get(0).toString())), Double.valueOf(newPrices.get(i).get(1).toString()));
serise3.add(new Millisecond(DateFormatUtils.getDate13(tradVol.get(i).get(0).toString())),  Double.valueOf(tradVol.get(i).get(1).toString()));
}


serise2.add(new Day(today), yClose);
Date tomorrow = new Date(today.getTime() + 86400000);//明天
serise2.add(new Day(tomorrow), yClose);
//分时图数据
lineSeriesConllection.addSeries(serise1);
lineSeriesConllection.addSeries(serise2);
//成交量数据
barSeriesCollection.addSeries(serise3);


//设置均线图画图器
XYLineAndShapeRenderer lineAndShapeRenderer = new XYLineAndShapeRenderer();
lineAndShapeRenderer.setBaseItemLabelsVisible(true);
lineAndShapeRenderer.setSeriesShapesVisible(0, false);//设置不显示数据点模型
lineAndShapeRenderer.setSeriesShapesVisible(1, false);
lineAndShapeRenderer.setSeriesPaint(0, Color.WHITE);//设置均线颜色
lineAndShapeRenderer.setSeriesPaint(1, Color.RED);


//设置k线图x轴,也就是时间轴
DateAxis domainAxis = new DateAxis();
domainAxis.setAutoRange(false);//设置不采用自动设置时间范围
//设置时间范围,注意,最大和最小时间设置时需要+ - 。否则时间刻度无法显示
Calendar calendar = Calendar.getInstance();
Date da = today;
calendar.setTime(da);
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 29);
calendar.set(Calendar.SECOND, 0);
Date sda = calendar.getTime();
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 01);
da = calendar.getTime();
domainAxis.setRange(sda, da);//设置时间范围


DateFormat df = new SimpleDateFormat("HH:mm");
domainAxis.setAutoTickUnitSelection(false);//设置不采用自动选择刻度值
domainAxis.setTickMarkPosition(DateTickMarkPosition.START);//设置标记的位置
domainAxis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());// 设置标准的时间刻度单位


domainAxis.setTickUnit(new DateTickUnit(DateTickUnit.MINUTE, 30));// 设置时间刻度的间隔
domainAxis.setDateFormatOverride(df);//设置时间格式


SegmentedTimeline timeline = SegmentedTimeline.newFifteenMinuteTimeline();//设置时间线显示的规则,用这个方法摒除掉周六和周日这些没有交易的日期


calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 31);
calendar.set(Calendar.SECOND, 0);
sda = calendar.getTime();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 59);
da = calendar.getTime();


timeline.addException(sda.getTime(), da.getTime());//排除非交易时间段
domainAxis.setTimeline(timeline);


//设置k线图y轴参数
NumberAxisY1 y1Axis = new NumberAxisY1();//设置Y轴,为数值,后面的设置,参考上面的y轴设置
y1Axis.setAutoRange(false);//设置不采用自动设置数据范围
y1Axis.setLabel(String.valueOf(yClose));
y1Axis.setLabelFont(new Font("微软雅黑", Font.BOLD, 12));
double t = yClose - mLow;
double t1 = mHigh - yClose;
t = Math.abs(t);
t1 = Math.abs(t1);
double range = t1 > t  ? t1 : t;//计算涨跌最大幅度
DecimalFormat df1 = new DecimalFormat("#0.00");
df1.setRoundingMode(RoundingMode.FLOOR);


y1Axis.setRange(Double.valueOf(df1.format(yClose - range)), Double.valueOf(df1.format(yClose + range)));//设置y轴数据范围
y1Axis.setNumberFormatOverride(df1);
y1Axis.centerRange(yClose);
NumberTickUnit numberTickUnit = new NumberTickUnit(Math.abs(range / 7));
y1Axis.setTickUnit(numberTickUnit);




NumberAxisY2 y2Axis = new NumberAxisY2();//设置Y轴,为数值,后面的设置,参考上面的y轴设置
y2Axis.setAutoRange(false);//设置不采用自动设置数据范围
y2Axis.setLabelFont(new Font("微软雅黑", Font.BOLD, 12));


t = (mLow - yClose) / yClose;
t1 = (mHigh - yClose) / yClose;
t = Math.abs(t);
t1 = Math.abs(t1);
range = t1 > t  ? t1 : t;
y2Axis.setRange(-range, range);//设置y轴数据范围
y2Axis.setTickLabelPaint(Color.RED);
DecimalFormat df2 = new DecimalFormat("#0.00%");
df2.setRoundingMode(RoundingMode.FLOOR);
y2Axis.setNumberFormatOverride(df2);
NumberTickUnit numberTickUnit2 = new NumberTickUnit(Math.abs(range / 7));
y2Axis.setTickUnit(numberTickUnit2);


//生成画图细节 第一个和最后一个参数这里需要设置为null,否则画板加载不同类型的数据时会有类型错误异常
//可能是因为初始化时,构造器内会把统一数据集合设置为传参的数据集类型,画图器可能也是同样一个道理
XYPlot plot = new XYPlot(lineSeriesConllection,domainAxis,null,lineAndShapeRenderer);
plot.setBackgroundPaint(Color.BLACK);//设置曲线图背景色
plot.setDomainGridlinesVisible(false);//不显示网格
plot.setRangeGridlinePaint(Color.RED);//设置间距格线颜色为红色
plot.setRangeAxis(0, y1Axis);
plot.setRangeAxis(1, y2Axis);




//设置柱状图参数
XYBarRenderer barRenderer = new XYBarRenderer();


barRenderer.setDrawBarOutline(true);//设置显示边框线
barRenderer.setBarPainter(new StandardXYBarPainter());//取消渐变效果
barRenderer.setMargin(0.5);//设置柱形图之间的间隔       
barRenderer.setSeriesPaint(0, Color.YELLOW);//设置柱子内部颜色
barRenderer.setSeriesOutlinePaint(0, Color.YELLOW);//设置柱子边框颜色
barRenderer.setSeriesVisibleInLegend(false);//设置不显示legend(数据颜色提示)
barRenderer.setShadowVisible(false);//设置没有阴影


//设置柱状图y轴参数
NumberAxis y3Axis = new NumberAxis();//设置Y轴,为数值,后面的设置,参考上面的y轴设置
y3Axis.setLabelFont(new Font("微软雅黑", Font.BOLD, 12));//设置y轴字体
y3Axis.setAutoRange(true);//设置采用自动设置时间范围
y3Axis.setTickLabelPaint(Color.ORANGE);//设置y轴刻度值颜色


//这里不设置x轴,x轴参数依照k线图x轴为模板
XYPlot plot2 = new XYPlot(barSeriesCollection, null, y3Axis, barRenderer);
plot2.setBackgroundPaint(Color.BLACK);//设置曲线图背景色
plot2.setDomainGridlinesVisible(false);//不显示网格
plot2.setRangeGridlinePaint(Color.RED);//设置间距格线颜色为红色






//建立一个恰当的联合图形区域对象,以x轴为共享轴
CombinedDomainXYPlot domainXYPlot = new CombinedDomainXYPlot(domainAxis);//
domainXYPlot.add(plot, 2);//添加图形区域对象,后面的数字是计算这个区域对象应该占据多大的区域2/3
domainXYPlot.add(plot2, 1);
domainXYPlot.setGap(2);//设置两个图形区域对象之间的间隔空间


//生成图纸
JFreeChart chart = new JFreeChart(title, new Font("微软雅黑", Font.BOLD, 24), domainXYPlot, true);


calendar.setTimeInMillis(System.currentTimeMillis());
int day = calendar.get(Calendar.DAY_OF_MONTH);
int month = calendar.get(Calendar.MONTH) + 1;
int year = calendar.get(Calendar.YEAR);


String file_path = PropertiesRead.getinstance().getValue("FILE_PATH");
path = year + "-" + month + "-" + day + "/" + Uuid.getUUID() + "timeSharing.png";
file_path = file_path + path;
saveChartAsJPEG(chart, file_path);
} catch (Exception e) {
logger.warn("timeSharingChartPlant:------------Exception--------------");
logger.warn(e);
e.printStackTrace();
}
return path;
}

画图:
/**
* 将chart(图片)存入指定路径中
* @param chart
* @param path
* @throws IOException
*/
private void saveChartAsJPEG(JFreeChart chart, String path) throws IOException{
int width = Integer.valueOf(PropertiesRead.getinstance().getValue("IMG_WIDTH"));
int height = Integer.valueOf(PropertiesRead.getinstance().getValue("IMG_HEIGHT"));


String fileDir = path.substring(0, path.lastIndexOf("/"));
// 创建文件输出流
File fos_jpg = new File(fileDir);
fos_jpg.mkdirs();//创建文件抽象路径
fos_jpg = new File(path);//创建图片文件


// 输出到哪个输出流
ChartUtilities.saveChartAsJPEG(fos_jpg, chart, // 统计图表对象
width, // 宽
height// 高
);
}

/**
* 此内部类专门为分时图提供,已解决分时图y轴数据刻度无法显示多种颜色的情况
* @author t
*
*/
private class NumberAxisY2 extends NumberAxis{
@Override
protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge)
{
AxisState state = new AxisState(cursor);
if (isAxisLineVisible()) {
drawAxisLine(g2, cursor, dataArea, edge);
}


List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
g2.setFont(getTickLabelFont());
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick)iterator.next();
if (isTickLabelsVisible()) {
if(tick.getValue() > 0){
g2.setPaint(Color.RED);
} else if(tick.getValue() == 0){
g2.setPaint(Color.GRAY);
} else {
g2.setPaint(Color.GREEN);
}


float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);
TextUtilities.drawRotatedString(tick.getText(), g2, anchorPoint[0], anchorPoint[1], tick.getTextAnchor(), tick.getAngle(), tick.getRotationAnchor());
}


if (((isTickMarksVisible()) && (tick.getTickType().equals(TickType.MAJOR))) || ((isMinorTickMarksVisible()) && (tick.getTickType().equals(TickType.MINOR))))
{
double ol = getTickMarkOutsideLength();


double il = getTickMarkInsideLength();


float xx = (float)valueToJava2D(tick.getValue(), dataArea, edge);


Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, xx, cursor + il, xx);
}
else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, xx, cursor - il, xx);
}
else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double(xx, cursor - ol, xx, cursor + il);
}
else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double(xx, cursor + ol, xx, cursor - il);
}
g2.draw(mark);
}


}


double used = 0.0D;
if (isTickLabelsVisible()) {
if (edge == RectangleEdge.LEFT) {
used += findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorLeft(used);
}
else if (edge == RectangleEdge.RIGHT) {
used = findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorRight(used);
}
else if (edge == RectangleEdge.TOP) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorUp(used);
}
else if (edge == RectangleEdge.BOTTOM) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorDown(used);
}
}


return state;
}
}


/**
* 此内部类专门为分时图提供,以解决分时图y轴无法以昨日收盘价为中心来描写刻度数据的问题
* @author t 
*
*/
private class NumberAxisY1 extends NumberAxis{
@Override
protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge)
{
AxisState state = new AxisState(cursor);
if (isAxisLineVisible()) {
drawAxisLine(g2, cursor, dataArea, edge);
}


List ticks = refreshTicks(g2, state, dataArea, edge);
//昨日收盘价
double yClose = Double.valueOf(getLabel());
//获取两个价位
NumberTick tick1 = (NumberTick) ticks.get(0);
NumberTick tick2 = (NumberTick) ticks.get(1);


//获取价位差值,而每个差值都是约等于
Double tick1Val = Double.valueOf(tick1.getText());
Double tick2Val = Double.valueOf(tick2.getText());
Double range = tick2Val - tick1Val;


//重置ticks集合,将昨日收盘价置于中间刻度,因设置刻度时与国内股票分时图刻度规则有差异,例:国内为上下7个刻度,加上中间的昨日收盘价,一起为15个刻度
//而这里设置7个刻度则没有写入昨日收盘价的中间刻度,所以这里重置ticks集合,长度为ticks集合size + 1,中间为昨日收盘价,然后以价位差值从中间开始往上
//下两个方向推,则可以得到合适的且平均的刻度价位
int ticksSize = 14;
NumberTick[] nticks = new NumberTick[ticksSize + 1];
NumberTick tickCenter = new NumberTick(yClose, String.valueOf(yClose), tick1.getTextAnchor(), tick1.getRotationAnchor(), tick1.getAngle());
//定位中间刻度,昨日收盘价
nticks[ticksSize / 2] = tickCenter;
double t = yClose;
//计算向下的价位,并写入集合中
for(int i = ticksSize / 2 - 1; i >= 0; i--){
t = t - range;
NumberTick tickF = new NumberTick(t, String.valueOf(t), tick1.getTextAnchor(), tick1.getRotationAnchor(), tick1.getAngle());
nticks[i] = tickF;
}
t = yClose;
//计算向上的价位,并写入集合中
for(int i = ticksSize / 2 + 1; i < ticksSize + 1; i++){
t = t + range;
NumberTick tickF = new NumberTick(t, String.valueOf(t), tick1.getTextAnchor(), tick1.getRotationAnchor(), tick1.getAngle());
nticks[i] = tickF;
}
ticks = new ArrayList();
for(NumberTick ti : nticks){
ticks.add(ti);
}
state.setTicks(ticks);
g2.setFont(getTickLabelFont());
Iterator iterator = ticks.iterator();


while (iterator.hasNext()) {
ValueTick tick = (ValueTick)iterator.next();
double tickValue = Double.valueOf(tick.getText());
float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);
if (isTickLabelsVisible()) {
if(tickValue > yClose){
g2.setPaint(Color.RED);
} else if(tickValue == yClose){
g2.setPaint(Color.GRAY);
} else {
g2.setPaint(Color.GREEN);
}
DecimalFormat df1 = new DecimalFormat("#0.00");


TextUtilities.drawRotatedString(df1.format(tickValue), g2, anchorPoint[0], anchorPoint[1], tick.getTextAnchor(), tick.getAngle(), tick.getRotationAnchor());
}


if (((isTickMarksVisible()) && (tick.getTickType().equals(TickType.MAJOR))) || ((isMinorTickMarksVisible()) && (tick.getTickType().equals(TickType.MINOR))))
{
double ol = getTickMarkOutsideLength();


double il = getTickMarkInsideLength();


float xx = (float)valueToJava2D(tick.getValue(), dataArea, edge);


Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, xx, cursor + il, xx);
}
else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, xx, cursor - il, xx);
}
else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double(xx, cursor - ol, xx, cursor + il);
}
else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double(xx, cursor + ol, xx, cursor - il);
}
g2.draw(mark);
}


}


double used = 0.0D;
if (isTickLabelsVisible()) {
if (edge == RectangleEdge.LEFT) {
used += findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorLeft(used);
}
else if (edge == RectangleEdge.RIGHT) {
used = findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorRight(used);
}
else if (edge == RectangleEdge.TOP) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorUp(used);
}
else if (edge == RectangleEdge.BOTTOM) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());


state.cursorDown(used);
}
}


return state;
}


@Override
protected AxisState drawLabel(String label, Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state) {


AffineTransform t;
Shape rotatedLabelBounds;
double labelx;
double labely;
if (state == null) {
throw new IllegalArgumentException("Null 'state' argument.");
}
//此y轴不提供y轴数据标题
label = "";
if ((label == null) || (label.equals(""))) {
return state;
}


Font font = getLabelFont();
RectangleInsets insets = getLabelInsets();
g2.setFont(font);
g2.setPaint(getLabelPaint());
FontMetrics fm = g2.getFontMetrics();
Rectangle2D labelBounds = TextUtilities.getTextBounds(label, g2, fm);


if (edge == RectangleEdge.TOP) {
t = AffineTransform.getRotateInstance(getLabelAngle(), labelBounds.getCenterX(), labelBounds.getCenterY());


rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
labelx = dataArea.getCenterX();
labely = state.getCursor() - insets.getBottom() - (labelBounds.getHeight() / 2.0D);


TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle(), TextAnchor.CENTER);


state.cursorUp(insets.getTop() + labelBounds.getHeight() + insets.getBottom());
}
else if (edge == RectangleEdge.BOTTOM) {
t = AffineTransform.getRotateInstance(getLabelAngle(), labelBounds.getCenterX(), labelBounds.getCenterY());


rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
labelx = dataArea.getCenterX();
labely = state.getCursor() + insets.getTop() + labelBounds.getHeight() / 2.0D;


TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle(), TextAnchor.CENTER);


state.cursorDown(insets.getTop() + labelBounds.getHeight() + insets.getBottom());
}
else if (edge == RectangleEdge.LEFT) {
t = AffineTransform.getRotateInstance(getLabelAngle() - 1.570796326794897D, labelBounds.getCenterX(), labelBounds.getCenterY());


rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
labelx = state.getCursor() - insets.getRight() - (labelBounds.getWidth() / 2.0D);


labely = dataArea.getCenterY();
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle() - 1.570796326794897D, TextAnchor.CENTER);


state.cursorLeft(insets.getLeft() + labelBounds.getWidth() + insets.getRight());
}
else if (edge == RectangleEdge.RIGHT)
{
t = AffineTransform.getRotateInstance(getLabelAngle() + 1.570796326794897D, labelBounds.getCenterX(), labelBounds.getCenterY());


rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
labelx = state.getCursor() + insets.getLeft() + labelBounds.getWidth() / 2.0D;


labely = dataArea.getY() + dataArea.getHeight() / 2.0D;
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle() + 1.570796326794897D, TextAnchor.CENTER);


state.cursorRight(insets.getLeft() + labelBounds.getWidth() + insets.getRight());
}


return state;
}
}
展开阅读全文

没有更多推荐了,返回首页