JFreeCharts 畫k線圖

       

        首先,k線圖裏包含了蠟燭圖、折線圖、柱狀圖,上面圖例。而後,折線圖和蠟燭圖畫在了一個plot裏面。柱狀圖單獨一個plot。java

       先說說蠟燭圖。JFreeCharts裏專門提供了一個叫OHLCSeries(open、high、low、close)的類來存放蠟燭圖數據。構造方法直接指定時間,而後指定OHLC數據就完成了數據構建。數據完成了,而後開始讓圖變得美觀。經過CandlestickRenderer(蠟燭圖畫圖器)來設置股票漲時的顏色(紅)和跌時的顏色(青),畫圖器有專門的方法提供setUp(Down)Paint。而後還能分別指定你的series顏色,setSeriesPaint(int index, Paint paint),這裏若是設置了up(down)paint,這個設置就只會改變外框的顏色(要的就是這個效果)。而後就完成了國內股票市場展現的通用顏色。es6

        均線也是一個道理,設置方法基本差很少。在這裏,均線和k線放在一塊兒。要實現這個效果其實很簡單。在咱們new plot對象時,先不要給對象設置數據和畫圖器,由於蠟燭圖和均線圖使用的series不是同一個(均線使用的是TimeSeries),因此new plot對象時若是設置了數據,則plot會默認數據格式爲OHLCSeries(猜的),而後在設置進TimeSeries的數據時就會出現數據轉換異常。解決的方法就是先不設置,而後初始化好對象後,調用plot.setDateset(int index, SeriesCollection series),而後調用plot.setRenderer來指定畫圖器便可。這樣,兩個數據線就疊加到了一個plot裏。dom

        柱狀圖數據省略掉了噢。數聽說完,而後說說軸線問題,先說x軸(時間軸)。首先,x軸會自動生成,可是不少時候自動生成的每每不符合咱們的需求,因此先.setAutoTickUnitSelection(false);//設置不採用自動選擇刻度值。關閉自動設置,而後關閉自動設置範圍,setAutoRange(false)。關閉完成後,須要設置的地方其實很少,先設置時間範圍setRange(startDate, endDate)、而後設置時間格式setDateFormatOverrride、設置時間刻度間隔setTickUnit(new DateTickUnit(DateTickUnit.DAY, 1)、而後還能夠設置時間顯示規則,例如去掉周6、週日這種節假日SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();.setTimeline(timeline);若是還想排除一些特殊日子,能夠用timeline.addException(date)。這樣,x軸的設置就完成了。而後是y軸,y軸這裏沒有什麼特殊要求,直接先取消自動設置範圍setAutoRange(false),而後設置一個數據範圍就好了,setRange(low, high)。ide

        最後將兩個Plot結合到一個畫板裏。使用CombinedDomainXYPlot這個類來操做便可,調用add(Plot plot, int weight)//添加圖形區域對象,後面的數字是計算這個區域對象應該佔據多大的區域2/3。這個類沒多少要設置的,這裏我就不一一講解了。最後生成Chart,經過ChartUtilities.saveChartAsJPEG存放到指定路徑就ok了。字體

public String stockKChart(Map<String, String>
 params) {

String data = null;

//獲取數據

if("index".equalsIgnoreCase(params.get("type"))){//指數

data = dataService.getIndexKData(params);

} else if("stock".equalsIgnoreCase(params.get("type"))){//股票

data = dataService.getaStockKData(params);

}

params.put("data", data);

logger.info("stockKChart : params : " + params);

logger.info("stockKChart : data : " + data);

String path = null;
//繪畫圖片

if(StringUtils.isBlank(params.get("isAverage"))&&StringUtils.isBlank(params.get("isTradVol")))
{

path = kChartPlant(params);

} else if(StringUtils.isBlank(params.get("isAverage")) && StringUtils.isNotBlank(params.get("isTradVol"))){

path = kBarChartPlant(params);

} else if(StringUtils.isNotBlank(params.get("isAverage")) && StringUtils.isNotBlank(params.get("isTradVol"))){

path = kBarLineChartPlant(params);

}

//返回圖片存放路徑

return path;

}

數據模型:ui

/**

* 獲取指數據日K線數據

*/

