diff --git a/index.html b/index.html index f127c07..fdc2472 100644 --- a/index.html +++ b/index.html @@ -179,14 +179,15 @@ - +
-

渠道效率对比

+

渠道效率对比(产品_国家 × 渠道)

+

每个产品_国家下列出其投放过的各渠道及效率指标,同组内可横向对比不同渠道表现。

- + @@ -446,17 +447,36 @@ options:{ responsive:true, maintainAspectRatio:false, plugins:{legend:{position:'right',labels:{boxWidth:12,font:{size:11}}}} } }); - // ---- 模块4:渠道效率表 ---- - document.querySelector('#channelTable tbody').innerHTML = chans.map(c => { - const cm = metrics(data.filter(x=>x.channel===c)); - return ` - - - - - - `; - }).join('') || ``; + // ---- 模块4:渠道效率对比(按 产品_国家 分组,展开各渠道)---- + // 分组键 = 产品 + 国家 + const groupMap = {}; + data.forEach(x => { + const g = x.product + '_' + x.location; + (groupMap[g] = groupMap[g] || []).push(x); + }); + // 分组按总展示降序;组内渠道也按展示降序 + const groupKeys = Object.keys(groupMap).sort((a,b)=> sum(groupMap[b],'impression') - sum(groupMap[a],'impression')); + let rowsHtml = ''; + groupKeys.forEach(g => { + const rows = groupMap[g]; + const chansInG = [...new Set(rows.map(x=>x.channel))] + .sort((a,b)=> sum(rows.filter(x=>x.channel===b),'impression') - sum(rows.filter(x=>x.channel===a),'impression')); + chansInG.forEach((c, idx) => { + const cm = metrics(rows.filter(x=>x.channel===c)); + const groupCell = idx===0 + ? `` + : ''; + rowsHtml += ` + ${groupCell} + + + + + + `; + }); + }); + document.querySelector('#channelTable tbody').innerHTML = rowsHtml || ``; // ---- 模块5:产品表现排行(按花费降序)---- const prods = [...new Set(data.map(d=>d.product))];
渠道展示点击转化产品_国家渠道展示点击转化 花费CTRCVReCPMCPCCPA
${c}${fmtNum(cm.imp)}${fmtNum(cm.clk)}${cm.cv}${fmtMoney(cm.sp)}${(cm.ctr*100).toFixed(2)}%${(cm.cvr*100).toFixed(2)}%$${cm.ecpm.toFixed(2)}$${cm.cpc.toFixed(3)}${cm.cpa?fmtMoney(cm.cpa):'-'}
暂无数据
${g}
${c}${fmtNum(cm.imp)}${fmtNum(cm.clk)}${cm.cv}${fmtMoney(cm.sp)}${(cm.ctr*100).toFixed(2)}%${(cm.cvr*100).toFixed(2)}%$${cm.ecpm.toFixed(2)}$${cm.cpc.toFixed(3)}${cm.cpa?fmtMoney(cm.cpa):'-'}
暂无数据