This commit is contained in:
root
2026-01-17 17:07:14 +05:00
parent cf1567d8a2
commit 08bee68aa2
+70 -26
View File
@@ -341,13 +341,13 @@
<div class="mt-4 pt-4 border-t border-slate-200/70">
<div class="overflow-hidden rounded-xl border border-slate-200/70">
<div class="grid grid-cols-12 bg-slate-50 text-[12px] font-semibold text-slate-600">
<div class="col-span-8 px-3 py-2">Категория</div>
<div class="col-span-4 px-3 py-2 text-right">Доля</div>
<div class="col-span-8 px-3 py-2">Возраст</div>
<div class="col-span-4 px-3 py-2 text-right">Доход</div>
</div>
<div class="divide-y divide-slate-200/70">
<div v-for="row in incomeTableRows" :key="row.label" class="grid grid-cols-12 px-3 py-2.5">
<div class="col-span-8 text-[13px] text-slate-800">{{ row.label }}</div>
<div class="col-span-4 text-[13px] text-slate-800 text-right">{{ row.value }}%</div>
<div class="col-span-4 text-[13px] text-slate-800 text-right">{{ row.value }} </div>
</div>
</div>
</div>
@@ -1517,33 +1517,77 @@ const ageBarData = computed(() => ({
]
}));
const incomeBarData = computed(() => {
const above = aboveAvgIncomeValue.value;
const other = Math.max(0, 100 - above);
return {
labels: ['Остальные', 'Выше среднего'],
datasets: [
{
data: [other, above],
borderRadius: 10,
backgroundColor: (context) => {
const { chart } = context;
const { ctx, chartArea } = chart;
if (!chartArea) return ['rgba(148,163,184,0.55)', 'rgba(82,196,26,0.55)'];
return [makeVerticalGradient(ctx, chartArea, 'rgba(148,163,184,0.75)', 'rgba(148,163,184,0.25)'), makeVerticalGradient(ctx, chartArea, 'rgba(82,196,26,0.80)', 'rgba(82,196,26,0.25)')];
}
}
]
// Income by age rows
const incomeRows = computed(() => {
const incomeByAge = report.value?.sections?.target_audience?.income_by_age ?? {};
// Маппинг ключей бэкенда на ключи фронтенда
const backendKeyMap = {
'18-24': { '18-24': 1.0 },
'18-25': { '18-24': 1.0 },
'25-34': { '25-34': 1.0 },
'25-45': { '25-34': 0.5, '35-44': 0.5 },
'35-44': { '35-44': 1.0 },
'20-40': { '25-34': 0.5, '35-44': 0.5 },
'45-54': { '45-54': 1.0 },
'40-60': { '45-54': 1.0 },
'55+': { '55+': 1.0 },
'60+': { '55+': 1.0 },
'60_plus': { '55+': 1.0 }
};
// Стандартный порядок для отображения
const order = [
{ key: '18-24', label: '1824' },
{ key: '25-34', label: '2534' },
{ key: '35-44', label: '3544' },
{ key: '45-54', label: '4554' },
{ key: '55+', label: '55+' }
];
// Агрегируем значения из бэкенда
const aggregated = {};
Object.keys(incomeByAge).forEach((backendKey) => {
const mapping = backendKeyMap[backendKey];
if (mapping) {
const value = Number(incomeByAge[backendKey]) || 0;
Object.keys(mapping).forEach((frontendKey) => {
if (!aggregated[frontendKey]) aggregated[frontendKey] = 0;
aggregated[frontendKey] += value * mapping[frontendKey];
});
}
});
// Формируем строки в нужном порядке
return order
.map(({ key, label }) => {
const value = aggregated[key] || 0;
return { key, label, value: Math.round(value) };
})
.filter((row) => row.value > 0);
});
const incomeBarData = computed(() => ({
labels: incomeRows.value.map((r) => r.label),
datasets: [
{
data: incomeRows.value.map((r) => r.value),
borderRadius: 10,
backgroundColor: (context) => {
const { chart } = context;
const { ctx, chartArea } = chart;
if (!chartArea) return 'rgba(82,196,26,0.55)';
return makeVerticalGradient(ctx, chartArea, 'rgba(82,196,26,0.80)', 'rgba(82,196,26,0.25)');
}
}
]
}));
const incomeTableRows = computed(() => {
const above = aboveAvgIncomeValue.value;
const other = Math.max(0, 100 - above);
return [
{ label: 'Остальные', value: other },
{ label: 'Выше среднего', value: above }
];
return incomeRows.value.map((row) => ({
label: row.label,
value: row.value.toLocaleString('ru-RU')
}));
});
// Segments list