public String getIndexKData(Map<String,String> params){

String secucode = (String)params.get("secucode");

String startDate = (String)params.get("startDate");

String endDate = (String)params.get("endDate");

String isAverage = (String)params.get("isAverage");//判斷是否須要均線

String isTradVol = (String)params.get("isTradVol");//判斷是否須要日交易量

String type = (String)params.get("type");



if(secucode.indexOf(".") > 0 ) secucode = secucode.substring(0 , secucode.indexOf(".")); //若是代碼中包括:.sh、.sz時,取出正式的代碼



List<Map> dataList = jydbDataServiceImpl.getAIndexOrStockKData(secucode,false, startDate, endDate, type);

if("1".equalsIgnoreCase(isAverage)){
jydbDataServiceImpl.initAverage(secucode ,false ,type);

}

Map map = new HashMap();

List quoteList = new ArrayList();//封裝日行情數據

List tradVol = new ArrayList();//封裝日交易量數據

List average5 = new ArrayList();//五日均線數據

List average20 = new ArrayList();//十日均線數據

String secuabbr = null;

// System.out.println("dataList is :"+dataList);

for(Map data : dataList){

if(secuabbr == null) {

secuabbr = (String)data.get("secuabbr");

if(secuabbr.startsWith("申萬")){

secuabbr = secuabbr.substring(2);

}

}

List dayQuote = new ArrayList();//日K線數據

List dayTradVol = new ArrayList();//日成交量數據

Date tradingDay = (Date)data.get("tradingday");

Double openPrice = (Double)data.get("openprice");

Double highprice = (Double)data.get("highprice");

Double lowprice = (Double)data.get("lowprice");

Double closeprice = (Double)data.get("closeprice");

Double turnovervolume = (Double)data.get("turnovervolume");

dayQuote.add(DateFormatUtils.getDate12(tradingDay));

dayQuote.add(openPrice);

dayQuote.add(closeprice);

dayQuote.add(highprice);

dayQuote.add(lowprice);

quoteList.add(dayQuote);
//添加成交量數據

if("1".equalsIgnoreCase(isTradVol)){

dayTradVol.add(DateFormatUtils.getDate12(tradingDay));

dayTradVol.add(turnovervolume);

tradVol.add(dayTradVol);

}



//添加均線數據

if("1".equalsIgnoreCase(isAverage)){

if(jydbDataServiceImpl.indexFiveAverage.get(secucode+"_"+DateFormatUtils.getDate12(tradingDay)) != null){

List average5day = new ArrayList();

average5day.add(DateFormatUtils.getDate12(tradingDay));
average5day.add(jydbDataServiceImpl.indexFiveAverage.get(secucode+"_"+DateFormatUtils.getDate12(tradingDay)));

average5.add(average5day);

}

if(jydbDataServiceImpl.indexTwentyAverage.get(secucode+"_"+DateFormatUtils.getDate12(tradingDay)) != null){

List average20day = new ArrayList();

average20day.add(DateFormatUtils.getDate12(tradingDay));

average20day.add(jydbDataServiceImpl.indexTwentyAverage.get(secucode+"_"+DateFormatUtils.getDate12(tradingDay)));

average20.add(average20day);

}

}

}
Map average = new HashMap();

if(average5.size() > 0){

average.put("MA5",average5);

}

if(average20.size() > 0){

average.put("MA20",average20);

}

if(average.size() > 0){

map.put("average", average);

}

map.put("quoteList", quoteList);

if(tradVol.size() > 0){

map.put("tradVol", tradVol);
}

if(secuabbr != null){

map.put("title", secuabbr+"("+secucode+")");

}else{

map.put("title", secucode);

}

return JsonUtil.toJson(map);

}

/**
* K線圖繪畫工廠
* 單k線
* @param params
* @return 圖片存放路徑
*/
private String kChartPlant(Map<String, String> params) {
String path = null;
try{
//獲取繪圖數據
String data = params.get("data");


Map<String, Object> datas = (Map<String, Object>) JsonUtil.parse(data);
//獲取標題
String title = (String) datas.get("title");


OHLCSeriesCollection seriesCollection = new OHLCSeriesCollection();//定義k線圖數據集
OHLCSeries series1 = new OHLCSeries("k_up");//高開低收數據序列,股票K線圖的四個數據,依次是開,高,低,收
OHLCSeries series2 = new OHLCSeries("k_down");//定義上漲和下跌的兩個數據集


//K線圖數據
List<List<Object>> quoteList = (List<List<Object>>) datas.get("quoteList");


double mLow = 0d;
double mHigh = 0d;


//統計這段數據包含多少個交易日,好計算設置時間軸刻度規則
int days = 0;


String startDate = null;
String endDate = null;
int i = 0;


//獲取全部工做日
List<Date> workDate = new ArrayList<Date>();


//添加k線圖數據,添加成交量數據
for(List<Object> list : quoteList){
Date quoteListDate = DateFormatUtils.getDateTimeForAll12((String) list.get(0));
double open = Double.valueOf(list.get(1).toString());
double close = Double.valueOf(list.get(2).toString());
double high = Double.valueOf(list.get(3).toString());
double low = Double.valueOf(list.get(4).toString());
Calendar quoteCalendar = Calendar.getInstance();
quoteCalendar.setTimeInMillis(quoteListDate.getTime());


workDate.add(quoteListDate);


//取這段交易日內最高和最低價格
if(mHigh < high){
mHigh = high;
}
if(mLow > low){
mLow = low;
} else if(mLow == 0){
mLow = low;
}
if(i == 0){//拿到起始時間
startDate = (String) list.get(0);
}
if(i == quoteList.size() - 1){
endDate = (String) list.get(0);
}
if(open > close){
series2.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);
} else {
series1.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);
}
i++;
days++;
}


