市面上圖表庫(如 JFreeChart、ECharts)功能強大,但普遍要求數據符合特定格式。現實中,XML 數據源往往來自第三方系統、結構千差萬別,強行轉換格式(常用 XSLT)不僅增加開發負擔,還掩蓋了 XML 本身的靈活優勢。本文示範如何構建一個通用圖表服務:直接讀取任意 XML,透過 XPath 動態提取數據系列與類別,調用 JFreeChart 生成圖片,最後以 JPEG 形式輸出給瀏覽器——無需客戶端安裝任何插件。
複雜圖表可包含多組數據系列(如預算收入 vs 實際收入),配置文件分離了數據源位置、XPath 提取規則、圖表尺寸、樣式配置,實現「配置即代碼」。
<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>
XPath 支持豐富過濾條件(如得分>0 且上場>1000 分鐘),極大提升數據提取靈活性。
<chart>
<Type>1</Type> <!-- 1=餅圖, 2=柱狀圖... -->
<Title>Points By Player</Title>
<CatTitle>Player Name</CatTitle>
<ValTitle>Points</ValTitle>
<SeriesTitles>Points Scored</SeriesTitles>
</chart>
系列標題、顏色、圖例等樣式均外部化,修改無需重編譯。
doGet() 解析請求參數(chartId、寬高),加載 charts.xml 獲取對應配置。DoChart() 執行核心邏輯:// 伪代碼示意
Document dataDoc = loadXML(dataUrl);
Document cfgDoc = loadXML(configUrl);
NodeList seriesNodes = xpathEval(dataDoc, seriesXPath);
NodeList catNodes = xpathEval(dataDoc, catXPath);
DefaultPieDataset dataset = new DefaultPieDataset();
for (int i=0; i<seriesNodes.getLength(); i++) {
dataset.setValue(catNodes.item(i).getTextContent(),
Double.parseDouble(seriesNodes.item(i).getTextContent()));
}
JFreeChart chart = ChartFactory.createPieChart(
cfgDoc.getTitle(), dataset, true, true, false);
// 應用顏色、字體、圖例等樣式...
ChartUtilities.writeChartAsJPEG(response.getOutputStream(), chart, width, height);
初版 ChartServer 讀取固定 XML 文件。生產環境可擴展為:
//Order[@customerId=$custId]/Amount,由請求參數動態綁定。ChartRenderer 接口,輕鬆切換 JFreeChart、ECharts 服務端渲染、Apache ECharts 等實現。這套「XML + XPath + JFreeChart」架構,以配置驅動替代硬編碼轉換,保留了 XML 的靈活性,同時屏蔽了圖表庫的複雜 API。它是構建企業級報表門戶、儀表盤後端的輕量級起點,擴展性強、維護成本低,極適合敏捷迭代場景。