.
This commit is contained in:
@@ -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: '18–24' },
|
||||
{ key: '25-34', label: '25–34' },
|
||||
{ key: '35-44', label: '35–44' },
|
||||
{ key: '45-54', label: '45–54' },
|
||||
{ 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
|
||||
|
||||
Reference in New Issue
Block a user