//將數據添加進數據集合
seriesCollection.addSeries(series1);
seriesCollection.addSeries(series2);


if(StringUtils.isBlank(params.get("startDate"))){
params.put("startDate", startDate);
}
if(StringUtils.isBlank(params.get("startDate"))){
params.put("endDate", endDate);
}
//獲取全部節假日
List<Date> allHolidys = getAllHolidays(workDate);


//建立主題樣式
StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
//設置標題字體
standardChartTheme.setExtraLargeFont(new Font("微軟雅黑",Font.BOLD,20));
//設置圖例的字體
standardChartTheme.setRegularFont(new Font("微軟雅黑",Font.PLAIN,15));
//應用主題樣式
ChartFactory.setChartTheme(standardChartTheme);


//生成k線圖畫板
JFreeChart chart = ChartFactory.createCandlestickChart(title, null, null, seriesCollection, true);


CandlestickRenderer candlestickRender = new CandlestickRenderer();//設置K線圖的畫圖器
candlestickRender.setUpPaint(Color.BLACK);//設置股票上漲的K線圖顏色
candlestickRender.setDownPaint(Color.CYAN);//設置股票下跌的K線圖顏色
candlestickRender.setSeriesPaint(1, Color.CYAN);//設置股票下跌的K線圖顏色
candlestickRender.setSeriesPaint(0, Color.RED);//設置股票上漲的K線圖顏色
candlestickRender.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_AVERAGE);//設置如何對K線圖的寬度進行設定
candlestickRender.setAutoWidthGap(0.001);//設置各個K線圖之間的間隔

candlestickRender.setSeriesVisibleInLegend(false);//設置不顯示legend(數據顏色提示)
//設置k線圖x軸,也就是時間軸
DateAxis domainAxis = new DateAxis();
domainAxis.setAutoRange(false);//設置不採用自動設置時間範圍
//設置時間範圍,注意,最大和最小時間設置時須要+ - 。不然時間刻度沒法顯示
Date da = DateFormatUtils.getDateTimeForAll12(endDate);
da.setTime(da.getTime() + 1);
Date sda = DateFormatUtils.getDateTimeForAll12(startDate);
sda.setTime(sda.getTime() - 1);
domainAxis.setRange(sda, da);



DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
domainAxis.setAutoTickUnitSelection(false);//設置不採用自動選擇刻度值
domainAxis.setTickMarkPosition(DateTickMarkPosition.START);//設置標記的位置
domainAxis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));
domainAxis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());// 設置標準的時間刻度單位
domainAxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, days / Const.TIME_SCALE));// 設置時間刻度的間隔
domainAxis.setDateFormatOverride(df);//設置時間格式
SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();//設置時間線顯示的規則,用這個方法摒除掉週六和週日這些沒有交易的日期
//排除全部節假日
for(Date holiday : allHolidys){
timeline.addException(holiday);
}
domainAxis.setTimeline(timeline);
//設置Y軸
NumberAxis y1Axis = new NumberAxis();
y1Axis.setAutoRange(false);//設置不採用自動設置時間範圍
y1Axis.setUpperMargin(0.5D);//設置向上邊框距離
y1Axis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));
y1Axis.setRange(mLow - (mLow * Const.UP_OR_DOWN_RANGE), mHigh + (mHigh * Const.UP_OR_DOWN_RANGE));//設置y軸數據範圍




