xyc
21 小时以前 54e10aee11aa4a10926df02782ca07d41eeb9b98
fix(holiday): 加大折线图纵向间距并同步 Word 尺寸
4个文件已修改
78 ■■■■■ 已修改文件
HANDOFF.md 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendChartService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayTrendChartServiceTest.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HANDOFF.md
@@ -6,6 +6,23 @@
## 最新(2026-10-06)
### 10-06:折线图纵向间距加高(验收通过)
- **用户背景**:客运量图线间距较好、标签摆放合理;其他多序列折线图因线距偏近,标签仍可能压线。用户同意适当增加图高,Word 只是取图来源,不要求当前分页为最终版,但图不能过高。
- **实现**:
  - `HolidayTrendChartService`:折线纵轴留白收紧为 `lowerMargin=0.04 / upperMargin=0.07`;`LINE_CHART_HEIGHT_SCALE=1.20`,所有折线 PNG 高度放大约 20%。
  - `HolidayTrendService`:12 张折线图的 Word 内嵌图片高度同步放大约 20%,保持 PNG 与 Word 图片框比例一致;饼图、堆叠图未改。
  - `HolidayTrendChartServiceTest`:新增折线图高度缩放断言。
- **验收**:用户于 2026-10-06 查看 `C:\Users\jcxiong\Downloads\2026年十一假期全省综合运输客流量走势图(折线加高20实验).docx` 后验收通过。
- **验证结果**:
  1. 15% 加高版在铁路客运量图 `image5` 检出 OCR 标签框重叠;20% 版 12 张折线图(`image1/2/4/5/6/7/8/9/10/11/14/15`)未检出标签框重叠。
  2. PNG 宽高比与 Word `wp:extent` 宽高比最大误差约 `0.162%`,未发生明显拉伸。
  3. Word 仍为 8 页、每页 2 张图(首页 1 张),与 15% 加高实验相同。
  4. 后端全量 `mvn -q test -f traffic-audit-server\pom.xml` 通过;`HolidayTrendChartServiceTest` 聚焦测试通过。
  5. 标签亲和度检查记录到 3 处标签框更靠近邻近线(`image1` 的 `1,518.02`、`image4` 的 `1,346.17`、`image9` 的 `248.65`);白描边保证可读,用户整体验收通过并保留该排版策略。
  6. `image13` 堆叠图有 4 处 OCR 标签重叠,但该图未参与本实验且代码未改。
