diff --git a/src/views/pages/MarketingAnalysis.vue b/src/views/pages/MarketingAnalysis.vue
index 7b40ce6..f5653df 100644
--- a/src/views/pages/MarketingAnalysis.vue
+++ b/src/views/pages/MarketingAnalysis.vue
@@ -341,13 +341,13 @@
-
Категория
-
Доля
+
Возраст
+
Доход
{{ row.label }}
-
{{ row.value }}%
+
{{ row.value }} ₸
@@ -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