XYPlot plot = (XYPlot) chart.getPlot();//生成畫圖細節
plot.setRenderer(candlestickRender);//設置畫圖器
plot.setBackgroundPaint(Color.BLACK);//設置曲線圖背景色
plot.setDomainGridlinesVisible(false);//不顯示網格
plot.setRangeGridlinePaint(Color.RED);//設置間距格線顏色爲紅色
plot.setDomainAxis(domainAxis);//設置x軸
plot.setRangeAxis(y1Axis);//設置y軸


Calendar calendar = Calendar.getInstance();
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() + "k.png";
file_path = file_path + path;
saveChartAsJPEG(chart, file_path);
} catch (Exception e) {
logger.warn("kChartPlant:------------Exception--------------");
logger.warn(e);
e.printStackTrace();
}
return path;
}


/**

* 組合圖繪畫工廠

* K線圖 + 柱狀圖

* @param params

* @return 圖片存放路徑

*/

private String kBarChartPlant(Map<String, String> params) {

String path = null;

try{ 

//獲取繪圖數據

String data = params.get("data");

Map<String, Object> datas = (Map<String, Object>) JsonUtil.parse(data);

//獲取標題

String title = (String) datas.get("title");





OHLCSeriesCollection seriesCollection = new OHLCSeriesCollection();//定義k線圖數據集

OHLCSeries series1 = new OHLCSeries("k_up");//高開低收數據序列,股票K線圖的四個數據,依次是開,高,低,收

OHLCSeries series2 = new OHLCSeries("k_down");//定義上漲和下跌的兩個數據集





TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();//保留成交量數據的集合

TimeSeries series3 = new TimeSeries("bar_up");//對應時間成交量數據

TimeSeries series4 = new TimeSeries("bar_down");//對應時間成交量數據
//K線圖數據

List<List<Object>> quoteList = (List<List<Object>>) datas.get("quoteList");





//成交量數據

List<List<Object>> tradVol = (List<List<Object>>) datas.get("tradVol");





double mLow = 0d;

double mHigh = 0d;





//統計這段數據包含多少個交易日,好計算設置時間軸刻度規則
int days = 0;





String startDate = null;

String endDate = null;





//獲取全部工做日

List<Date> workDate = new ArrayList<Date>();

//添加k線圖數據,添加成交量數據

for(int i = 0; i < quoteList.size(); i++){

Date quoteListDate = DateFormatUtils.getDateTimeForAll12((String) quoteList.get(i).get(0));

double open = Double.valueOf(quoteList.get(i).get(1).toString());

double close = Double.valueOf(quoteList.get(i).get(2).toString());

double high = Double.valueOf(quoteList.get(i).get(3).toString());

double low = Double.valueOf(quoteList.get(i).get(4).toString());

Calendar quoteCalendar = Calendar.getInstance();

quoteCalendar.setTimeInMillis(quoteListDate.getTime());
Date tradVolDate = DateFormatUtils.getDateTimeForAll12((String) tradVol.get(i).get(0));

double vol = Double.valueOf(tradVol.get(i).get(1).toString());





Calendar volCalendar = Calendar.getInstance();

volCalendar.setTimeInMillis(tradVolDate.getTime());





workDate.add(quoteListDate);





//取這段交易日內最高和最低價格

if(mHigh < high){

mHigh = high;

}

if(mLow > low){

mLow = low;

} else if(mLow == 0){

mLow = low;
}

if(i == 0){//拿到起始時間

startDate = (String) quoteList.get(i).get(0);

}

if(i == quoteList.size() - 1){

endDate = (String) quoteList.get(i).get(0);

}





if(open > close){

series2.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);

series4.add(new Day(volCalendar.get(volCalendar.DAY_OF_MONTH), volCalendar.get(volCalendar.MONTH) + 1, volCalendar.get(volCalendar.YEAR)), vol);

} else {
series1.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);

series3.add(new Day(volCalendar.get(volCalendar.DAY_OF_MONTH), volCalendar.get(volCalendar.MONTH) + 1, volCalendar.get(volCalendar.YEAR)), vol);

}        


days++;

}









//將數據添加進數據集合

seriesCollection.addSeries(series1);

seriesCollection.addSeries(series2);


timeSeriesCollection.addSeries(series3);

timeSeriesCollection.addSeries(series4);





if(StringUtils.isBlank(params.get("startDate"))){

params.put("startDate", startDate);

}
if(StringUtils.isBlank(params.get("startDate"))){

params.put("endDate", endDate);

}

//獲取全部節假日

List<Date> allHolidys = getAllHolidays(workDate);





