現有圖表套件通常要求特定資料格式,迫使開發者以 XSLT 轉換 XML,喪失 XML 彈性。本文實作一個圖表服務,直接從 XML 資料源透過 XPath 提取數據系列與類別,送入 JFreeChart 引擎生成 JPEG,支援瀏覽器直接顯示,無需客戶端外掛。
players.xml)。charts.xml 定義各圖表的資料源 URL、設定檔 URL、系列/類別 XPath、尺寸。pmconfig.xml)定義圖表類型、標題、軸標籤、系列標題。chart、width、height 參數,載入設定,解析 XPath,構建 Dataset,生成 JPEG 輸出。<?xml version="1.0"?>
<root>
<chart id='points'>
<url>https://localhost/players.xml</url>
<config>https://localhost/pmconfig.xml</config>
<series>//Players/Player[Points>0 and Minutes>1000]/Points</series>
<categories>//Players/Player[Points>0 and Minutes>1000]/Name</categories>
<XSize>600</XSize>
<YSize>400</YSize>
</chart>
<chart id='defenders'> ... </chart>
<chart id='makeup'>
<series>//Players/Player/Goals,//Players/Player/Points</series>
<categories>//Players/Player/Number</categories>
</chart>
</root>
<chart>
<Type>1</Type>
<Title>Points By Player</Title>
<CatTitle>Player Name</CatTitle>
<ValTitle>Points</ValTitle>
<SeriesTitles>Points Scored</SeriesTitles>
</chart>
<Players team="New York Power">
<Player>
<Number>30</Number>
<Name>Justi Baumgardt-Yamada</Name>
<Points>1</Points>
...
</Player>
...
</Players>
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String strChart = request.getParameter("chart").toLowerCase();
int nXSize = parseInt(request.getParameter("width"), 0);
int nYSize = parseInt(request.getParameter("height"), 0);
// 載入 charts.xml,依 id 找到 chart 節點
// 取得 url、config、series、categories、XSize、YSize
// 載入資料 XML (players.xml) 與樣式 XML (pmconfig.xml)
// 解析 series、categories XPath 到 Vector
// 呼叫 DoChart() 生成 JFreeChart 物件
response.setContentType("image/jpeg");
ChartUtilities.writeChartAsJPEG(response.getOutputStream(), chart, nXSize, nYSize);
}
private void DoChart() {
int nType = Integer.parseInt(getChildItem("Type")); // 0-10
String title = getChildItem("Title");
String catTitle = getChildItem("CatTitle");
String valTitle = getChildItem("ValTitle");
String seriesTitles = getChildItem("SeriesTitles");
loadSeriesTitles(seriesTitles);
CategoryDataset dataset = createDataset();
switch(nType) {
case 0: chart = ChartFactory.createVerticalBarChart(...); break;
case 1: chart = ChartFactory.createPieChart(...); break;
case 2: chart = ChartFactory.createHorizontalBarChart(...); break;
case 3: chart = ChartFactory.createLineChart(...); break;
case 4: chart = ChartFactory.createAreaChart(...); break;
case 5: chart = ChartFactory.createHorizontalBarChart3D(...); break;
case 6: chart = ChartFactory.createPie3DChart(...); break;
case 7: chart = ChartFactory.createStackedHorizontalBarChart(...); break;
case 8: chart = ChartFactory.createStackedVerticalBarChart(...); break;
case 9: chart = ChartFactory.createStackedVerticalBarChart3D(...); break;
case 10: chart = ChartFactory.createVerticalBarChart3D(...); break;
}
setupChart(); // 套用自訂顏色
}
private CategoryDataset createDataset() {
// 對每個 series XPath,用 XPathAPI 選取節點,提取文字值存入 Vector[]
// 對 categories XPath 同理提取類別標籤
// 建立 Double[][] 數據矩陣,填入 DefaultCategoryDataset
// 設定系列名稱與類別陣列
return dataset;
}
(含所有 import、欄位宣告、輔助方法 GetChildItem、LoadDataDoc、LoadConfigDoc、LoadSeries、LoadCategories、LoadSeriesTitles、setupChart)