- **数据边界**:未导入、覆盖或重导任何业务数据;仅本地只读生成走势图做实验。
### 10-06:平均拥挤度标签恢复为 2 位小数
- **调整**:按用户要求,“普通国省道观测站平均拥挤度”不再单独使用 3 位小数,恢复为折线图默认 2 位。
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendChartService.java
@@ -78,6 +78,7 @@
    private static final double ITEM_LABEL_GAP = 10.0;
    private static final float HALO_OUTLINE_WIDTH = 4.0f;
    private static final int PERCENT_ITEM_LABEL_DECIMALS = 1;
    private static final double LINE_CHART_HEIGHT_SCALE = 1.20;
    private static final Color ITEM_LABEL_COLOR = new Color(55, 55, 55);
    private static final Color[] SERIES_COLORS = {
            new Color(192, 80, 77),
@@ -141,8 +142,8 @@
        NumberAxis rangeAxis = new NumberAxis();
        rangeAxis.setAutoRangeIncludesZero(false);
        rangeAxis.setLowerMargin(0.12);
        rangeAxis.setUpperMargin(0.16);
        rangeAxis.setLowerMargin(0.04);
        rangeAxis.setUpperMargin(0.07);
        rangeAxis.setTickLabelFont(TICK_FONT);
        rangeAxis.setLabelFont(LABEL_FONT);
        rangeAxis.setTickLabelPaint(MUTED_TEXT_COLOR);
@@ -173,7 +174,8 @@
                    BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        }
        plot.setRenderer(renderer);
        return render(chart, width, height, yAxisLabel, true, percentAxis, valueDecimals);
        return render(chart, width, scaleLineChartHeight(height),
                yAxisLabel, true, percentAxis, valueDecimals);
    }
    public byte[] pieChart(String valueSuffix, List<ChartCategory> categories,
@@ -1115,6 +1117,14 @@
        return total;
    }
    static int scaleLineChartHeight(int height) {
        return (int) Math.round(height * LINE_CHART_HEIGHT_SCALE);
    }
    static long scaleLineChartHeight(long height) {
        return Math.round(height * LINE_CHART_HEIGHT_SCALE);
    }
    static BigDecimal displayValue(BigDecimal value, boolean percentItemLabels, int valueDecimals) {
        if (value == null) return null;
        int scale = percentItemLabels ? PERCENT_ITEM_LABEL_DECIMALS + 2 : valueDecimals;
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java
@@ -64,12 +64,12 @@
                prefix + "全省跨区域人员流动量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.totalDaily), false, 1100, 715),
                new HolidayTrendWordService.ImageSize(5268595L, 3424555L)));
                lineImageSize(5268595L, 3424555L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期累计跨区域人员流动量走势",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.totalCumulative), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期各交通运输方式客运量占比情况",
                chartService.pieChart("人次", selected.modalShare(), 1000, 607), true,
@@ -80,44 +80,44 @@
                "“" + holidayLabel + "”假期自驾出行量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.selfDrivingPersonFlow), false, 1100, 522),
                new HolidayTrendWordService.ImageSize(5232400L, 2484120L)));
                lineImageSize(5232400L, 2484120L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期铁路客运量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.rail), false, 1100, 445),
                new HolidayTrendWordService.ImageSize(5264785L, 2129155L)));
                lineImageSize(5264785L, 2129155L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期水路客运量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.water), false, 1100, 433),
                new HolidayTrendWordService.ImageSize(5274310L, 2075815L)));
                lineImageSize(5274310L, 2075815L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期民航客运量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.civilAviation), false, 1100, 521),
                new HolidayTrendWordService.ImageSize(5271135L, 2496185L)));
                lineImageSize(5271135L, 2496185L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期道路客运量情况",
                chartService.lineChart("万人次",
                        series(years, yearData, item -> item.road), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.SectionBlock("三、车流量走势"));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期高速公路车流量情况",
                chartService.lineChart("万辆次",
                        series(years, yearData, item -> item.expressway), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期普通国省道车流量情况",
                chartService.lineChart("万辆次",
                        series(years, yearData, item -> item.nationalProvincial), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期全省车流总量情况",
                chartService.lineChart("万辆次",
                        series(years, yearData, item -> item.totalVehicleFlow), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                "“" + holidayLabel + "”假期公路出行结构",
                chartService.stackedBarChart("万人次",
@@ -139,12 +139,12 @@
                prefix + "普通国省道观测站平均机动车速度",
                chartService.lineChart("公里/小时",
                        Collections.singletonList(series("平均速度", observation.speed)), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        blocks.add(new HolidayTrendWordService.ChartBlock(
                prefix + "普通国省道观测站平均拥挤度",
                chartService.lineChart("拥挤度",
                        Collections.singletonList(series("平均拥挤度", observation.congestion)), false, 1100, 590),
                new HolidayTrendWordService.ImageSize(5268595L, 2821305L)));
                lineImageSize(5268595L, 2821305L)));
        File template = resolveTemplateFile();
        if (!template.exists() || !template.isFile()) {
@@ -347,6 +347,11 @@
        return result;
    }
    private HolidayTrendWordService.ImageSize lineImageSize(long width, long height) {
        return new HolidayTrendWordService.ImageSize(
                width, HolidayTrendChartService.scaleLineChartHeight(height));
    }
    private File resolveTemplateFile() {
        List<File> candidates = new ArrayList<>();
        File configured = new File(trendTemplatePath);
traffic-audit-server/src/test/java/com/trafficaudit/holiday/service/HolidayTrendChartServiceTest.java
@@ -79,6 +79,22 @@
    }
    @Test
    void scalesLineChartHeightForBetterVerticalSeparation() throws Exception {
        HolidayTrendChartService service = new HolidayTrendChartService();
        HolidayTrendChartService.ChartSeries series = new HolidayTrendChartService.ChartSeries();
        series.setName("测试");
        series.setValues(java.util.Arrays.asList(
                new BigDecimal("1.00"), new BigDecimal("2.00"), new BigDecimal("3.00")));
        byte[] png = service.lineChart("万人次",
                java.util.Collections.singletonList(series), false, 1100, 590);
        BufferedImage image = ImageIO.read(new ByteArrayInputStream(png));
        assertNotNull(image);
        assertEquals(HolidayTrendChartService.scaleLineChartHeight(590), image.getHeight());
    }
    @Test
    void rendersHigherPrecisionLineLabelsWhenRequested() {
        HolidayTrendChartService service = new HolidayTrendChartService();
        HolidayTrendChartService.ChartSeries congestion = new HolidayTrendChartService.ChartSeries();