//設置k線圖參數

CandlestickRenderer candlestickRender = new CandlestickRenderer();//設置K線圖的畫圖器

candlestickRender.setUpPaint(Color.BLACK);//設置股票上漲的K線圖顏色

candlestickRender.setDownPaint(Color.CYAN);//設置股票下跌的K線圖顏色

candlestickRender.setSeriesPaint(1, Color.CYAN);//設置股票下跌的K線圖顏色

candlestickRender.setSeriesPaint(0, Color.RED);//設置股票上漲的K線圖顏色

candlestickRender.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_AVERAGE);//設置如何對K線圖的寬度進行設定

candlestickRender.setAutoWidthGap(0.001);//設置各個K線圖之間的間隔

candlestickRender.setSeriesVisibleInLegend(false);//設置不顯示legend(數據顏色提示)





NumberAxis y1Axis=new NumberAxis();//設置Y軸,爲數值,後面的設置,參考上面的y軸設置

y1Axis.setAutoRange(false);//設置不採用自動設置時間範圍

y1Axis.setUpperMargin(0.5D);//設置向上邊框距離
y1Axis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));

y1Axis.setRange(mLow - (mLow * Const.UP_OR_DOWN_RANGE), mHigh + (mHigh * Const.UP_OR_DOWN_RANGE));//設置y軸數據範圍





//設置k線圖x軸,也就是時間軸

DateAxis domainAxis = new DateAxis();

domainAxis.setAutoRange(false);//設置不採用自動設置時間範圍

//設置時間範圍,注意,最大和最小時間設置時須要+ - 。不然時間刻度沒法顯示

Date da = DateFormatUtils.getDateTimeForAll12(endDate);

da.setTime(da.getTime() + 1);

Date sda = DateFormatUtils.getDateTimeForAll12(startDate);

sda.setTime(sda.getTime() - 1);

domainAxis.setRange(sda, da);





DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

domainAxis.setAutoTickUnitSelection(false);//設置不採用自動選擇刻度值

domainAxis.setTickMarkPosition(DateTickMarkPosition.START);//設置標記的位置

domainAxis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());// 設置標準的時間刻度單位

domainAxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, days / Const.TIME_SCALE));// 設置時間刻度的
domainAxis.setDateFormatOverride(df);//設置時間格式

SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();//設置時間線顯示的規則,用這個方法摒除掉週六和週日這些沒有交易的日期

//排除全部節假日

for(Date holiday : allHolidys){

timeline.addException(holiday);

}

domainAxis.setTimeline(timeline);






XYPlot plot = new XYPlot(seriesCollection,domainAxis,y1Axis,candlestickRender);//生成畫圖細節

plot.setBackgroundPaint(Color.BLACK);//設置曲線圖背景色

plot.setDomainGridlinesVisible(false);//不顯示網格

plot.setRangeGridlinePaint(Color.RED);//設置間距格線顏色爲紅色





//設置柱狀圖參數

XYBarRenderer barRenderer = new XYBarRenderer();





barRenderer.setDrawBarOutline(true);//設置顯示邊框線

barRenderer.setBarPainter(new StandardXYBarPainter());//取消漸變效果

barRenderer.setMargin(0.3);//設置柱形圖之間的間隔
       

barRenderer.setSeriesPaint(0, Color.BLACK);//設置柱子內部顏色

barRenderer.setSeriesPaint(1, Color.CYAN);//設置柱子內部顏色

barRenderer.setSeriesOutlinePaint(0, Color.RED);//設置柱子邊框顏色

barRenderer.setSeriesOutlinePaint(1, Color.CYAN);//設置柱子邊框顏色

barRenderer.setSeriesVisibleInLegend(false);//設置不顯示legend(數據顏色提示)

barRenderer.setShadowVisible(false);//設置沒有陰影





//設置柱狀圖y軸參數

NumberAxis y2Axis=new NumberAxis();//設置Y軸,爲數值,後面的設置,參考上面的y軸設置

y2Axis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));//設置y軸字體

y2Axis.setAutoRange(true);//設置採用自動設置範圍





XYPlot plot2 = new XYPlot(timeSeriesCollection, null, y2Axis, barRenderer);

plot2.setBackgroundPaint(Color.BLACK);//設置曲線圖背景色
plot2.setDomainGridlinesVisible(false);//不顯示網格

plot2.setRangeGridlinePaint(Color.RED);//設置間距格線顏色爲紅色

