Multi-dimensional KPI double radar (performance management) — generate this PDF with Java (DoubleRadar)
DoubleRadar2 页 A4 · 256 KB
Overlays this period and last period KPIs on one radar chart so rises and falls of each metric are directly comparable.

Output specs
- PDF pages
- 2
- Chart type
- DoubleRadar
- Template lines
- 88
- Source lines
- 104
Java source · JQuickBiz38KpiDoubleRadarTest.java
This is the complete test class that produced the PDF above — copy it and run as-is; see the quick-start section for the Maven dependency.
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) [2025-2099] Martin ([email protected])
*/
package com.github.paohaijiao.demo.biz;
import com.github.paohaijiao.JOption;
import com.github.paohaijiao.combol.JDoubleRadarChartData;
import com.github.paohaijiao.config.JPdfConfig;
import com.github.paohaijiao.demo.constant.JQuickConstant;
import com.github.paohaijiao.enums.JChartType;
import com.github.paohaijiao.executor.JQuickPdfFactory;
import com.github.paohaijiao.factory.JChartRendererFactory;
import org.junit.Test;
import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
/**
* 业务场景 Demo 38:多维度 KPI 双雷达对比(企业绩效管理)
*
* <p>业务场景:企业绩效管理部门从营收增长、成本控制、交付及时率、质量合格率、客户满意度五个维度,
* 对比本期(2024年)与去年同期(2023年)的 KPI 得分,用于年度绩效复盘。</p>
* <p>实际图表类型:{@link JChartType#DoubleRadar} 双雷达图,左侧为本期、右侧为去年同期,两个雷达并列展示。</p>
*
* <p>模板:{@code report/biz/38_kpi_double_radar.txt};图表以 SVG 文本形式绑定到模板的
* {@code ${svg}} 占位符,输出到 {@code D:\test\biz\38_kpi_double_radar.pdf}。</p>
*
* <p>图表尺寸说明:图表按 700pt 宽的横版比例设计;模板中 {@code <svg>} 只声明宽度、不声明高度,
* 宽度被页面自动收窄时高度会按原比例同步缩放,不会纵向拉伸变形。</p>
*
* @author Martin
* @version 1.0.0
*/
public class JQuickBiz38KpiDoubleRadarTest {
public static final String path = JQuickConstant.path;
@Test
public void biz38KpiDoubleRadar() throws IOException {
JDoubleRadarChartData chartData = new JDoubleRadarChartData();
chartData.setTitleText("多维度 KPI 双雷达对比");
chartData.setSubtitleText("本期(2024年)与去年同期(2023年)绩效得分对比");
chartData.setLeftTitle("本期 KPI(2024年)");
chartData.setRightTitle("去年同期(2023年)");
chartData.setDimensions(Arrays.asList("营收增长", "成本控制", "交付及时率", "质量合格率", "客户满意度"));
// 左侧雷达:本期各维度得分
JDoubleRadarChartData.RadarData leftRadar = new JDoubleRadarChartData.RadarData();
JDoubleRadarChartData.Series leftSeries = new JDoubleRadarChartData.Series();
leftSeries.setName("本期");
leftSeries.setValues(Arrays.asList(88.0, 92.0, 85.0, 95.0, 80.0));
leftSeries.setColor(new Color(106, 27, 154));
leftRadar.setSeriesList(Arrays.asList(leftSeries));
chartData.setLeftRadar(leftRadar);
// 右侧雷达:去年同期各维度得分
JDoubleRadarChartData.RadarData rightRadar = new JDoubleRadarChartData.RadarData();
JDoubleRadarChartData.Series rightSeries = new JDoubleRadarChartData.Series();
rightSeries.setName("去年同期");
rightSeries.setValues(Arrays.asList(81.0, 85.0, 79.0, 90.0, 76.0));
rightSeries.setColor(new Color(156, 39, 176));
rightRadar.setSeriesList(Arrays.asList(rightSeries));
chartData.setRightRadar(rightRadar);
chartData.setGridLevels(4);
chartData.setFillAlpha(70);
chartData.setLineWidth(2.0f);
chartData.setShowDataPoints(true);
chartData.setLegendAtTop(false);
chartData.setShowLegendSide(true);
chartData.setFooterText("数据来源:企业绩效管理系统");
JOption option = new JOption();
option.setData(chartData);
String svg = JChartRendererFactory.renderChart(JChartType.DoubleRadar, option);
File dir = new File(path + "biz");
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fileOutputStream = new FileOutputStream(path + "biz/38_kpi_double_radar.pdf");
JPdfConfig config = new JPdfConfig();
// 开启 flex 行布局,使模板中的 display:flex 生效(图表居中)
config.getLayoutConfig().setFlexLayout(true);
JQuickPdfFactory factory = new JQuickPdfFactory(config);
factory.bind("svg", svg);
byte[] bytes = factory.executeResource("report/biz/38_kpi_double_radar.txt");
fileOutputStream.write(bytes);
fileOutputStream.close();
}
}Minimal invocation (3 lines)
Skip the full test class — the core is these three lines: bind the chart SVG, execute the template, get the PDF bytes. Copy them straight into your project.
// config 可省略;svg 来自 JChartRendererFactory.renderChart(...),见下方完整源码
factory.bind("svg", svg);
byte[] pdf = new JQuickPdfFactory(config).executeResource("report/biz/38_kpi_double_radar.txt");Template file · 38_kpi_double_radar.txt
An HTML-like template with inline CSS that renders to PDF once bound to data. The full template is below — copy it or download the raw file.
<pdf>
<body>
<div style="background:#6A1B9A; padding:14px; borderRadius:4px; marginBottom:10px; keepTogether:true">
<div style="display:flex; justifyContent:space-between">
<div style="width:300px">
<h1 style="color:white; fontSize:18; bold:true; marginBottom:4px">'多维度 KPI 双雷达对比'</h1>
<p style="color:#E6D3F0; fontSize:9">'本期(2024年)与去年同期(2023年)绩效得分对比'</p>
</div>
<div style="width:240px; textAlignment:right; borderLeft:1px solid #A96FBD; paddingLeft:10px">
<p style="color:white; fontSize:9">'统计周期:2024年1月 - 2024年12月'</p>
<p style="color:#E6D3F0; fontSize:9">'考核维度:营收增长 / 成本控制 / 交付及时率 / 质量合格率 / 客户满意度'</p>
<p style="color:#E6D3F0; fontSize:9">'报送对象:年度绩效评审委员会'</p>
</div>
</div>
</div>
<h2 style="color:#6A1B9A; fontSize:13; bold:true; marginBottom:6px">'一、各维度得分对比'</h2>
<div style="marginBottom:12px">
<table style="width:540px; fontSize:10">
<tr>
<th style="width:150px; backgroundColor:#6A1B9A; color:white; padding:6px; textAlign:center; border:1px solid #D5BDE0">'考核维度'</th>
<th style="width:130px; backgroundColor:#6A1B9A; color:white; padding:6px; textAlign:center; border:1px solid #D5BDE0">'本期(2024年)'</th>
<th style="width:130px; backgroundColor:#6A1B9A; color:white; padding:6px; textAlign:center; border:1px solid #D5BDE0">'去年同期(2023年)'</th>
<th style="width:130px; backgroundColor:#6A1B9A; color:white; padding:6px; textAlign:center; border:1px solid #D5BDE0">'同比变动'</th>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px">'营收增长'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'88.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'81.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'+7.0'</td>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px">'成本控制'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'92.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'85.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'+7.0'</td>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px">'交付及时率'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'85.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'79.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'+6.0'</td>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px">'质量合格率'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'95.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'90.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'+5.0'</td>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px">'客户满意度'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'80.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'76.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC">'+4.0'</td>
</tr>
<tr>
<td style="border:1px solid #DCE3EC; borderLeft:3px solid #6A1B9A; padding:5px; bold:true">'平均得分'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC; bold:true">'88.0'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC; bold:true">'82.2'</td>
<td style="padding:5px; textAlign:right; border:1px solid #DCE3EC; bold:true">'+5.8'</td>
</tr>
</table>
</div>
<h2 style="color:#6A1B9A; fontSize:13; bold:true; marginBottom:6px">'二、双雷达得分对比'</h2>
<div style="marginBottom:12px">
<div style="display:flex; justifyContent:center">
<svg style="width:700pt">${svg}</svg>
</div>
<p style="fontSize:9; color:#6c757d; italic:true; marginTop:4px">'图 1 左雷达为本期(2024年)得分,右雷达为去年同期(2023年)得分(数据来源:企业绩效管理系统)'</p>
</div>
<h2 style="color:#6A1B9A; fontSize:13; bold:true; marginBottom:6px">'三、绩效复盘结论'</h2>
<list style="list-style-type:none; padding-left:0; fontSize:10">
<li style="borderTop:1px dashed #C7C7C7; paddingTop:6px; marginBottom:4px">'本期平均得分 88.0 分,较去年同期 82.2 分提升 5.8 分,五个维度全部实现正增长。'</li>
<li style="borderTop:1px dashed #C7C7C7; paddingTop:6px; marginBottom:4px">'质量合格率 95.0 分为本期最高,同比提升 5.0 分,是本年度表现最稳健的维度。'</li>
<li style="borderTop:1px dashed #C7C7C7; paddingTop:6px; marginBottom:4px">'客户满意度 80.0 分为五个维度中最低,同比提升 4.0 分,仍是下一年度的改善重点。'</li>
<li style="borderTop:1px dashed #C7C7C7; paddingTop:6px; marginBottom:4px">'交付及时率由 79.0 分升至 85.0 分,提升 6.0 分,交付周期压缩措施成效明显。'</li>
<li style="borderTop:1px dashed #C7C7C7; paddingTop:6px; marginBottom:4px">'建议:将客户满意度拆分为响应时长与一次性解决率两个二级指标,按季度跟踪并纳入部门考核。'</li>
</list>
<div style="textAlignment:center; marginTop:10px; paddingTop:10px; borderTop:1px solid #dee2e6; color:#6c757d; fontSize:8">
<p>'数据来源:企业绩效管理系统 | 生成时间:2025年1月15日'</p>
<p>'内部资料 · 未经许可请勿外传'</p>
</div>
</body>
</pdf>More demos in this group
The PDF, preview image, template and source code on this page were all produced by a real JQuick-Pdf run and are free to copy into your own project.