From adee580f186d7f1cc5d5405792d6b0c13076f0a2 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期四, 08 十月 2026 14:29:41 +0800
Subject: [PATCH] fix(holiday): 铁路客运量走势图10月3日标签上移避免遮挡
---
traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java | 104 ++++++++++++++++++++++++---------------------------
1 files changed, 49 insertions(+), 55 deletions(-)
diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java
index f02238e..08ef648 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/holiday/service/HolidayTrendService.java
@@ -15,6 +15,7 @@
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -47,16 +48,10 @@
if (holidayLabel == null) {
throw new IllegalArgumentException("涓嶆敮鎸佺殑鑺傚亣鏃ョ被鍨�");
}
- List<HolidayCalendar> holidayDays = configService.findHolidayDays(year, holidayType);
- if (holidayDays.isEmpty()) {
- throw new IllegalArgumentException("鎵�閫夊勾浠藉拰鑺傚亣鏃ュ皻鏈厤缃棩鏈燂紝璇峰厛鍦ㄧ郴缁熼厤缃腑缁存姢鑺傚亣鏃�");
- }
- List<String> dayLabels = dayLabels(holidayDays);
- int dayCount = holidayDays.size();
List<Integer> years = Arrays.asList(year, year - 1, year - 2);
Map<Integer, YearData> yearData = new LinkedHashMap<>();
for (Integer item : years) {
- yearData.put(item, buildYearData(item, holidayType, dayCount));
+ yearData.put(item, buildYearData(item, holidayType));
}
YearData selected = yearData.get(year);
if (selected == null || !selected.hasAnyData()) {
@@ -69,12 +64,12 @@
blocks.add(new HolidayTrendWordService.ChartBlock(
prefix + "鍏ㄧ渷璺ㄥ尯鍩熶汉鍛樻祦鍔ㄩ噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.totalDaily), false, dayLabels, 2, 1100, 715),
+ series(years, yearData, item -> item.totalDaily), false, 1100, 715),
lineImageSize(5268595L, 3424555L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熺疮璁¤法鍖哄煙浜哄憳娴佸姩閲忚蛋鍔�",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.totalCumulative), false, dayLabels, 2, 1100, 590),
+ series(years, yearData, item -> item.totalCumulative), false, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熷悇浜ら�氳繍杈撴柟寮忓杩愰噺鍗犳瘮鎯呭喌",
@@ -85,44 +80,50 @@
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熻嚜椹惧嚭琛岄噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.selfDrivingPersonFlow), false, dayLabels, 2, 1100, 522),
+ series(years, yearData, item -> item.selfDrivingPersonFlow), false, 1100, 522),
lineImageSize(5232400L, 2484120L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熼搧璺杩愰噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.rail), false, dayLabels, 2, 1100, 445),
+ // Pin the 2026 rail label for day 3 above its point so the
+ // 2024 label (70.6) no longer covers it; other charts keep
+ // automatic placement.
+ series(years, yearData, item -> item.rail), false, 2,
+ HolidayTrendChartService.DAY_LABELS, 1100, 445,
+ Collections.singletonList(new HolidayTrendChartService.LineLabelOverride(
+ 0, 2, HolidayTrendChartService.LineLabelAnchor.ABOVE))),
lineImageSize(5264785L, 2129155L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熸按璺杩愰噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.water), false, dayLabels, 2, 1100, 433),
+ series(years, yearData, item -> item.water), false, 1100, 433),
lineImageSize(5274310L, 2075815L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熸皯鑸杩愰噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.civilAviation), false, dayLabels, 2, 1100, 521),
+ series(years, yearData, item -> item.civilAviation), false, 1100, 521),
lineImageSize(5271135L, 2496185L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熼亾璺杩愰噺鎯呭喌",
chartService.lineChart("涓囦汉娆�",
- series(years, yearData, item -> item.road), false, dayLabels, 2, 1100, 590),
+ series(years, yearData, item -> item.road), false, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.SectionBlock("涓夈�佽溅娴侀噺璧板娍"));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熼珮閫熷叕璺溅娴侀噺鎯呭喌",
chartService.lineChart("涓囪締娆�",
- series(years, yearData, item -> item.expressway), false, dayLabels, 2, 1100, 590),
+ series(years, yearData, item -> item.expressway), false, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熸櫘閫氬浗鐪侀亾杞︽祦閲忔儏鍐�",
chartService.lineChart("涓囪締娆�",
- series(years, yearData, item -> item.nationalProvincial), false, dayLabels, 2, 1100, 590),
+ series(years, yearData, item -> item.nationalProvincial), false, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熷叏鐪佽溅娴佹�婚噺鎯呭喌",
chartService.lineChart("涓囪締娆�",
- series(years, yearData, item -> item.totalVehicleFlow), false, dayLabels, 2, 1100, 590),
+ series(years, yearData, item -> item.totalVehicleFlow), false, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熷叕璺嚭琛岀粨鏋�",
@@ -135,21 +136,23 @@
blocks.add(new HolidayTrendWordService.ChartBlock(
"鈥�" + holidayLabel + "鈥濆亣鏈熸瘡鏃ュ娴佹瀯鎴愬彉鍖�",
chartService.stackedBarChart("鍗犳瘮",
- dayLabels,
- dailyShareSeries(selected, dayCount), true, 1000, 607), true,
+ HolidayTrendChartService.DAY_LABELS,
+ dailyShareSeries(selected), true, 1000, 607), true,
new HolidayTrendWordService.ImageSize(5106670L, 3097530L)));
blocks.add(new HolidayTrendWordService.SectionBlock("闄勫綍浜� 鏅�氬浗鐪侀亾瑙傛祴绔欒矾缃戣繍琛�"));
- ObservationData observation = observationData(holidayDays);
+ ObservationData observation = observationData(year, holidayType);
blocks.add(new HolidayTrendWordService.ChartBlock(
prefix + "鏅�氬浗鐪侀亾瑙傛祴绔欏钩鍧囨満鍔ㄨ溅閫熷害",
chartService.lineChart("鍏噷/灏忔椂",
- Collections.singletonList(series("骞冲潎閫熷害", observation.speed)), false, dayLabels, 2, 1100, 590),
+ Collections.singletonList(series("骞冲潎閫熷害", observation.speed)), false, 2,
+ observation.labels, 1100, 590),
lineImageSize(5268595L, 2821305L)));
blocks.add(new HolidayTrendWordService.ChartBlock(
prefix + "鏅�氬浗鐪侀亾瑙傛祴绔欏钩鍧囨嫢鎸ゅ害",
chartService.lineChart("鎷ユ尋搴�",
- Collections.singletonList(series("骞冲潎鎷ユ尋搴�", observation.congestion)), false, dayLabels, 2, 1100, 590),
+ Collections.singletonList(series("骞冲潎鎷ユ尋搴�", observation.congestion)), false, 2,
+ observation.labels, 1100, 590),
lineImageSize(5268595L, 2821305L)));
File template = resolveTemplateFile();
@@ -163,9 +166,9 @@
}
}
- private YearData buildYearData(int year, String holidayType, int dayCount) {
+ private YearData buildYearData(int year, String holidayType) {
List<DailyMetrics> metrics = new ArrayList<>();
- for (int day = 1; day <= dayCount; day++) {
+ for (int day = 1; day <= HolidayTrendChartService.DAY_LABELS.size(); day++) {
metrics.add(statService.dailyMetrics(year, holidayType, day));
}
YearData data = new YearData();
@@ -216,19 +219,19 @@
return result;
}
- private List<HolidayTrendChartService.ChartSeries> dailyShareSeries(YearData data, int dayCount) {
+ private List<HolidayTrendChartService.ChartSeries> dailyShareSeries(YearData data) {
List<HolidayTrendChartService.ChartSeries> result = new ArrayList<>();
- result.add(series("鑷┚", share(data.selfDrivingPersonFlow, data, dayCount)));
- result.add(series("閬撹矾", share(data.road, data, dayCount)));
- result.add(series("閾佽矾", share(data.rail, data, dayCount)));
- result.add(series("姘戣埅", share(data.civilAviation, data, dayCount)));
- result.add(series("姘磋矾", share(data.water, data, dayCount)));
+ result.add(series("鑷┚", share(data.selfDrivingPersonFlow, data)));
+ result.add(series("閬撹矾", share(data.road, data)));
+ result.add(series("閾佽矾", share(data.rail, data)));
+ result.add(series("姘戣埅", share(data.civilAviation, data)));
+ result.add(series("姘磋矾", share(data.water, data)));
return result;
}
- private List<BigDecimal> share(List<BigDecimal> values, YearData data, int dayCount) {
+ private List<BigDecimal> share(List<BigDecimal> values, YearData data) {
List<BigDecimal> result = new ArrayList<>();
- for (int i = 0; i < dayCount; i++) {
+ for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) {
BigDecimal total = dayTotal(data, i);
BigDecimal value = valueAt(values, i);
result.add(total == null || total.signum() == 0
@@ -266,9 +269,10 @@
series("閬撹矾瀹㈣繍閲�", road));
}
- private ObservationData observationData(List<HolidayCalendar> days) {
+ private ObservationData observationData(int year, String holidayType) {
+ List<HolidayCalendar> days = configService.findHolidayDays(year, holidayType);
if (days.isEmpty()) {
- return new ObservationData(nulls(0), nulls(0));
+ return new ObservationData(nulls(), nulls(), HolidayTrendChartService.DAY_LABELS);
}
LocalDate start = days.get(0).getHolidayDate();
LocalDate end = days.get(days.size() - 1).getHolidayDate();
@@ -277,14 +281,18 @@
for (ObservationDailyOperation row : rows) {
byDate.put(row.getObsDate(), row);
}
+ DateTimeFormatter labelFormat = DateTimeFormatter.ofPattern("M鏈坉鏃�");
List<BigDecimal> speed = new ArrayList<>();
List<BigDecimal> congestion = new ArrayList<>();
+ List<String> labels = new ArrayList<>();
for (HolidayCalendar day : days) {
- ObservationDailyOperation row = byDate.get(day.getHolidayDate());
+ LocalDate date = day.getHolidayDate();
+ ObservationDailyOperation row = byDate.get(date);
speed.add(row == null ? null : row.getAverageSpeed());
congestion.add(row == null ? null : row.getAverageCongestion());
+ labels.add(date.format(labelFormat));
}
- return new ObservationData(speed, congestion);
+ return new ObservationData(speed, congestion, labels);
}
private HolidayTrendChartService.ChartSeries series(String name, List<BigDecimal> values) {
@@ -324,8 +332,7 @@
private List<BigDecimal> percentageChanges(List<BigDecimal> current, List<BigDecimal> previous) {
List<BigDecimal> result = new ArrayList<>();
- int size = Math.max(current == null ? 0 : current.size(), previous == null ? 0 : previous.size());
- for (int i = 0; i < size; i++) {
+ for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) {
BigDecimal currentValue = valueAt(current, i);
BigDecimal previousValue = valueAt(previous, i);
BigDecimal ratio = HolidayNumberUtils.divide(currentValue, previousValue);
@@ -348,24 +355,9 @@
}
private List<BigDecimal> nulls() {
- return nulls(HolidayTrendChartService.DAY_LABELS.size());
- }
-
- private List<BigDecimal> nulls(int size) {
List<BigDecimal> result = new ArrayList<>();
- for (int i = 0; i < size; i++) result.add(null);
+ for (int i = 0; i < HolidayTrendChartService.DAY_LABELS.size(); i++) result.add(null);
return result;
- }
-
- static List<String> dayLabels(List<HolidayCalendar> days) {
- List<String> labels = new ArrayList<>();
- if (days == null) return labels;
- for (HolidayCalendar day : days) {
- if (day == null || day.getHolidayDate() == null) continue;
- labels.add(day.getHolidayDate().getMonthValue() + "鏈�"
- + day.getHolidayDate().getDayOfMonth() + "鏃�");
- }
- return labels;
}
private HolidayTrendWordService.ImageSize lineImageSize(long width, long height) {
@@ -462,10 +454,12 @@
private static class ObservationData {
private final List<BigDecimal> speed;
private final List<BigDecimal> congestion;
+ private final List<String> labels;
- private ObservationData(List<BigDecimal> speed, List<BigDecimal> congestion) {
+ private ObservationData(List<BigDecimal> speed, List<BigDecimal> congestion, List<String> labels) {
this.speed = speed;
this.congestion = congestion;
+ this.labels = labels;
}
}
}
--
Gitblit v1.9.1