CombinedDomainXYPlot domainXYPlot = new CombinedDomainXYPlot(domainAxis);//創建一個恰當的聯合圖形區域對象,以x軸爲共享軸

domainXYPlot.add(plot, 2);//添加圖形區域對象,後面的數字是計算這個區域對象應該佔據多大的區域2/3

domainXYPlot.add(plot2, 1);//添加圖形區域對象,後面的數字是計算這個區域對象應該佔據多大的區域2/3

domainXYPlot.setGap(10);//設置兩個圖形區域對象之間的間隔空間

JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, domainXYPlot, true);





Calendar calendar = Calendar.getInstance();

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() + "kBar.png";

file_path = file_path + path;

saveChartAsJPEG(chart, file_path);

} catch (Exception e) {

logger.warn("kBarChartPlant:------------Exception--------------");

logger.warn(e);

e.printStackTrace();

}

return path;

}
/**

* 組合圖繪畫工廠

* k線圖 + 柱狀圖 + 折線圖

* @param params

* @return 圖片存放路徑

*/

private String kBarLineChartPlant(Map<String, String> params) {

String path = null;

try{

//獲取繪圖數據

String data = params.get("data");





Map<String, Object> datas = (Map<String, Object>) JsonUtil.parse(data);

//獲取標題

String title = (String) datas.get("title");





OHLCSeriesCollection seriesCollection = new OHLCSeriesCollection();//定義k線圖數據集
OHLCSeries series1 = new OHLCSeries("");//高開低收數據序列,股票K線圖的四個數據,依次是開,高,低,收

OHLCSeries series2 = new OHLCSeries("");//定義上漲和下跌的兩個數據集





//K線圖數據

List<List<Object>> quoteList = (List<List<Object>>) datas.get("quoteList");





//成交量數據

List<List<Object>> tradVol = (List<List<Object>>) datas.get("tradVol");





TimeSeriesCollection volSeriesCollection = new TimeSeriesCollection();//保留成交量數據的集合

TimeSeries series3 = new TimeSeries("");//對應時間成交量數據

TimeSeries series4 = new TimeSeries("");//對應時間成交量數據
double mLow = 0d;

double mHigh = 0d;





//統計這段數據包含多少個交易日,好計算設置時間軸刻度規則

int days = 0;





String startDate = null;

String endDate = null;





//全部工做日

List<Date> workDate = new ArrayList<Date>();

//添加k線圖數據,添加成交量數據

for(int i = 0; i < quoteList.size(); i++){

Date quoteListDate = DateFormatUtils.getDateTimeForAll12((String) quoteList.get(i).get(0));

double open = Double.valueOf(quoteList.get(i).get(1).toString());

double close = Double.valueOf(quoteList.get(i).get(2).toString());

double high = Double.valueOf(quoteList.get(i).get(3).toString());

double low = Double.valueOf(quoteList.get(i).get(4).toString());
Calendar quoteCalendar = Calendar.getInstance();

quoteCalendar.setTimeInMillis(quoteListDate.getTime());





Date tradVolDate = DateFormatUtils.getDateTimeForAll12((String) tradVol.get(i).get(0));

double vol = Double.valueOf(tradVol.get(i).get(1).toString());





Calendar volCalendar = Calendar.getInstance();

volCalendar.setTimeInMillis(tradVolDate.getTime());





workDate.add(quoteListDate);





//取這段交易日內最高和最低價格

if(mHigh < high){

mHigh = high;

}
if(mLow > low){

mLow = low;

} else if(mLow == 0){

mLow = low;

}

if(i == 0){//拿到起始時間

startDate = (String) quoteList.get(i).get(0);

}

if(i == quoteList.size() - 1){

endDate = (String) quoteList.get(i).get(0);

}

if(open > close){

series2.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);

series4.add(new Day(volCalendar.get(volCalendar.DAY_OF_MONTH), volCalendar.get(volCalendar.MONTH) + 1, volCalendar.get(volCalendar.YEAR)), vol);

} else {

series1.add(new Day(quoteCalendar.get(quoteCalendar.DAY_OF_MONTH), quoteCalendar.get(quoteCalendar.MONTH) + 1, quoteCalendar.get(quoteCalendar.YEAR)), open, high, low, close);

series3.add(new Day(volCalendar.get(volCalendar.DAY_OF_MONTH), volCalendar.get(volCalendar.MONTH) + 1, volCalendar.get(volCalendar.YEAR)), vol);

}
days++;

}





//k線圖數據

seriesCollection.addSeries(series1);

seriesCollection.addSeries(series2);

//成交量數據

volSeriesCollection.addSeries(series3);

volSeriesCollection.addSeries(series4);





if(StringUtils.isBlank(params.get("startDate"))){

params.put("startDate", startDate);

}

if(StringUtils.isBlank(params.get("startDate"))){

params.put("endDate", endDate);
}

//獲取全部節假日

List<Date> allHolidys = getAllHolidays(workDate);





//獲取均線圖數據

Map<String, List<List<Object>>> average = (Map<String, List<List<Object>>>) datas.get("average");





List<List<Object>> fiveDayAvg = average.get("MA5");//5天均線數據

List<List<Object>> twentyDayAvg = average.get("MA20");//20天均線數據





TimeSeriesCollection lineSeriesConllection = new TimeSeriesCollection();//保留均線圖數據的集合

TimeSeries series5 = new TimeSeries("MA5");//對應時間成交量數據,5天

TimeSeries series6 = new TimeSeries("MA10");//對應時間成交量數據,10天

TimeSeries series7 = new TimeSeries("MA20");//對應時間成交量數據,20天
//添加均線圖5天數據

if(fiveDayAvg != null){

for(List<Object> list : fiveDayAvg){

Date avgDate = DateFormatUtils.getDateTimeForAll12((String) list.get(0));

double avg = Double.valueOf(list.get(1).toString());





Calendar avgCalendar = Calendar.getInstance();

avgCalendar.setTimeInMillis(avgDate.getTime());

series5.add(new Day(avgCalendar.get(avgCalendar.DAY_OF_MONTH), avgCalendar.get(avgCalendar.MONTH) + 1, avgCalendar.get(avgCalendar.YEAR)), avg);

}

}

//添加均線圖20天數據

if(twentyDayAvg != null){

for(List<Object> list : twentyDayAvg){

Date avgDate = DateFormatUtils.getDateTimeForAll12((String) list.get(0));

double avg = Double.valueOf(list.get(1).toString());





Calendar avgCalendar = Calendar.getInstance();
avgCalendar.setTimeInMillis(avgDate.getTime());

series7.add(new Day(avgCalendar.get(avgCalendar.DAY_OF_MONTH), avgCalendar.get(avgCalendar.MONTH) + 1, avgCalendar.get(avgCalendar.YEAR)), avg);

}

}

lineSeriesConllection.addSeries(series5);

lineSeriesConllection.addSeries(series6);

lineSeriesConllection.addSeries(series7);





//設置K線圖的畫圖器

CandlestickRenderer candlestickRender = new CandlestickRenderer();

candlestickRender.setUpPaint(Color.BLACK);//設置股票上漲的K線圖顏色

candlestickRender.setDownPaint(Color.CYAN);//設置股票下跌的K線圖顏色

candlestickRender.setSeriesPaint(1, Color.CYAN);//設置股票下跌的K線圖顏色

candlestickRender.setSeriesPaint(0, Color.RED);//設置股票上漲的K線圖顏色

candlestickRender.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_AVERAGE);//設置如何對K線圖的寬度進行設定

