https://github.com/paohaijiao/jquick-pdf
https://github.com/paohaijiao/jquick-pdf
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/paohaijiao/jquick-pdf
- Owner: paohaijiao
- Created: 2025-06-21T14:47:50.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-25T23:51:17.000Z (7 months ago)
- Last Synced: 2025-12-26T23:53:07.805Z (7 months ago)
- Language: Java
- Size: 19.6 MB
- Stars: 79
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README-EN.md
- Changelog: change.md
Awesome Lists containing this project
- fucking-awesome-java - jquick-pdf - Generates PDFs from HTML-like templates and ECharts-style charts using iText 7, without a browser dependency. (Projects / PDF)
- awesome-java - jquick-pdf - Generates PDFs from HTML-like templates and ECharts-style charts using iText 7, without a browser dependency. (Projects / PDF)
README
# 📄 JQuickPDF – The lightest and purest Java PDF generation library
[简体中文](./README.md) | [ENGLISH]
> JQuickPDF is a pure Java library specifically designed to render syntax like HTML and CSS styles into PDFs,
> **It does not rely on any browser or external rendering engine at all**。
> **Supports commonly used Echart graphics such as bar charts, maps, radar charts, and pie chart**。
## ✅ core feature
- 🚀 **Pure Java implementation**
No need to install a browser, WebKit, or any native libraries
- 🎨 **CSS support**
Supports most CSS styles, including borders, padding, floating, etc
- 📝 **template-friendly**
It can be used in conjunction with template engines such as Thymeleaf and FreeMarker to generate dynamic content
- 📊 **graphics-rich**
Supports over 20 common Echart graphics
- 💰 **open source and free**
under the Apache License
---
| 图标类型 | 备注 |
|------------------|--------------------|
| BAR | 柱状图 |
| BOXPLOT | 箱线图 |
| HEATMAP | 热力图 |
| K | K线图(蜡烛图) |
| LINE | 折线图 |
| PIE | 饼图 |
| RADAR | 雷达图 |
| RELATION | 关系图 |
| SCATTER | 散点图 |
| SUNBURST | 旭日图(1.5.1) |
| Treemap | 矩形树图(1.5.1) |
| Bubble | 气泡图(1.5.1) |
| Calendar | 日历活动图(1.5.3) |
| Lunar | 日历(1.5.3) |
| Funnel | 漏斗图(1.5.3) |
| CorrectionMatrix | 相关系数矩阵(1.5.3) |
| Gantt | 甘特图(1.5.3) |
| Gauge | 仪表盘(1.5.3) |
| WordsCloud | 词云(1.5.3) |
| GEO Json | 地图(1.5.4) |
| Line Bar | 组合图形<折线条形图>(1.5.5) |
| Multiple Line | 多重折线图(1.5.6) |
| Multiple Bar | 多重条形图(1.5.7) |
| AREA | 区域堆积图(1.5.8) |
| HorizontalBar | 横向条形图(1.5.9) |
| MutipleHorizontalBar | 多重横向条形图(1.5.10) |
| DoubleRadar | 双雷达图(1.5.11) |
## 🚀 项目状态
[](https://github.com/paohaijiao/jquick-pdf)
[](https://github.com/paohaijiao/jquick-pdf)
[](https://github.com/paohaijiao/jquick-pdf/issues)
[](https://opensource.org/licenses/Apache-2.0)
---
### 📖 Table of Contents
- [✨ Core Features](#-core-features)
- [📦 Quick Start](#-quick-start)
- [Installation](#installation)
- [Basic Usage](#basic-usage)
- [🎨 Style System](#-style-system)
- [Block Element Styles](#block-element-styles)
- [Property Styles](#property-styles)
- [🧩 Content Elements](#-content-elements)
- [Text Elements](#text-elements)
- [Layout Elements](#layout-elements)
- [List Elements](#list-elements)
- [Table Elements](#table-elements)
- [Form Elements](#form-elements)
- [Media Elements](#media-elements)
- [📊 Chart Support](#-chart-support)
- [🔧 Special Elements](#-special-elements)
- [💌 Support the Project](#-support-the-project)
---
## ✨ Core Features
JQuickPDF is a lightweight Java library used to generate PDF documents from HTML like templates. Support dynamic data binding, rich style control, and multiple common chart types.
### 🌟 Key Features
- ✅ HTML-like template syntax, easy to get started
- ✅ Support for dynamic data binding
- ✅ Rich style control
- ✅ Support for multiple chart types
- ✅ Lightweight with no redundant dependencies
```java
JQuickPdfXExecutor executor = new JQuickPdfXExecutor();
executor.execute(templateContent);
```
## 📦 📦 Quick Start
```xml
io.github.paohaijiao
jquick-pdf
最新版本
```
## 📝 Basic Grammar
Create a simple PDF template:
```html
Hello JQuickPDF
This is a sample paragraph.
```
### Syntax Rules
```string
Content
```
#### Elements
##### Text Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `
` | Paragraph block (Paragraph) | `
'Paragraph content'
` |
| `-` | Heading (styled paragraph) | `'Heading content'
` |
| `` | Inline text container (Chunk) | `'Inline text'` |
| `
` | Line break (Newline) | `
` |
| `` | Tab character | `'Text after tabs'
` |
##### Layout Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `
` | Block container (Div) | `'Block container content'` |
| `` | Section break (AreaBreak) | `` |
| `` | Explicit page break (NewPage) | `next_area` |
| `` | Line separator | `` |
##### List and Table Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `` | Ordered/unordered list (List) | `
'Option 1' ` |
| `` | List item (ListItem) | `
'Option 1' ` |
| `` | Table container (Table) | `'Data'` |
| `` | Table row (TableRow) | `` |
| `` | Table data cell (TableCell) | `'Data'` |
| `` | Table header cell (TableCell) | `'Header'` |
##### Form Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `` | Button (PushbuttonField) | `'Submit'` |
| `` | Checkbox (CheckboxField) | `'Submit'` |
| `` | Text input field (TextField) | `'Hello China'` |
| `` | Combo box (ComboBoxField) | `'Submit'` |
| `` | Multi-line text input field (TextAreaField) | `
'Hello China'
` |
##### Media Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `` | Embedded image (Image) | `` |
| `` | Vector graphic (PdfTemplate) | `${svg}` or `&{svg}` |
##### Special Elements
| Element | Description | Example Code |
|---------|-------------|--------------|
| `` | Reusable template content | `&html` |
| `` | Tree-structured data | `${tree}` or `tree` |
| `${variable}` | Data binding placeholder | `
Name: ${name}
` |
| `` | Multi-line text input field (TextAreaField) | `'Multi-line text'
` |
#### 📋 Complete Property Table (Including Example Code)
| Property | Example Value | Description | Example Code |
|----------|---------------|-------------|--------------|
| **Margin Properties** | | | |
| `marginLeft` | `"1px"` | Left margin value | `
Content` |
| `marginRight` | `"500px"` | Right margin value | `Content` |
| `marginTop` | `"500px"` | Top margin value | `Content` |
| `marginBottom` | `"500px"` | Bottom margin value | `Content` |
| `commonMargin` | `"100px"` | Uniform margin for all sides | `Content` |
| `margins` | `"'20px 30px 40px 50px'"` | Top, right, bottom, left margins (clockwise) | `Content` |
| **Padding Properties** | | | |
| `paddingLeft` | `"50px"` | Left padding value | `Content` |
| `paddingRight` | `"50px"` | Right padding value | `Content` |
| `paddingTop` | `"50px"` | Top padding value | `Content` |
| `paddingBottom` | `"50px"` | Bottom padding value | `Content` |
| `commonPadding` | `"50px"` | Uniform padding for all sides | `Content` |
| `paddings` | `"50px 50px 60px 70px"` | Top, right, bottom, left padding (clockwise) | `Content` |
| **Alignment & Layout Properties** | | | |
| `verticalAlignment` | `"top"` | Vertical alignment (top/middle/bottom) | `Content` |
| `spacingRatio` | `"30"` | Spacing ratio between elements | `Content` |
| `keepTogether` | `"true"` | Whether to keep elements together | `Content` |
| `keepWithNext` | `"true"` | Whether to keep with the next element | `Content` |
| **Dimension Properties** | | | |
| `width` | `"300px"` | Element width | `Content` |
| `height` | `"300px"` | Element height | `Content` |
| `maxHeight` | `"300px"` | Maximum element height | `Content` |
| `minHeight` | `"300px"` | Minimum element height | `Content` |
| `minWidth` | `"300px"` | Minimum element width | `Content` |
| `maxWidth` | `"300px"` | Maximum element width | `Content` |
| **Other Properties** | | | |
| `angleInRadians` | `"30"` | Rotation angle (in radians) | `Content` |
#### 📐 Dimension Properties Table (Including Example Code)
| Property | Example Value | Description | Example Code |
|----------|---------------|-------------|--------------|
| `width` | `"300px"` | Element width | `
Content` |
| `height` | `"300px"` | Element height | `Content` |
| `maxHeight` | `"300px"` | Maximum element height | `Content` |
| `minHeight` | `"300px"` | Minimum element height | `Content` |
| `minWidth` | `"300px"` | Minimum element width | `Content` |
| `maxWidth` | `"300px"` | Maximum element width | `Content` |
#### Property Styles
## 🎨 Property Styles Table (Including Example Code)
| Property | Example Value | Description | Example Code |
|----------|---------------|-------------|--------------|
| **Position & Layout** | | | |
| `relativePosition` | `"30px 30px 30px 30px"` | Relative position value (left, top, right, bottom) | `
Content` |
| **Font Properties** | | | |
| `font` | `"HELVETICA"` | Font type, refer to JFontEnum | `Text` |
| `fontFamilyNames` | `"Helvetica"` | Font family names (comma-separated) | `Text
` |
| `fontColor` | `"red"` | Font color, refer to JColorEnums class | `Red text` |
| `fontSize` | `"34"` | Font size | `Large text
` |
| `fontKerning` | `"yes"` | Font kerning setting | `Text with adjusted kerning
` |
| `fontScript` | `"common"` | Font script type | `Text
` |
| **Text Styles** | | | |
| `textAlignment` | `"left"` | Text alignment, refer to JTextAlignment | `Left-aligned text` |
| `characterSpacing` | `"30"` | Character spacing | `Text
` |
| `wordSpacing` | `"30"` | Word spacing | `Text
` |
| `splitCharacters` | `"24"` | Character spacing (same as characterSpacing) | `Text
` |
| `textRenderingMode` | `"24"` | Text rendering mode | `Text
` |
| `baseDirection` | `"no_bidi"` | Text base direction | `Text
` |
| **Text Decoration** | | | |
| `bold` | `"true"` | Whether text is bold | `Bold text` |
| `italic` | `"true"` | Whether text is italic | `Italic text` |
| `lineThrough` | `"true"` | Whether text has strikethrough | `Strikethrough text` |
| `underline` | `"true"` | Whether text has underline | `Underlined text` |
| **Background & Border** | | | |
| `backgroundColor` | `"red"` | Background color, refer to JColorEnums class | `Content` |
| `backgroundImage` | `"D:/pdf/image.png"` | Background image path | `Content` |
| `border` | `"solid 32px red"` | Border style (type, width, color) | `Content` |
| `borderTop` | `"solid 32px red"` | Top border style | `Content` |
| `borderRight` | `"solid 32px red"` | Right border style | `Content` |
| `borderLeft` | `"solid 32px red"` | Left border style | `Content` |
| `borderBottom` | `"solid 32px red"` | Bottom border style | `Content` |
| `borderRadius` | `"32px 24px"` | Border radius value | `Content` |
| `borderBottomLeftRadius` | `"32px 24px"` | Bottom-left border radius | `Content` |
| `borderBottomRightRadius` | `"32px 24px"` | Bottom-right border radius | `Content` |
| `borderTopRightRadius` | `"32px 24px"` | Top-right border radius | `Content` |
| `borderTopLeftRadius` | `"32px 24px"` | Top-left border radius | `Content` |
| **Effects & Stroke** | | | |
| `opacity` | `"0.5"` | Element opacity | `Semi-transparent content` |
| `strokeColor` | `"red"` | Stroke color | `Content` |
| `strokeWidth` | `"24"` | Stroke width | `Content` |
| **Anchor & Target** | | | |
| `destination` | `"hello"` | Element target/anchor name | `Content` |
# 📊 Chart Types
JQuickPDF supports multiple chart types, which can be configured via Java code and embedded into PDFs:
## 📈 How to use
### 📉 1.Native way
```string
# Pass SVG XML String to Variable
#1. Define Java Code
JContext params = new JContext();
String svg = "";
params.put("svg", svg);
JReader fileReader = new JReSourceFileReader("sample/svg1.txt");
JAdaptor context = new JAdaptor(fileReader);
JQuickPdfXExecutor executor = new JQuickPdfXExecutor(params);
executor.execute(context.getRuleContent());
#2. Define Template Code
${svg}
```
### 🍩 2.Java implements
```string
# Pass JOption of Related Graphics to JPdfConfig for Rendering
#1. Define Java Code
JGraphContainer graphContainer = new JGraphContainer();
JOption option = new JOption();
graphContainer.setOption(option);
graphContainer.setType(JChartType.K);
JGraphConfig graphConfig = new JGraphConfig();
graphConfig.put("svg", graphContainer);
JPdfConfig config = new JPdfConfig();
config.setGraphConfig(graphConfig);
JReader fileReader = new JReSourceFileReader("sample/svg2.txt");
JAdaptor context = new JAdaptor(fileReader);
JQuickPdfXExecutor executor = new JQuickPdfXExecutor(config);
#2. Define Template Code
&{svg}
```
## 📋相关图形的JOption
```string
// ============================================================================
# 1.柱状图 BAR chart
// ============================================================================
```
柱状图数据
// 1. 创建图表配置
JOption option = new JOption();
option.title().text("销售数据")
.subtext("2023年度");
option.tooltip().trigger(JTrigger.axis);
// 2. 配置坐标轴
JCategoryAxis xAxis = new JCategoryAxis();
xAxis.data("衬衫", "羊毛衫", "雪纺衫",
"裤子", "高跟鞋", "袜子");
option.xAxis(xAxis);
option.yAxis(new JValueAxis());
// 3. 配置数据系列
JBar bar = new JBar();
bar.name("销量").data(5, 20, 36, 10, 10, 20);
option.series(bar);
柱状图数据
```string
// ============================================================================
# 箱线图 BOXPLOT chart
// ============================================================================
```
箱线图数据
// 1. 创建图表配置
JOption option = new JOption();
option.title().text("销售数据分布");
option.xAxis(new JCategoryAxis().data("一季度",
"二季度", "三季度", "四季度"));
option.series(new JBoxplot().data(
new Object[]{10, 15, 20, 25, 30},
new Object[]{12, 18, 22, 28, 35},
new Object[]{8, 14, 19, 26, 32},
new Object[]{11, 16, 21, 27, 33}
));
箱线图数据
```string
// ============================================================================
# HEATMAP 热力图 chart
// ============================================================================
```
热力图数据
// 1. 创建图表配置
JOption option = new JOption();
option.title().text("销售数据分布");
option.xAxis(new JCategoryAxis().data("一季度",
"二季度", "三季度", "四季度"));
option.series(new JBoxplot().data(
new Object[]{10, 15, 20, 25, 30},
new Object[]{12, 18, 22, 28, 35},
new Object[]{8, 14, 19, 26, 32},
new Object[]{11, 16, 21, 27, 33}
));
JOption option = new JOption();
option.title("2023年月度温度分布热力图");
option.xAxis(new JCategoryAxis()
.data("1月", "2月", "3月", "4月", "5月", "6月",
"7月", "8月", "9月", "10月", "11月", "12月"));
option.yAxis(new JCategoryAxis()
.data("凌晨(0-6)", "早晨(6-9)", "上午(9-12)",
"中午(12-14)", "下午(14-18)", "晚上(18-24)"));
JHeatmap heatmap = new JHeatmap();
heatmap.data(
new Object[]{0, 0, -5.2}, new Object[]{0, 1, -3.8}
, new Object[]{0, 2, 1.5},
new Object[]{0, 3, 4.2}, new Object[]{0, 4, 2.8},
new Object[]{0, 5, -2.1},
new Object[]{1, 0, -3.5}, new Object[]{1, 1, -1.2}
, new Object[]{1, 2, 3.0},
new Object[]{1, 3, 6.5}, new Object[]{1, 4, 4.2},
new Object[]{1, 5, 0.5},
new Object[]{2, 0, 0.8}, new Object[]{2, 1, 3.5},
new Object[]{2, 2, 8.2},
new Object[]{2, 3, 12.0}, new Object[]{2, 4, 9.5},
new Object[]{2, 5, 4.2},
new Object[]{3, 0, 5.2}, new Object[]{3, 1, 8.0},
new Object[]{3, 2, 12.5},
new Object[]{3, 3, 16.8}, new Object[]{3, 4, 14.2},
new Object[]{3, 5, 9.5},
new Object[]{4, 0, 10.5}, new Object[]{4, 1, 13.2},
new Object[]{4, 2, 17.8},
new Object[]{4, 3, 21.5}, new Object[]{4, 4, 19.0},
new Object[]{4, 5, 14.8},
new Object[]{5, 0, 15.2}, new Object[]{5, 1, 18.5},
new Object[]{5, 2, 22.0},
new Object[]{5, 3, 26.5}, new Object[]{5, 4, 24.2},
new Object[]{5, 5, 19.8},
new Object[]{6, 0, 18.5}, new Object[]{6, 1, 22.0},
new Object[]{6, 2, 26.5},
new Object[]{6, 3, 30.2}, new Object[]{6, 4, 28.5},
new Object[]{6, 5, 23.8},
new Object[]{7, 0, 17.8}, new Object[]{7, 1, 21.5},
new Object[]{7, 2, 25.2},
new Object[]{7, 3, 29.0}, new Object[]{7, 4, 27.5},
new Object[]{7, 5, 22.8},
new Object[]{8, 0, 13.5}, new Object[]{8, 1, 16.2},
new Object[]{8, 2, 20.0},
new Object[]{8, 3, 24.5}, new Object[]{8, 4, 22.0},
new Object[]{8, 5, 17.5},
new Object[]{9, 0, 8.2}, new Object[]{9, 1, 11.5},
new Object[]{9, 2, 15.0},
new Object[]{9, 3, 18.8}, new Object[]{9, 4, 16.5},
new Object[]{9, 5, 12.0},
new Object[]{10, 0, 2.5}, new Object[]{10, 1, 5.0},
new Object[]{10, 2, 9.2},
new Object[]{10, 3, 12.5}, new Object[]{10, 4, 10.0},
new Object[]{10, 5, 5.5},
new Object[]{11, 0, -2.8}, new Object[]{11, 1, -0.5},
new Object[]{11, 2, 3.5},
new Object[]{11, 3, 6.8}, new Object[]{11, 4, 4.2},
new Object[]{11, 5, 0.0}
);
option.series(heatmap);
热力图数据
```string
// ============================================================================
# K线图(蜡烛图) K chart
// ============================================================================
```
K线图(蜡烛图)
JOption option = new JOption();
option.title().text("股票K线图(含数据)");
option.tooltip().trigger(JTrigger.axis);
JCategoryAxis xAxis = new JCategoryAxis();
xAxis.data("01/01", "01/02", "01/03", "01/04",
"01/05","01/06", "01/07", "01/08", "01/09",
"01/10");
option.xAxis(xAxis);
option.yAxis(new JValueAxis());
JCandlestick candlestick = new JCandlestick();
candlestick.name("股价")
.data(
new Object[]{105.2, 108.5, 104.8, 109.1},
new Object[]{108.6, 107.8, 106.5, 109.5},
new Object[]{107.9, 105.3, 104.2, 108.0},
new Object[]{105.4, 106.1, 104.5, 107.2},
new Object[]{106.2, 104.8, 103.0, 107.5},
new Object[]{104.9, 107.3, 104.0, 108.2},
new Object[]{107.4, 109.1, 106.5, 110.2},
new Object[]{109.2, 108.8, 107.0, 110.5},
new Object[]{108.9, 110.3, 108.2, 111.0},
new Object[]{110.4, 112.1, 109.5, 112.8}
);
option.series(candlestick);
K线图(蜡烛图)
```string
// ============================================================================
# 折线图 Line chart
// ============================================================================
```
折线图(Line chart)
JOption option = new JOption();
option.title().text("销售数据折线图");
option.tooltip().trigger(JTrigger.axis);
JCategoryAxis xAxis = new JCategoryAxis();
xAxis.data("1月", "2月", "3月", "4月",
"5月", "6月", "7月");
option.xAxis(xAxis);
option.yAxis(new JValueAxis());
JLine line = new JLine();
line.name("销售额").data(120, 132, 101,
134, 90, 230, 210);
option.series(line);
折线图
```string
// ============================================================================
# 饼图 PIE chart
// ============================================================================
```
饼图(PIE chart)
JOption option = new JOption();
option.title().text("销售占比").subtext("2023年度");
option.tooltip().trigger(JTrigger.item);
JPie pie = new JPie("销售占比");
pie.data(
new JData().name("衬衫").value(35),
new JData().name("羊毛衫").value(20),
new JData().name("雪纺衫").value(15),
new JData().name("裤子").value(18),
new JData().name("高跟鞋").value(8),
new JData().name("袜子").value(4)
);
option.series(pie);
饼图
```string
// ============================================================================
# 雷达图 RADAR chart
// ============================================================================
```
雷达图(RADAR chart)
// 创建图表选项
JOption option = new JOption();
option.title().text("雷达图示例")
.subtext("预算 vs 开销对比")
.left("center")
.textStyle(new JTextStyle().color("#333"));
// 设置提示框
option.tooltip().trigger(JTrigger.item);
// 设置雷达图指标
JRadar radar = new JRadar();
radar.indicator(
new JRadar.Indicator().name("销售")
.max(6500),
new JRadar.Indicator().name("管理")
.max(16000),
new JRadar.Indicator().name("信息技术")
.max(30000),
new JRadar.Indicator().name("客服")
.max(38000),
new JRadar.Indicator().name("研发")
.max(52000),
new JRadar.Indicator().name("市场")
.max(25000)
);
option.radar(radar);
// 添加雷达图系列数据
JRadarSeries budgetSeries = new JRadarSeries();
budgetSeries.name("预算").type(JSeriesType.radar)
.data(4300, 10000, 28000, 35000, 50000, 19000);
JRadarSeries actualSeries = new JRadarSeries();
actualSeries.name("实际开销")
.type(JSeriesType.radar)
.data(5000, 14000, 28000, 31000, 42000, 21000);
option.series(budgetSeries, actualSeries);
雷达图
```string
// ============================================================================
# 关系图 RELATION chart
// ============================================================================
```
关系图(RELATION chart)
JGsonOption option = new JGsonOption();
option.title("Relationship Chart Test");
// 创建图系列
JGraph graph = new JGraph();
graph.name("关系图");
graph.layout(JLayout.force); // 使用力导向布局
graph.force().repulsion(100); // 设置排斥力
graph.draggable(true); // 节点可拖动
// 添加节点 - 修正了ID问题
List nodes = new ArrayList<>();
nodes.add(new JNode("1", "Node A")
.symbolSize(30).category(0));//id 1
nodes.add(new JNode("2", "Node B")
.symbolSize(25).category(1));
nodes.add(new JNode("3", "Node C")
.symbolSize(20).category(2));
nodes.add(new JNode("4", "Node D")
.symbolSize(15).category(0));
nodes.add(new JNode("5", "Node E")
.symbolSize(35).category(1));
nodes.add(new JNode("6", "Node F")
.symbolSize(20).category(3));
nodes.add(new JNode("7", "Node G")
.symbolSize(25).category(2));
nodes.add(new JNode("8", "Node H")
.symbolSize(15).category(4));
nodes.add(new JNode("9", "Node I")
.symbolSize(30).category(3));
nodes.add(new JNode("10", "Node J")
.symbolSize(20).category(0));
graph.setData(nodes);
// 添加连接
List links = new ArrayList<>();
links.add(new JLink("1", "2"));
links.add(new JLink("1", "3"));
links.add(new JLink("2", "4"));
links.add(new JLink("3", "5"));
links.add(new JLink("4", "6"));
links.add(new JLink("5", "7"));
links.add(new JLink("6", "8"));
links.add(new JLink("7", "9"));
links.add(new JLink("8", "10"));
links.add(new JLink("9", "1"));
links.add(new JLink("10", "2"));
links.add(new JLink("3", "6"));
links.add(new JLink("4", "7"));
links.add(new JLink("5", "8"));
graph.setLinks(links);
// 添加类别
List categories =
new ArrayList<>();
categories.add(new JCategory()
.name("Category 1"));
categories.add(new JCategory()
.name("Category 2"));
categories.add(new JCategory()
.name("Category 3"));
categories.add(new JCategory()
.name("Category 4"));
categories.add(new JCategory()
.name("Category 5"));
graph.setCategories(categories);
option.series(graph);
option.legend().data("Category 1",
"Category 2", "Category 3", "Category 4",
"Category 5");
关系图
```string
// ============================================================================
# 散点图 SCATTER chart
// ============================================================================
```
散点图(SCATTER chart)
JData[] data = new JData[]{
new JData().value(new Double[]{10.0, 8.04}),
new JData().value(new Double[]{8.07, 6.95}),
new JData().value(new Double[]{13.0, 7.58}),
new JData().value(new Double[]{9.05, 8.81}),
new JData().value(new Double[]{11.0, 8.33}),
new JData().value(new Double[]{14.0, 7.66}),
new JData().value(new Double[]{13.4, 6.81}),
new JData().value(new Double[]{10.0, 6.33}),
new JData().value(new Double[]{14.0, 8.96}),
new JData().value(new Double[]{12.5, 6.82}),
new JData().value(new Double[]{9.15, 7.2}),
new JData().value(new Double[]{11.5, 7.2}),
new JData().value(new Double[]{3.03, 4.23}),
new JData().value(new Double[]{12.2, 7.83}),
new JData().value(new Double[]{2.02, 4.47}),
new JData().value(new Double[]{1.05, 3.33}),
new JData().value(new Double[]{4.05, 4.96}),
new JData().value(new Double[]{6.03, 7.24}),
new JData().value(new Double[]{12.0, 6.26}),
new JData().value(new Double[]{12.0, 8.84}),
new JData().value(new Double[]{7.08, 5.82}),
new JData().value(new Double[]{5.02, 5.68})
};
JOption option = new JOption();
option.title().text("散点图示例");
option.tooltip().trigger(JTrigger.axis);
option.xAxis(new JValueAxis().scale(true));
option.yAxis(new JValueAxis().scale(true));
JScatter scatter = new JScatter();
scatter.symbolSize(20).data(data);
option.series(scatter);
散点图
```string
// ============================================================================
# 旭日图(1.5.1) SUNBURST chart
// ============================================================================
```
旭日图(SUNBURST chart)
JOption option = new JOption();
// 设置标题
JTitle title = new JTitle();
title.setText("咖啡风味分析");
option.setTitle(title);
JSunburstData root =
new JSunburstData("总数据", 1.0);
JSunburstData main1 =
new JSunburstData("电子产品", 0.4);
JSunburstData main2 =
new JSunburstData("服装", 0.3);
JSunburstData main3 =
new JSunburstData("食品", 0.3);
// 第二层:子分类
JSunburstData main1Sub1 =
new JSunburstData("手机", 0.6);
JSunburstData main1Sub2 =
new JSunburstData("电脑", 0.4);
JSunburstData main2Sub1 =
new JSunburstData("男装", 0.5);
JSunburstData main2Sub2 =
new JSunburstData("女装", 0.5);
JSunburstData main3Sub1 =
new JSunburstData("生鲜", 0.4);
JSunburstData main3Sub2 =
new JSunburstData("零食", 0.6);
// 第三层:孙分类
main1Sub1.addChild(new
JSunburstData("智能手机", 0.7));
main1Sub1.addChild(new
JSunburstData("功能手机", 0.3));
main1Sub2.addChild(new
JSunburstData("笔记本电脑", 0.6));
main1Sub2.addChild(new
JSunburstData("台式电脑", 0.4));
main2Sub1.addChild(new
JSunburstData("衬衫", 0.4));
main2Sub1.addChild(new
JSunburstData("裤子", 0.6));
main3Sub2.addChild(new
JSunburstData("膨化食品", 0.5));
main3Sub2.addChild(new
JSunburstData("糖果", 0.5));
main1.addChild(main1Sub1);
main1.addChild(main1Sub2);
main2.addChild(main2Sub1);
main2.addChild(main2Sub2);
main3.addChild(main3Sub1);
main3.addChild(main3Sub2);
root.addChild(main1);
root.addChild(main2);
root.addChild(main3);
option.setSunburstData(root);
旭日图
```string
// ============================================================================
# 矩形树图(1.5.1) Treemap chart
// ============================================================================
```
矩形树图(Treemap chart)
JTreeMapNode root = createTestData();
TreeMapOption treemapOption = new TreeMapOption();
treemapOption.setRoot(root);
treemapOption.setDepartmentColors(DEPARTMENT_COLORS);
treemapOption.setCategoryColors(CATEGORY_COLORS);
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("开发", "技术部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("项目", "技术部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("服务", "技术部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("会计", "财务部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("预算", "财务部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("税务", "财务部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("审计", "财务部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("销售", "销售部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("区域", "销售部"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("招聘", "人力资源"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("培训", "人力资源"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("薪酬", "人力资源"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("员工", "人力资源"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("营销", "市场营销"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("品牌", "市场营销"));
treemapOption.getDepartmentRules()
.add(new TreeMapMapping("公关", "市场营销"));
JOption option = new JOption();
option.setTreemapOption(treemapOption);
option.title("公司业务分布矩形树图(JTreemapRenderer)");
矩形树图
```string
// ============================================================================
# 气泡图(1.5.1) Bubble chart
// ============================================================================
```
气泡图(Bubble chart)
JTitle title = new JTitle();
title.setText("空气质量指数 (AQI) 监测气泡图");
title.setSubtext("图表说明:本气泡图展示了空气质量指数(AQI)的
时间变化趋势。X轴表示日期,Y轴表示AQI数值,气泡大小反映PM2.5浓度,
气泡颜色表示AQI等级。");
JOption option = new JOption()
.title(title)
.legend("优", "良", "轻度污染", "中度污染", "重度污染")
.xAxis(new CategoryAxis().name("日期"))
.yAxis(new ValueAxis().name("AQI数值"));
ScatterSeries series = new ScatterSeries("空气质量监测");
List> data = new ArrayList<>();
Random random = new Random(42); // 固定种子以便重现
String[] dates = {"01-01", "01-02", "01-03", "01-04",
"01-05", "01-06", "01-07", "01-08", "01-09", "01-10",
"01-11", "01-12", "01-13", "01-14", "01-15"};
for (int i = 0; i < dates.length; i++) {
int aqi = 20 + random.nextInt(180); // AQI 20-200
double pm25 = 10 + random.nextDouble() * 150; // PM2.5 10-160
String category;
if (aqi <= 50) category = "优";
else if (aqi <= 100) category = "良";
else if (aqi <= 150) category = "轻度污染";
else if (aqi <= 200) category = "中度污染";
else category = "重度污染";
String name = String.format("日期:%s, AQI:%d,
PM2.5:%.1f", dates[i], aqi, pm25);
Map dataPoint = new HashMap<>();
dataPoint.put("x", dates[i]);
dataPoint.put("y", aqi);
dataPoint.put("size", pm25);
dataPoint.put("category", category);
dataPoint.put("name", name);
data.add(dataPoint);
}
series.data(data.toArray());
option.series(series);
气泡图
```string
// ============================================================================
# 日历(1.5.3) Lunar chart
// ============================================================================
```
日历贡献图(Calendar chart)
Map data = new HashMap<>();
LocalDate startDate = LocalDate.of(2024, 1, 1);
for (int i = 0; i < 365; i++) {
LocalDate date = startDate.plusDays(i);
int value = (int) (Math.random() * 15);
data.put(date, value);
}
JOption option = new JOption();
JCalendarOption calendarOption = new JCalendarOption(
"2024年活动日历", "类似GitHub贡献图", 2024, data,
new Color(235, 237, 240),
new Color(32, 125, 222),
new Color(232, 235, 240),
new Color(84, 85, 90),
20,
80
);
option.setJCalendarOption(calendarOption);
日历贡献图
```string
// ============================================================================
# 日历(1.5.3) Lunar chart
// ============================================================================
```
日历(Lunar chart)
LunarCalendarOption.CalendarDataConfig dataConfig =
new LunarCalendarOption.CalendarDataConfig()
.setDayDataList(createDefaultDayData())
.setSpecialDays(createDefaultSpecialDays())
.setWeekDays(new String[]{"Mon", "Tue",
"Wed", "Thu", "Fri", "Sat", "Sun"})
.setRows(5)
.setCols(7);
LunarCalendarOption.ColorConfig colorConfig =
new LunarCalendarOption.ColorConfig()
.setBackgroundColor(null)
.setSpecialDayColor(new Color(0, 100, 0));
JTitle title = new JTitle();
title.setText("2024年3月日历");
日历
```string
// ============================================================================
# 漏斗图(1.5.3) Funnel chart
// ============================================================================
```
日历(Lunar chart)
JFunnelOption option = JFunnelOption
.createDefaultFunnel();
JFunnelOption customOption = option
.title(new Title().text("销售漏斗")
.subtext("2024年数据"))
.funnel(new Funnel()
.width(600)
.topY(80)
.bottomY(200)
.gap(2)
.borderColor(Color.GRAY)
)
.series(Collections.singletonList(
new Series()
.name("sales")
.type("funnel")
.data(Arrays.asList(
new DataItem("展现", 10000),
new DataItem("点击", 5000),
new DataItem("咨询", 2000),
new DataItem("订单", 500)
))
))
.colors(
new Color(12, 168, 223),
new Color(255, 153, 77),
new Color(80, 112, 221),
new Color(182, 214, 52)
);
JFunnelChartRenderer renderer = new JFunnelChartRenderer();
JOption jOption = new JOption();
jOption.setFunnelOption(customOption);
漏斗图
```string
// ============================================================================
# 相关系数矩阵(1.5.3) CorrectionMatrix chart
// ============================================================================
```
相关系数矩阵(CorrectionMatrix chart)
double[][] correlationData = {
{1.00, -0.20, 0.03, -0.62, -0.54, -0.21, 0.63, 0.30},
{-0.20, 1.00, 0.36, -0.61, -0.26, 0.05, 0.16, 0.41},
{0.03, 0.36, 1.00, -0.74, -0.94, 0.71, -0.90, -0.66},
{-0.62, -0.61, -0.74, 1.00, 0.37, -0.66, 0.54, -0.66},
{-0.54, -0.26, -0.94, 0.37, 1.00, -0.05, -0.46, 0.71},
{-0.21, 0.05, 0.71, -0.66, -0.05, 1.00, -0.84, -0.40},
{0.63, 0.16, -0.90, 0.54, -0.46, -0.84, 1.00, -0.55},
{0.30, 0.41, -0.66, -0.66, 0.71, -0.40, -0.55, 1.00}
};
String[] dimensions = {"销售额", "广告费", "促销费",
"竞品价", "季节指数", "GDP", "人口", "天气"};
JCorrelationMatrixOption option = JCorrelationMatrixOption.builder()
.title("销售因素相关系数矩阵", "各因素之间的相关性分析")
.dataset(correlationData)
.build();
option.dataset().dimensions(dimensions);
JOption jOption = new JOption();
jOption.setCorrelationMatrixOption(option);
相关系数矩阵
```string
// ============================================================================
# 甘特图(1.5.3) Gantt chart
// ============================================================================
```
甘特图(Gantt chart)
JGanttOption option = new JGanttOption();
option.setTitle(
new JGanttOption.Title(
"Gantt of Airport Flight", "航班调度甘特图")
);
option.setFlightData(
Arrays.asList(
new JGanttOption.FlightData
("Y3683", "681", "X", 21, 0, 360, 0, 0.7),
new JGanttOption.FlightData
("EKXAD", "682I", "W", 21, 0, 360, 1, 0.7),
new JGanttOption.FlightData
("Y4682", "682O", "W", 21, 0, 360, 2, 0.7),
new JGanttOption.FlightData
("Y4393", "682", "X", 21, 0, 360, 3, 0.7),
new JGanttOption.FlightData
("Y2238", "683", "X", 21, 0, 360, 4, 0.7),
new JGanttOption.FlightData
("Y8192", "684", "W", 21, 0, 240, 5, 0.7),
new JGanttOption.FlightData
("Y3887", "685", "X", 21, 0, 360, 6, 0.7),
new JGanttOption.FlightData
("Y3086", "690", "X", 21, 0, 360, 7, 0.7),
new JGanttOption.FlightData
("Y7421", "691", "X", 21, 0, 120, 8, 0.7),
new JGanttOption.FlightData
("Y4619", "692", "X", 21, 0, 300, 9, 0.7)
));
option.setChartStyle(new JGanttOption.ChartStyle(
Color.WHITE,
new Color(146, 154, 186),
new Color(54, 140, 108),
new Color(80, 112, 221),
new Color(221, 179, 11),
new Font("微软雅黑", Font.BOLD, 18),
new Font("微软雅黑", Font.PLAIN, 12),
872,
282
));
option.setTimeRange(
new JGanttOption.TimeRange(21, 3,
new String[]{"21:00", "22:00", "23:00", "00:00",
"01:00", "02:00", "03:00"}));
JChartRenderer renderer = new JGanttChartRenderer();
JOption jOption = new JOption();
jOption.setGanttOption(option);
甘特图
```string
// ============================================================================
# 甘特图(1.5.3) Gantt chart
// ============================================================================
```
仪表盘(Gauge chart)
GuageConfig scoreConfig = GuageConfig.builder()
.score(75) // 设置分数为75
.pointerColor(new Color(220, 80, 80))
// 红色指针
.backgroundColor(new Color(240, 240, 245))
// 浅灰色背景
.title("PERFORMANCE")
.build();
JGuageOption option = JGuageOption.builder()
.scoreMeter(scoreConfig).build();
JGuageRenderer renderer = new JGuageRenderer();
JOption option1 = new JOption();
option1.setGuageOption(option);
仪表盘
```string
// ============================================================================
# 词云(1.5.3) WordsCloud chart
// ============================================================================
```
词云(WordsCloud chart)
JOption option = new JOption()
.title(new JTitle().text("热门编程语言"))
.series(Arrays.asList(
new JWordCloudSeries("语言热度")
.data(Arrays.asList(
new JData("Java", 100),
new JData("Python", 85),
new JData("JavaScript", 75),
new JData("C++", 60),
new JData("Go", 50),
new JData("Rust", 45),
new JData("Kotlin", 40),
new JData("Swift", 35),
new JData("TypeScript", 30),
new JData("Scala", 25)
))
.minFontSize(20)
.maxFontSize(60)
.gridSize(10)
.rotationStep(15)
.rotationRange(90)
.textStyle(new JItemStyle().color(Color.BLUE))
));
词云
```string
// ============================================================================
# 地图 (1.5.4) GEO Json chart
// ============================================================================
```
地图(GEO Json chart)
JOption jOption = new JOption();
String geoJsonContent = readFile("d://sample//test.geojson");
地图
```string
// ============================================================================
# 组合图形<折线条形图> (1.5.5) LineBar chart
// ============================================================================
```
组合图形 (折线条形图 LineBar chart)
JOption jOption = new JOption();
List salesData = Arrays.asList(45.0, 38.0, 52.0,
48.0, 62.0, 58.0, 72.0, 78.0, 65.0, 70.0, 82.0, 88.0);
List profitData =Arrays.asList(12.0, 10.0, 15.0,
14.0, 18.0, 17.0, 22.0, 25.0, 20.0, 21.0, 26.0, 28.0);
List months =Arrays.asList("1月", "2月", "3月",
"4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月");
JComboLineBarChartData data = JComboLineBarChartData.builder()
.width(1000) // 宽度1000像素
.height(600) // 高度600像素
.title("2024年度销售数据分析", "全年12个月数据趋势")
.barData(salesData)
.lineData(profitData)
.xAxisLabels(months)
.leftAxisTitle("销售额(万元)")
.rightAxisTitle("利润率(%)")
.barLegendText("月销售额(万元)")
.lineLegendText("利润率趋势")
.footerText("数据来源:2024年度财务报告")
.barColor(new Color(52, 152, 219)) // 蓝色
.lineColor(new Color(231, 76, 60)) // 红色
.showBarLabels(true)
.showLineLabels(true)
.autoCalculateMax(true)
.build();
jOption.setData(data);
折线条形图
```string
// ============================================================================
# 多重折线图(1.5.6) Mutiple Line Chart
// ============================================================================
```
多重折线图(多重折线图 Mutiple Line Chart)
List months = Arrays.asList("1月", "2月", "3月",
"4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月");
List productA = Arrays.asList(120.0, 135.0, 148.0,
162.0, 175.0, 190.0, 205.0, 218.0, 230.0, 245.0, 258.0, 270.0);
List productB = Arrays.asList(95.0, 108.0, 112.0,
130.0, 125.0, 145.0, 150.0, 168.0, 172.0, 185.0, 190.0, 200.0);
List productC = Arrays.asList(80.0, 82.0, 85.0, 88.0,
90.0, 92.0, 95.0, 98.0, 100.0, 102.0, 105.0, 108.0);
List productD = Arrays.asList(45.0, 58.0, 72.0, 89.0,
105.0, 128.0, 150.0, 175.0, 198.0, 225.0, 248.0, 275.0);
JMultiLineChartData chartData = new JMultiLineChartData();
chartData.setXAxisLabels(months);
chartData.setWidth(900);
chartData.setHeight(600);
chartData.setTitleText("2024年度产品销售趋势分析");
chartData.setSubtitleText("各产品线月度销售额对比(单位:万元)");
chartData.setYAxisTitle("销售额(万元)");
chartData.setFooterText("数据来源:销售系统报表 | 统计时间:
2024年1月-12月");
chartData.setGridCount(6);
chartData.setShowDataLabels(false);
chartData.setShowInnerPoint(true);
chartData.setPointRadius(5);
chartData.setInnerPointRadius(2);
chartData.setChartAreaColor(new Color(248, 249, 250));
chartData.setAxisColor(Color.BLACK);
chartData.setGridColor(new Color(220, 220, 220));
chartData.setTextColor(Color.BLACK);
chartData.setFooterColor(new Color(128, 128, 128));
chartData.setValueWithPercent(false);
chartData.setAutoCalculateMax(true);
chartData.setRotateXAxisLabels(false);
JMultiLineChartData.LineData lineA = new JMultiLineChartData
.LineData();
lineA.setName("产品A");
lineA.setLegendText("产品A - 高端系列");
lineA.setValues(productA);
lineA.setLineColor(new Color(66, 133, 244));
lineA.setLineWidth(2.5f);
JMultiLineChartData.LineData lineB = new JMultiLineChartData
.LineData();
lineB.setName("产品B");
lineB.setLegendText("产品B - 中端系列");
lineB.setValues(productB);
lineB.setLineColor(new Color(234, 67, 53));
lineB.setLineWidth(2.5f);
JMultiLineChartData.LineData lineC = new JMultiLineChartData
.LineData();
lineC.setName("产品C");
lineC.setLegendText("产品C - 入门系列");
lineC.setValues(productC);
lineC.setLineColor(new Color(52, 168, 83));
lineC.setLineWidth(2.5f);
JMultiLineChartData.LineData lineD = new JMultiLineChartData
.LineData();
lineD.setName("产品D");
lineD.setLegendText("产品D - 创新系列");
lineD.setValues(productD);
lineD.setLineColor(new Color(251, 188, 5));
lineD.setLineWidth(2.5f);
chartData.setLineDataList(Arrays.asList(lineA, lineB, lineC, lineD));
chartData.updateMaxValues();
JOption option = new JOption();
JTitle title = new JTitle();
title.setText("2024年度产品销售趋势分析");
title.setSubtext("各产品线月度销售额对比");
option.setTitle(title);
option.setData(chartData);
多重折线图
```string
// ============================================================================
# 多重条形图(1.5.7) Mutiple Bar Chart
// ============================================================================
```
多重条形图(多重条形图 Mutiple Bar Chart)
JMultiBarChartData regionalData = new JMultiBarChartData();
regionalData.setTitleText("2024年上半年各区域业绩对比(万元)");
regionalData.setSubtitleText("华东、华南、华北、西部四区表现");
regionalData.setXAxisLabels(Arrays.asList("1月", "2月",
"3月", "4月", "5月", "6月"));
regionalData.setXAxisTitle("月份");
regionalData.setYAxisTitle("业绩(万元)");
// 华东区域
JMultiBarChartData.BarData eastChina = new JMultiBarChartData
.BarData();
eastChina.setLegendText("华东");
eastChina.setBarColor(JMultiBarChartRenderer.COLOR_A);
eastChina.setValues(Arrays.asList(120.5, 135.2, 148.0,
162.5, 175.3, 190.8));
// 华南区域
JMultiBarChartData.BarData southChina = new JMultiBarChartData
.BarData();
southChina.setLegendText("华南");
southChina.setBarColor(JMultiBarChartRenderer.COLOR_B);
southChina.setValues(Arrays.asList(98.3, 112.6, 128.4, 145.2,
158.7, 172.5));
// 华北区域
JMultiBarChartData.BarData northChina = new JMultiBarChartData
.BarData();
northChina.setLegendText("华北");
northChina.setBarColor(JMultiBarChartRenderer.COLOR_C);
northChina.setValues(Arrays.asList(85.6, 92.3, 105.8, 118.4,
132.6, 148.2));
// 西部区域
JMultiBarChartData.BarData westChina = new JMultiBarChartData
.BarData();
westChina.setLegendText("西部");
westChina.setBarColor(new Color(80, 180, 120));
westChina.setValues(Arrays.asList(52.4, 61.8, 73.5, 85.2,
96.8, 108.5));
regionalData.setBarDataList(Arrays.asList(eastChina, southChina,
northChina, westChina));
JOption option = new JOption();
option.setData(regionalData);
多重条形图
```string
// ============================================================================
# 区域堆积图(1.5.8) Area Chart
// ============================================================================
```
区域堆积图(区域堆积图 Area Chart)
java.util.List values =Arrays.asList(85.0, 120.0,
150.0, 210.0, 280.0, 350.0, 420.0, 400.0, 380.0, 450.0, 480.0, 520.0);
List labels = Arrays.asList("1月", "2月", "3月", "4月", "5月",
"6月", "7月", "8月", "9月", "10月", "11月", "12月");
JAreaChartData data = new JAreaChartData();
data.setWidth(800);
data.setHeight(500);
data.setTitle("2024年度销售趋势");
data.setSubtitle("数据来源:销售系统");
data.setXAxisTitle("月份");
data.setYAxisTitle("销售额(万元)");
data.setLegendText("销售额");
data.setShowDataLabels(true);
data.setSeriesList(Arrays.asList(new JSeriesData("销售额", values)));
data.setXAxisLabels(labels);
data.setTheme(JTheme.DEFAULT); // 默认主题
JOption option = new JOption();
option.setData(data);
堆叠区域图
```string
// ============================================================================
# 横向条形图(1.5.9) HorizontalBar Chart
// ============================================================================
```
横向条形图(横向条形图 HorizontalBar Chart)
JHorizontalBarChartData chartData = new JHorizontalBarChartData();
chartData.setTitleText("2024年度销售数据");
chartData.setSubtitleText("各产品线销售占比");
chartData.setXAxisTitle("销售额(万元)");
chartData.setYAxisTitle("产品类别");
chartData.setValueWithPercent(false);
chartData.setShowDataLabels(true);
chartData.addYAxisLabel("电子产品");
chartData.addYAxisLabel("服装服饰");
chartData.addYAxisLabel("家居用品");
chartData.addYAxisLabel("美妆个护");
chartData.addYAxisLabel("食品饮料");
java.util.List productAValues = Arrays
.asList(85.5, 62.3, 45.8, 71.2, 93.6);
java.util.List productBValues = Arrays
.asList(45.2, 78.9, 52.1, 38.5, 67.4);
chartData.addBarData(new JHorizontalBarChartData
.BarData("产品A", productAValues, JHorizontalBarChartData.COLOR_A));
chartData.addBarData(new JHorizontalBarChartData
.BarData("产品B", productBValues, JHorizontalBarChartData.COLOR_B));
JOption option = new JOption();
option.setData(chartData);
横向条形图
```string
// ============================================================================
# 多重横向条形图(1.5.10) MutipleHorizontalBar Chart
// ============================================================================
```
多重横向条形图(多重横向条形图 MutipleHorizontalBar Chart)
JHorizontalMultiBarChartData chartData =
new JHorizontalMultiBarChartData();
chartData.setTitleText("2024年度各产品销售数据");
chartData.setSubtitleText("单位:万元");
chartData.setXAxisTitle("销售额(万元)");
// chartData.setYAxisTitle("产品类别");
chartData.setValueWithPercent(false);
chartData.setShowDataLabels(true);
chartData.setLegendAtTop(true);
chartData.setGroupSpacingRatio(0.15);
chartData.setBarSpacingRatio(0.2);
chartData.addCategory("智能手机");
chartData.addCategory("笔记本电脑");
chartData.addCategory("平板电脑");
chartData.addCategory("智能手表");
chartData.addCategory("耳机音箱");
List productAValues = Arrays
.asList(125.5, 98.3, 65.8, 45.2, 78.6);
List productBValues = Arrays
.asList(88.2, 112.5, 72.1, 38.5, 55.3);
List productCValues = Arrays
.asList(45.6, 68.9, 52.4, 28.7, 42.1);
chartData.addSeries("品牌 A", productAValues,
new Color(52, 73, 94)); // 深灰蓝 #34495e
chartData.addSeries("品牌 B", productBValues,
new Color(41, 128, 185)); // 中蓝 #2980b9
chartData.addSeries("品牌 C", productCValues,
new Color(26, 188, 156)); // 薄荷绿 #1abc9c
JOption option = new JOption();
option.setData(chartData);
多重横向条形图
```string
// ============================================================================
# 双雷达图(1.5.11) DoubleRadar Chart
// ============================================================================
```
双雷达图(双雷达图 DoubleRadar Chart)
JDoubleRadarChartData chartData = new
JDoubleRadarChartData();
chartData.setWidth(1000);
chartData.setHeight(600);
chartData.setTitleText("多维度数据对比雷达图");
chartData.setSubtitleText("左右两组数据对比分析");
chartData.setLeftTitle("实验组数据");
chartData.setRightTitle("对照组数据");
List dimensions = Arrays.asList("维度A",
"维度B", "维度C", "维度D", "维度E");
chartData.setDimensions(dimensions);
JDoubleRadarChartData.RadarData leftRadar = new
JDoubleRadarChartData.RadarData();
List leftSeriesList = new ArrayList<>();
JDoubleRadarChartData.Series series1 = new JDoubleRadarChartData.Series();
series1.setName("节点1");
List values1 = Arrays.asList(85.0, 70.0, 65.0, 80.0, 75.0);
series1.setValues(values1);
series1.setColor(new Color(84, 112, 198)); // 蓝色
leftSeriesList.add(series1);
JDoubleRadarChartData.Series series2 = new JDoubleRadarChartData.Series();
series2.setName("节点2");
List values2 = Arrays.asList(70.0, 85.0, 80.0, 65.0, 70.0);
series2.setValues(values2);
series2.setColor(new Color(250, 200, 88)); // 黄色
leftSeriesList.add(series2);
leftRadar.setSeriesList(leftSeriesList);
chartData.setLeftRadar(leftRadar);
JDoubleRadarChartData.RadarData rightRadar = new J
DoubleRadarChartData.RadarData();
List rightSeriesList = new ArrayList<>();
JDoubleRadarChartData.Series series3 = new JDoubleRadarChartData.Series();
series3.setName("节点3");
List values3 = Arrays.asList(90.0, 85.0, 88.0, 92.0, 87.0);
series3.setValues(values3);
series3.setColor(new Color(238, 102, 102)); // 红色
rightSeriesList.add(series3);
JDoubleRadarChartData.Series series4 = new JDoubleRadarChartData.Series();
series4.setName("节点4");
List values4 = Arrays.asList(75.0, 80.0, 72.0, 78.0, 82.0);
series4.setValues(values4);
series4.setColor(new Color(80, 180, 150)); // 绿色
rightSeriesList.add(series4);
rightRadar.setSeriesList(rightSeriesList);
chartData.setRightRadar(rightRadar);
chartData.setGridLevels(4);
chartData.setFillAlpha(70);
chartData.setLineWidth(2.0f);
chartData.setShowDataPoints(true);
chartData.setLegendAtTop(false);
chartData.setShowLegendSide(true);
chartData.setFooterText("数据来源:示例数据");
双雷达图
### How to Generate a Credit Report Using JQuickPDF
#### Define a Template
```xml
'企业信用评级报告'
'报告编号: CR-2023-08975 | 评估日期: 2023年11月15日'
'评估机构: 四川省企业信用评估中心'
'四川省泡海椒科技有限公司'
'统一信用代码'
'91110108MA01XX1234'
'成立日期'
'2018年5月20日'
'注册资本'
'1000万元人民币'
'法定代表人'
'泡海椒'
'所属行业'
'软件和信息技术服务业'
'企业规模'
'中型(150-200人)'
&html
'历年财务数据(单位:万元)'
'财务指标'
'2020年'
'2021年'
'2022年'
'2023年'
'增长率'
'营业收入'
'8,560'
'12,340'
'18,920'
'25,680'
'+44.2%'
'净利润'
'1,240'
'2,150'
'3,890'
'5,420'
'+63.8%'
'总资产'
'15,800'
'22,450'
'31,200'
'42,800'
'+39.5%'
'净资产'
'9,200'
'13,800'
'19,500'
'26,400'
'+42.1%'
'毛利率'
'42.5%'
'45.8%'
'48.2%'
'51.6%'
'+9.1%'
'关键经营指标'
'营收增长率:连续三年保持40%以上增长,2023年达到25,680万元'
' 利润率提升:净利率从14.5%提升至21.1%,盈利能力显著增强'
' 研发投入:研发费用年均增长38.9%,占营收比例达13.3%'
' 人才结构:技术研发人员占比42%,硕士以上学历占35%'
' 客户质量:服务15家上市公司,客户续约率92%,大客户满意度4.8/5.0'
' 资产质量:资产负债率维持在38%左右,流动比率2.8,偿债能力良好'
'信用评级雷达图'
${svg}
'评级指标说明'
'财务状况(90分):'
'营收稳定增长'
'经营能力(95分):'
' 客户留存率高'
'偿债能力(85分):'
'负债率合理'
'发展潜力(92分):'
'研发投入增加'
'综合评价'
'四川省泡海椒科技有限公司作为国家级高新技术企业和专精特新"小巨人"企业,在云计算和大数据领域表现出色。'
'公司财务状况健康,经营能力突出,技术创新能力强,具备良好的发展潜力。信用评级为AAA级,展望稳定。'
'认证通过'
'本报告依据公开信息和专业评估模型生成,仅供参考 | 报告生成时间: 2025年09月06日'
'© 2023 企业信用评估中心 版权所有 | 认证编号: CE-2023-001'
```
#### 定义一个内嵌的html 组件(html 变量)
企业资质认证
AAA
信用等级
高新
高新技术企业
专精特新
小巨人企业
水电
双软认证企业
#### 定义一个雷达图背景svg(也可以使用java 加载方式)
```xml
偿债能力
盈利能力
运营能力
成长能力
现金流
信用历史
100
80
60
40
20
90
85
80
75
88
92
科技有限公司信用评级
综合信用评分: 85/100 | 评级: AA
```
#### pdf 渲染
```java
JPdfConfig config = new JPdfConfig();
JTemplateConfig templateConfig = config.getTemplateConfig();
templateConfig.put("html", html);
System.out.println(html);
config.setTemplateConfig(templateConfig);
JReader fileReader = new JReSourceFileReader("report.txt");
JAdaptor adaptor = new JAdaptor(fileReader);
JContext param = new JContext();
param.put("svg", svg);
JQuickPdfXExecutor executor = new JQuickPdfXExecutor(param, config);
executor.execute(adaptor.getRuleContent());
```

# **捐献 ☕**
感谢您使用这个开源项目!它完全免费并将持续维护,但开发者确实需要您的支持。
---
## **如何支持我们**
1. **请我喝杯咖啡**
果这个项目为您节省了时间或金钱,请考虑通过小额捐赠支持我。
2. **您的捐赠用途**
- 维持项目运行的服务器成本.
- 开发新功能以提供更多价值.
- 优化文档以提升用户体验.