Skip to content

Multi-dimensional KPI double radar (performance management) — generate this PDF with Java (DoubleRadar)

JQuick-PdfBiz Demo

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.

Download the PDFView raw template fileBack to all demos

Multi-dimensional KPI double radar (performance management) — DoubleRadar
Rendered output

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.