candlestickRender.setAutoWidthGap(0.001);//設置各個K線圖之間的間隔
candlestickRender.setSeriesVisibleInLegend(false);//設置不顯示legend(數據顏色提示)





//設置k線圖y軸參數

NumberAxis y1Axis=new NumberAxis();//設置Y軸,爲數值,後面的設置,參考上面的y軸設置

y1Axis.setAutoRange(false);//設置不採用自動設置數據範圍

y1Axis.setUpperMargin(Const.UPPER_RANGE);//設置向上邊框距離

y1Axis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));

y1Axis.setRange(mLow - (mLow * Const.UP_OR_DOWN_RANGE), mHigh + (mHigh * Const.UP_OR_DOWN_RANGE));//設置y軸數據範圍

//        y1Axis.setAutoTickUnitSelection(true);//數據軸的數據標籤是否自動肯定(默認爲true)





//設置k線圖x軸,也就是時間軸

DateAxis domainAxis = new DateAxis();

domainAxis.setAutoRange(false);//設置不採用自動設置時間範圍

//設置時間範圍,注意,最大和最小時間設置時須要+ - 。不然時間刻度沒法顯示

Date da = DateFormatUtils.getDateTimeForAll12(endDate);

da.setTime(da.getTime() + 1);
Date sda = DateFormatUtils.getDateTimeForAll12(startDate);

sda.setTime(sda.getTime() - 1);

