Add revenue by channel — Общий/Расход/Прибыль/ROI + bar chart доход vs расход
This commit is contained in:
1 parent
d5fb5b4949
commit
a825d84fee
1 file changed
+89
-16
+89
-16
@@ -127,6 +127,8 @@ body{font-family:'Inter',-apple-system,sans-serif;background:var(--bg);color:var
|
||||
|
||||
<div class="sum-row" id="cpa-sum"></div>
|
||||
|
||||
<div class="sum-row" id="rev-sum" style="margin-bottom:12px"></div>
|
||||
|
||||
<div class="cr cr2">
|
||||
<div class="cc">
|
||||
<div class="ch"><div class="ct" id="cpa-main-t"></div><div class="cs" id="cpa-main-s"></div></div>
|
||||
@@ -139,6 +141,11 @@ body{font-family:'Inter',-apple-system,sans-serif;background:var(--bg);color:var
|
||||
</div>
|
||||
|
||||
<div class="cc" style="margin-bottom:12px">
|
||||
<div class="ch"><div class="ct">Доход по каналам</div><div class="cs">Выручка и расход по каналам привлечения</div></div>
|
||||
<div class="cd s" id="rev-channel"></div>
|
||||
</div>
|
||||
|
||||
<div class="cc" style="margin-bottom:12px">
|
||||
<div class="ch"><div class="ct">Раскрытие: ключевые запросы</div><div class="cs">Нажмите на канал для детализации</div></div>
|
||||
<div id="cpa-table-wrap" style="max-height:350px;overflow:auto;margin-top:12px"></div>
|
||||
</div>
|
||||
@@ -150,6 +157,8 @@ body{font-family:'Inter',-apple-system,sans-serif;background:var(--bg);color:var
|
||||
|
||||
<div class="sum-row" id="conv-sum"></div>
|
||||
|
||||
<div class="sum-row" id="conv-rev" style="margin-bottom:12px"></div>
|
||||
|
||||
<div class="cr cr2">
|
||||
<div class="cc">
|
||||
<div class="ch"><div class="ct" id="cv-main-t"></div><div class="cs" id="cv-main-s"></div></div>
|
||||
@@ -183,6 +192,8 @@ body{font-family:'Inter',-apple-system,sans-serif;background:var(--bg);color:var
|
||||
|
||||
<div class="sum-row" id="ltv-sum"></div>
|
||||
|
||||
<div class="sum-row" id="ltv-rev" style="margin-bottom:12px"></div>
|
||||
|
||||
<div class="cr cr2">
|
||||
<div class="cc">
|
||||
<div class="ch"><div class="ct" id="ltv-main-t"></div><div class="cs" id="ltv-main-s"></div></div>
|
||||
@@ -227,11 +238,15 @@ const DATA = {
|
||||
spend: {v:'1.1М ₽',d:'+8%',t:'up',n:'расход на рекламу'},
|
||||
ratio: {v:'62%',d:'−3%',t:'down',n:'CPA / средний чек'},
|
||||
channels: [
|
||||
{n:'Яндекс Директ',spend:520000,conv:120,cpa:4333,avg:863},
|
||||
{n:'VK Реклама',spend:280000,conv:65,cpa:4308,avg:862},
|
||||
{n:'SEO',spend:150000,conv:35,cpa:4286,avg:857},
|
||||
{n:'Ретаргетинг',spend:120000,conv:15,cpa:8000,avg:800},
|
||||
{n:'Яндекс Директ',spend:520000,conv:120,cpa:4333,avg:863,revenue:1072000},
|
||||
{n:'VK Реклама',spend:280000,conv:65,cpa:4308,avg:862,revenue:560000},
|
||||
{n:'SEO',spend:150000,conv:35,cpa:4286,avg:857,revenue:299857},
|
||||
{n:'Ретаргетинг',spend:120000,conv:15,cpa:8000,avg:800,revenue:120000},
|
||||
],
|
||||
totalRevenue: '2 051 857 ₽',
|
||||
totalSpend: '1 070 000 ₽',
|
||||
totalProfit: '981 857 ₽',
|
||||
roi: '91.8%',
|
||||
keywords: {
|
||||
'Яндекс Директ': [
|
||||
{q:'купить [товар] москва', clicks:3200, conv:85, cpa:3200, cost_per_click:45},
|
||||
@@ -336,10 +351,14 @@ const DATA = {
|
||||
spend: {v:'275К ₽',d:'+5%',t:'up',n:'расход на рекламу'},
|
||||
ratio: {v:'18%',d:'−2%',t:'down',n:'CPA / средний чек'},
|
||||
channels: [
|
||||
{n:'Яндекс Директ',spend:140000,conv:42,cpa:3333,avg:18476},
|
||||
{n:'VK Реклама',spend:75000,conv:22,cpa:3409,avg:18409},
|
||||
{n:'SEO',spend:60000,conv:22,cpa:2727,avg:18182},
|
||||
{n:'Яндекс Директ',spend:140000,conv:42,cpa:3333,avg:18476,revenue:775952},
|
||||
{n:'VK Реклама',spend:75000,conv:22,cpa:3409,avg:18409,revenue:405000},
|
||||
{n:'SEO',spend:60000,conv:22,cpa:2727,avg:18182,revenue:400004},
|
||||
],
|
||||
totalRevenue: '1 580 956 ₽',
|
||||
totalSpend: '275 000 ₽',
|
||||
totalProfit: '1 305 956 ₽',
|
||||
roi: '474.9%',
|
||||
keywords: {
|
||||
'Яндекс Директ': [
|
||||
{q:'создать сайт цена', clicks:1800, conv:42, cpa:2800, cost_per_click:52},
|
||||
@@ -424,11 +443,15 @@ const DATA = {
|
||||
spend: {v:'4.2М ₽',d:'+4%',t:'up',n:'расход на рекламу'},
|
||||
ratio: {v:'5.2%',d:'−1%',t:'down',n:'CPA / средний чек'},
|
||||
channels: [
|
||||
{n:'Яндекс Директ',spend:2100000,conv:150,cpa:14000,avg:270000},
|
||||
{n:'VK Реклама',spend:980000,conv:100,cpa:9800,avg:245000},
|
||||
{n:'SEO',spend:520000,conv:50,cpa:10400,avg:260000},
|
||||
{n:'Выставки',spend:600000,conv:40,cpa:15000,avg:300000},
|
||||
{n:'Яндекс Директ',spend:2100000,conv:150,cpa:14000,avg:270000,revenue:4050000},
|
||||
{n:'VK Реклама',spend:980000,conv:100,cpa:9800,avg:245000,revenue:2450000},
|
||||
{n:'SEO',spend:520000,conv:50,cpa:10400,avg:260000,revenue:1300000},
|
||||
{n:'Выставки',spend:600000,conv:40,cpa:15000,avg:300000,revenue:1200000},
|
||||
],
|
||||
totalRevenue: '10 050 000 ₽',
|
||||
totalSpend: '4 200 000 ₽',
|
||||
totalProfit: '5 850 000 ₽',
|
||||
roi: '139.3%',
|
||||
keywords: {
|
||||
'Яндекс Директ': [
|
||||
{q:'купить [оборудование] оптом', clicks:2800, conv:55, cpa:11200, cost_per_click:48},
|
||||
@@ -553,6 +576,14 @@ function renderCPA(d) {
|
||||
{l:'CPA / чек',v:c.ratio.v,d:c.ratio.d,t:c.ratio.t,n:c.ratio.n},
|
||||
]);
|
||||
|
||||
// Revenue summary
|
||||
sumRow('rev-sum', [
|
||||
{l:'Общий доход',v:c.totalRevenue,d:'+15%',t:'up',n:'за 30 дней'},
|
||||
{l:'Расход',v:c.totalSpend,d:'+8%',t:'up',n:'на рекламу'},
|
||||
{l:'Прибыль',v:c.totalProfit,d:'+12%',t:'up',n:'доход − расход'},
|
||||
{l:'ROI',v:c.roi,d:'+5%',t:'up',n:'возврат инвестиций'},
|
||||
]);
|
||||
|
||||
// Main: CPA trend
|
||||
const mc = document.getElementById('cpa-main');
|
||||
if (!charts.cpaMain) charts.cpaMain = echarts.init(mc);
|
||||
@@ -597,6 +628,30 @@ function renderCPA(d) {
|
||||
|
||||
// Table: Keywords
|
||||
renderKeywordTable(c.keywords);
|
||||
|
||||
// Revenue by channel
|
||||
const rc = document.getElementById('rev-channel');
|
||||
if (!charts.revChannel) charts.revChannel = echarts.init(rc);
|
||||
const revData = c.channels.map(ch => ({
|
||||
name: ch.n,
|
||||
spend: ch.spend,
|
||||
revenue: ch.revenue,
|
||||
profit: ch.revenue - ch.spend,
|
||||
roi: ((ch.revenue - ch.spend) / ch.spend * 100).toFixed(0) + '%',
|
||||
}));
|
||||
const chNames = revData.map(r => r.name);
|
||||
charts.revChannel.setOption({
|
||||
tooltip:{trigger:'axis',backgroundColor:'#111',borderColor:'#222',textStyle:{color:'#fafafa',fontSize:11}},
|
||||
legend:{data:['Доход','Расход'],textStyle:{color:'#52525b',fontSize:10},top:0},
|
||||
grid:{left:100,right:16,top:30,bottom:10},
|
||||
xAxis:{type:'category',data:chNames,axisLine:{lineStyle:{color:'#1e1e22'}},axisLabel:{color:'#a1a1aa',fontSize:9}},
|
||||
yAxis:{type:'value',splitLine:{lineStyle:{color:'#1a1a1e'}},axisLabel:{color:'#52525b',fontSize:10,formatter:v=>v>=1e6?(v/1e6).toFixed(0)+'М':(v/1e3).toFixed(0)+'К'}},
|
||||
series:[
|
||||
{name:'Доход',type:'bar',data:revData.map(r=>r.revenue),barWidth:'35%',itemStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:'#22c55e'},{offset:1,color:'rgba(34,197,94,.3)'}]),borderRadius:[4,4,0,0]}},
|
||||
{name:'Расход',type:'bar',data:revData.map(r=>r.spend),barWidth:'35%',itemStyle:{color:new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:'#3b82f6'},{offset:1,color:'rgba(59,130,246,.3)'}]),borderRadius:[4,4,0,0]}},
|
||||
],
|
||||
animationDuration:600,
|
||||
},true);
|
||||
}
|
||||
|
||||
function renderKeywordTable(keywords) {
|
||||
@@ -627,11 +682,20 @@ function renderConv(d) {
|
||||
const c = d.conv;
|
||||
|
||||
sumRow('conv-sum', [
|
||||
{l:'Конверсия',v:c.avg.v,d:c.avg.d,t:c.avg.t,n:c.avg.n},
|
||||
{l:'Лиды',v:c.leads.v,d:c.leads.d,t:c.leads.t,n:c.leads.n},
|
||||
{l:'Продажи',v:c.sales.v,d:c.sales.d,t:c.sales.t,n:c.sales.n},
|
||||
{l:'Цикл',v:c.cycle.v,d:c.cycle.d,t:c.cycle.t,n:c.cycle.n},
|
||||
]);
|
||||
{l:'Конверсия',v:c.avg.v,d:c.avg.d,t:c.avg.t,n:c.avg.n},
|
||||
{l:'Лиды',v:c.leads.v,d:c.leads.d,t:c.leads.t,n:c.leads.n},
|
||||
{l:'Продажи',v:c.sales.v,d:c.sales.d,t:c.sales.t,n:c.sales.n},
|
||||
{l:'Цикл',v:c.cycle.v,d:c.cycle.d,t:c.cycle.t,n:c.cycle.n},
|
||||
]);
|
||||
|
||||
// Revenue in conv tab (using CPA data)
|
||||
const rc = DATA[curSeg].cpa;
|
||||
sumRow('conv-rev', [
|
||||
{l:'Общий доход',v:rc.totalRevenue,d:'+15%',t:'up',n:'за 30 дней'},
|
||||
{l:'Расход',v:rc.totalSpend,d:'+8%',t:'up',n:'на рекламу'},
|
||||
{l:'Прибыль',v:rc.totalProfit,d:'+12%',t:'up',n:'доход − расход'},
|
||||
{l:'ROI',v:rc.roi,d:'+5%',t:'up',n:'возврат инвестиций'},
|
||||
]);
|
||||
|
||||
// Main: Conv trend
|
||||
const mc = document.getElementById('cv-main');
|
||||
@@ -717,6 +781,15 @@ function renderLTV(d) {
|
||||
{l:'Ср. чек',v:c.avgCheck.v,d:c.avgCheck.d,t:c.avgCheck.t,n:c.avgCheck.n},
|
||||
]);
|
||||
|
||||
// Revenue in LTV tab
|
||||
const rc = DATA[curSeg].cpa;
|
||||
sumRow('ltv-rev', [
|
||||
{l:'Общий доход',v:rc.totalRevenue,d:'+15%',t:'up',n:'за 30 дней'},
|
||||
{l:'Расход',v:rc.totalSpend,d:'+8%',t:'up',n:'на рекламу'},
|
||||
{l:'Прибыль',v:rc.totalProfit,d:'+12%',t:'up',n:'доход − расход'},
|
||||
{l:'ROI',v:rc.roi,d:'+5%',t:'up',n:'возврат инвестиций'},
|
||||
]);
|
||||
|
||||
// Main: LTV curve
|
||||
const mc = document.getElementById('ltv-main');
|
||||
if (!charts.ltvMain) charts.ltvMain = echarts.init(mc);
|
||||
|
||||
Reference in new issue
Block a user