feat(document): подразделы 5.1/5.2 + блок «Разрыв» + сравнение регионов

Расширил генератор чтобы он умел рендерить структуру эталонного отчёта:
- §5 'Сравнительный анализ предприятий' разбит на 5.1 (лидеры) и 5.2 (кластеры)
- 5.1: heading2 + text.leaders5_1 (массив или строка) + chart2
- 5.2: heading2 + text.cluster5_2 + text.clusterGroups (массив объектов
  {title, text} рендерится как жирный bullet + текст) + chart3 +
  text.gap (calloutBox с красной полосой)
- chart4 + text.regionComparisonSummary — после блока кластеризации

Раздел 5 теперь визуально соответствует эталону DT_Вологда_2026.docx.
This commit is contained in:
Ник
2026-06-08 21:10:16 +03:00
parent a0af0ba772
commit 5b73983805
+56 -14
View File
@@ -293,31 +293,73 @@ async function buildDocument ({ subject, period, data, text, meta = {}, charts =
} }
} }
// ═══ 5. РЕГИОНАЛЬНЫЙ РАЗРЕЗ ════════════════════════════════════════════════ // ═══ 5. СРАВНИТЕЛЬНЫЙ АНАЛИЗ ══════════════════════════════════════════════
if (charts.chart2 || charts.chart3 || charts.chart4) { if (charts.chart2 || charts.chart3 || charts.chart4 || text.leaders5_1 || text.cluster5_2) {
children.push(heading1('5. Региональный разрез и эффективность'), spacer(60)) children.push(heading1('5. Сравнительный анализ предприятий'), spacer(60))
if (text.regionalSummary) { // 5.1 Лидеры по субсидиям, прибыли и переработке
children.push(body(text.regionalSummary), spacer(100)) if (text.leaders5_1 || charts.chart2) {
children.push(heading2('5.1. Лидеры по субсидиям, прибыли и переработке'))
if (text.leaders5_1) {
if (Array.isArray(text.leaders5_1)) text.leaders5_1.forEach(t => children.push(body(t)))
else children.push(body(text.leaders5_1))
children.push(spacer(60))
} }
if (charts.chart2) { if (charts.chart2) {
children.push(caption('Рисунок 2. Лидеры по закупочной цене молока')) children.push(caption('Рисунок 2. Лидеры рынка: чистая прибыль и объём переработки'))
children.push(imgPara(charts.chart2)) children.push(imgPara(charts.chart2))
children.push(spacer(80)) children.push(spacer(120))
}
} }
if (charts.chart4) { // 5.2 Кластеризация предприятий по финансовым индексам (II / OH / CS)
children.push(caption('Рисунок 3. Сравнение регионов: лидеры и аутсайдеры')) if (text.cluster5_2 || (text.clusterGroups && text.clusterGroups.length) || charts.chart3 || text.gap) {
children.push(imgPara(charts.chart4)) children.push(heading2('5.2. Кластеризация предприятий по финансовым индексам (II / OH / CS)'))
if (text.cluster5_2) {
if (Array.isArray(text.cluster5_2)) text.cluster5_2.forEach(t => children.push(body(t)))
else children.push(body(text.cluster5_2))
}
if (text.clusterGroups && text.clusterGroups.length) {
text.clusterGroups.forEach(g => {
if (typeof g === 'string') {
children.push(dashBullet(g))
} else {
// объект { title, text } — рендерим title жирно + текст
children.push(new Paragraph({
spacing: { after: 80 },
indent: { left: 360, hanging: 240 },
children: [
run('\t', { size: 21, color: D.dGray }),
run((g.title || '') + ' ', { size: 21, bold: true, color: D.dGray }),
run(g.text || '', { size: 21, color: D.dGray })
]
}))
}
})
children.push(spacer(80)) children.push(spacer(80))
} }
if (charts.chart3) { if (charts.chart3) {
children.push(caption('Рисунок 4. EBITDA-маржа по группам эффективности хозяйств')) children.push(caption('Рисунок 3. EBITDA margin производителей · ранжирование по группам А–В'))
children.push(imgPara(charts.chart3)) children.push(imgPara(charts.chart3))
if (text.efficiencySummary) children.push(body(text.efficiencySummary)) children.push(spacer(120))
children.push(spacer(80)) }
// Блок «Разрыв ...» — выделенный
if (text.gap && (text.gap.title || text.gap.text)) {
children.push(calloutBox(text.gap.title || 'Разрыв лидеров и аутсайдеров', text.gap.text || ''))
children.push(spacer(160))
}
}
// Сравнение с соседними регионами / другими ФО
if (charts.chart4) {
children.push(caption('Рисунок 4. Сравнение с соседними регионами и РФ'))
children.push(imgPara(charts.chart4))
if (text.regionComparisonSummary) children.push(body(text.regionComparisonSummary))
children.push(spacer(120))
} }
} }