domainAxis.setRange(sda, da);

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");


domainAxis.setAutoTickUnitSelection(false);//設置不採用自動選擇刻度值

domainAxis.setTickMarkPosition(DateTickMarkPosition.START);//設置標記的位置

domainAxis.setStandardTickUnits(DateAxis.createStandardDateTickUnits());// 設置標準的時間刻度單位

domainAxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, days / Const.TIME_SCALE));// 設置時間刻度的間隔

domainAxis.setDateFormatOverride(df);//設置時間格式





SegmentedTimeline timeline = SegmentedTimeline.newMondayThroughFridayTimeline();//設置時間線顯示
//排除全部節假日

for(Date holiday : allHolidys){

timeline.addException(holiday);

}

domainAxis.setTimeline(timeline);





//設置均線圖畫圖器

XYLineAndShapeRenderer lineAndShapeRenderer = new XYLineAndShapeRenderer();

lineAndShapeRenderer.setBaseItemLabelsVisible(true);

lineAndShapeRenderer.setSeriesShapesVisible(0, false);//設置不顯示數據點模型

lineAndShapeRenderer.setSeriesShapesVisible(1, false);

lineAndShapeRenderer.setSeriesShapesVisible(2, false);

lineAndShapeRenderer.setSeriesPaint(0, Color.WHITE);//設置均線顏色

lineAndShapeRenderer.setSeriesPaint(1, Color.YELLOW);

lineAndShapeRenderer.setSeriesPaint(2, Color.MAGENTA);

//生成畫圖細節 第一個和最後一個參數這裏須要設置爲null,不然畫板加載不一樣類型的數據時會有類型錯誤異常

//多是由於初始化時,構造器內會把統一數據集合設置爲傳參的數據集類型,畫圖器可能也是一樣一個道理

XYPlot plot = new XYPlot(null,domainAxis,y1Axis,null);

plot.setBackgroundPaint(Color.BLACK);//設置曲線圖背景色

plot.setDomainGridlinesVisible(false);//不顯示網格

plot.setRangeGridlinePaint(Color.RED);//設置間距格線顏色爲紅色






//將設置好的數據集合和畫圖器放入畫板

plot.setDataset(0, seriesCollection);

plot.setRenderer(0, candlestickRender);

plot.setDataset(1, lineSeriesConllection);

plot.setRenderer(1, lineAndShapeRenderer);

//設置柱狀圖參數

XYBarRenderer barRenderer = new XYBarRenderer();





barRenderer.setDrawBarOutline(true);//設置顯示邊框線

barRenderer.setBarPainter(new StandardXYBarPainter());//取消漸變效果

barRenderer.setMargin(0.3);//設置柱形圖之間的間隔
       

barRenderer.setSeriesPaint(0, Color.BLACK);//設置柱子內部顏色

barRenderer.setSeriesPaint(1, Color.CYAN);//設置柱子內部顏色

barRenderer.setSeriesOutlinePaint(0, Color.RED);//設置柱子邊框顏色

barRenderer.setSeriesOutlinePaint(1, Color.CYAN);//設置柱子邊框顏色

barRenderer.setSeriesVisibleInLegend(false);//設置不顯示legend(數據顏色提示)

barRenderer.setShadowVisible(false);//設置沒有陰影

//設置柱狀圖y軸參數

NumberAxis y2Axis=new NumberAxis();//設置Y軸,爲數值,後面的設置,參考上面的y軸設置

y2Axis.setLabelFont(new Font("微軟雅黑", Font.BOLD, 12));//設置y軸字體

y2Axis.setAutoRange(true);//設置採用自動設置時間範圍





//這裏不設置x軸,x軸參數依照k線圖x軸爲模板

XYPlot plot2 = new XYPlot(volSeriesCollection, null, y2Axis, 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);//添加圖形區域對象,後面的數字是計算這個區域對象應該佔據多大的區域1/3

domainXYPlot.setGap(10);//設置兩個圖形區域對象之間的間隔空間

//生成圖紙
JFreeChart chart = new JFreeChart(title, new Font("微軟雅黑", Font.BOLD, 24), domainXYPlot, true);





Calendar calendar = Calendar.getInstance();

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() + "kLineBar.png";

file_path = file_path + path;

saveChartAsJPEG(chart, file_path);

} catch (Exception e) {

logger.warn("kBarLineChartPlant:------------Exception--------------");

logger.warn(e);

e.printStackTrace();

}

return path;

}
相關文章
相關標籤/搜索