feat: show data labels on channel-compare and spend-share charts
This commit is contained in:
+24
-3
@@ -5,6 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Moboost 广告投放报告</title>
|
<title>Moboost 广告投放报告</title>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0/dist/chartjs-plugin-datalabels.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
body {
|
body {
|
||||||
@@ -363,6 +364,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Tab 1: 投放数据 ---------- */
|
/* ---------- Tab 1: 投放数据 ---------- */
|
||||||
|
// datalabels 默认全局注册,先取消,只在需要的图表按需启用
|
||||||
|
if (window.ChartDataLabels) { try { Chart.unregister(ChartDataLabels); } catch(e){} }
|
||||||
const CH_COLORS = { Mintegral:'#3b82f6', MediaGo:'#10b981', Bigo:'#f59e0b' };
|
const CH_COLORS = { Mintegral:'#3b82f6', MediaGo:'#10b981', Bigo:'#f59e0b' };
|
||||||
const PALETTE = ['#3b82f6','#10b981','#f59e0b','#ef4444','#8b5cf6','#06b6d4','#ec4899','#84cc16','#f97316','#6366f1'];
|
const PALETTE = ['#3b82f6','#10b981','#f59e0b','#ef4444','#8b5cf6','#06b6d4','#ec4899','#84cc16','#f97316','#6366f1'];
|
||||||
let perfCharts = {};
|
let perfCharts = {};
|
||||||
@@ -471,15 +474,33 @@
|
|||||||
{ label:'转化', data:chConv, backgroundColor:'#ef4444', borderRadius:4, yAxisID:'y1' },
|
{ label:'转化', data:chConv, backgroundColor:'#ef4444', borderRadius:4, yAxisID:'y1' },
|
||||||
]},
|
]},
|
||||||
options:{ responsive:true, maintainAspectRatio:false,
|
options:{ responsive:true, maintainAspectRatio:false,
|
||||||
plugins:{legend:{position:'top',labels:{boxWidth:12,font:{size:11}}}},
|
layout:{padding:{top:24}},
|
||||||
|
plugins:{
|
||||||
|
legend:{position:'top',labels:{boxWidth:12,font:{size:11}}},
|
||||||
|
datalabels:{
|
||||||
|
anchor:'end', align:'end', color:'#374151', font:{size:11,weight:'600'},
|
||||||
|
formatter:(v,ctx)=> ctx.datasetIndex===0 ? '$'+Math.round(v).toLocaleString() : Math.round(v).toLocaleString()
|
||||||
|
}
|
||||||
|
},
|
||||||
scales:{ x:{grid:{display:false},ticks:{color:'#9ca3af'}},
|
scales:{ x:{grid:{display:false},ticks:{color:'#9ca3af'}},
|
||||||
y:{position:'left',ticks:{color:'#9ca3af'},grid:{color:'#f3f4f6'}},
|
y:{position:'left',ticks:{color:'#9ca3af'},grid:{color:'#f3f4f6'}},
|
||||||
y1:{position:'right',ticks:{color:'#9ca3af'},grid:{display:false}} } }
|
y1:{position:'right',ticks:{color:'#9ca3af'},grid:{display:false}} } },
|
||||||
|
plugins:[ChartDataLabels]
|
||||||
});
|
});
|
||||||
|
const totalSpend = chSpend.reduce((a,b)=>a+b,0) || 1;
|
||||||
drawChart('chartSpendShare', {
|
drawChart('chartSpendShare', {
|
||||||
type:'doughnut',
|
type:'doughnut',
|
||||||
data:{ labels:chans, datasets:[{ data:chSpend, backgroundColor:chans.map(c=>CH_COLORS[c]||'#999') }] },
|
data:{ labels:chans, datasets:[{ data:chSpend, backgroundColor:chans.map(c=>CH_COLORS[c]||'#999') }] },
|
||||||
options:{ responsive:true, maintainAspectRatio:false, plugins:{legend:{position:'right',labels:{boxWidth:12,font:{size:11}}}} }
|
options:{ responsive:true, maintainAspectRatio:false,
|
||||||
|
plugins:{
|
||||||
|
legend:{position:'right',labels:{boxWidth:12,font:{size:11}}},
|
||||||
|
datalabels:{
|
||||||
|
color:'#fff', font:{size:12,weight:'700'},
|
||||||
|
formatter:(v)=> (v/totalSpend*100)>=5 ? '$'+Math.round(v).toLocaleString()+'\n'+(v/totalSpend*100).toFixed(0)+'%' : '',
|
||||||
|
textAlign:'center'
|
||||||
|
}
|
||||||
|
} },
|
||||||
|
plugins:[ChartDataLabels]
|
||||||
});
|
});
|
||||||
|
|
||||||
// ---- 模块4:渠道效率对比(按 产品_国家 分组,展开各渠道)----
|
// ---- 模块4:渠道效率对比(按 产品_国家 分组,展开各渠道)----
|
||||||
|
|||||||
Reference in New Issue
Block a user