r111/scatter.html · 约 4471 字符
1<!DOCTYPE html>2<html lang="zh-CN">3<head>4<meta charset="UTF-8">5<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">6<meta name="theme-color" content="#4263eb">7<title>散点图与气泡图 · 图表工具大全</title>8<link rel="stylesheet" href="style.css">9</head>10<body data-page="scatter" class="nopad">11<div class="navbar"><a class="bk" href="gallery.html">‹</a><div class="tt">散点图与气泡图</div><div class="rt"><a href="#" id="viewjson">JSON</a></div></div>12<div class="card" style="margin-top:12px">13 <div class="ch"><b id="tt">--</b><span id="src"></span></div>14 <div class="seg" id="mode" style="margin-bottom:8px">15 <button class="on" data-v="scatter">散点图</button>16 <button data-v="bubble">气泡图</button>17 </div>18 <div class="chart" id="c1"></div>19 <div class="legend" id="lg"></div>20 <div class="muted mt8" id="axis"></div>21</div>2223<div class="card">24 <div class="ch"><b>相关性分析</b><span>皮尔逊系数</span></div>25 <div id="corr"></div>26 <div class="muted mt8">系数越接近 1 表示投放金额与转化率的正相关性越强。</div>27</div>2829<div class="card">30 <div class="ch"><b>渠道效率对比</b><span>单位投放产出</span></div>31 <div class="chart" id="c2"></div>32</div>3334<div class="card">35 <div class="ch"><b>原始数据点</b><span id="ptcnt"></span></div>36 <div class="tblwrap"><table class="tbl" id="tbl"></table></div>37</div>38<div style="height:18px"></div>3940<div class="sheet" id="sjson">41 <div class="sh"><b>数据源 JSON</b><span class="x">×</span></div>42 <div class="sb"><pre class="code" id="jsonbox"></pre></div>43</div>444546<div class="mask" id="mask"></div>47<div class="toast" id="toast"></div>48<script src="data/fallback.js"></script>49<script src="chart.js"></script>50<script src="app.js"></script>51<script>5253var mode='scatter', DATA=null;5455function draw(){56 if(!DATA) return;57 CH.scatter($('#c1'), {58 series:DATA.series, bubble: mode==='bubble', h:262,59 xname:DATA.xname, yname:DATA.yname, zname:DATA.zname60 });61}62function pearson(pts){63 var n=pts.length, sx=0, sy=0, sxy=0, sxx=0, syy=0;64 pts.forEach(function(p){ sx+=p[0]; sy+=p[1]; sxy+=p[0]*p[1]; sxx+=p[0]*p[0]; syy+=p[1]*p[1]; });65 var d=Math.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy));66 return d ? (n*sxy-sx*sy)/d : 0;67}68function corr(){69 $('#corr').innerHTML = DATA.series.map(function(s){70 var r = pearson(s.points);71 return '<div class="rank"><div class="rt"><s class="dot" style="width:8px;height:8px;border-radius:50%;background:'+s.color+';display:inline-block"></s>'+72 '<span>'+s.name+'</span><b>r = '+r.toFixed(3)+'</b></div>'+73 '<div class="bar"><i style="width:'+(Math.abs(r)*100).toFixed(1)+'%;background:'+s.color+'"></i></div></div>';74 }).join('');75}76function eff(){77 var cats = DATA.series.map(function(s){ return s.name; });78 var data = DATA.series.map(function(s){79 var z=0, x=0;80 s.points.forEach(function(p){ z+=(p[2]||0); x+=p[0]; });81 return Math.round(z/x);82 });83 CH.bar($('#c2'), {84 cats:cats, series:[{name:'每万元成交订单', color:'#12b886', data:data}],85 label:true, h:190, unit:' 单'86 });87}88function table(){89 var n=0;90 var h='<thead><tr><th>渠道</th><th>'+DATA.xname+'</th><th>'+DATA.yname+'</th><th>'+DATA.zname+'</th></tr></thead><tbody>';91 DATA.series.forEach(function(s){92 s.points.forEach(function(p){93 n++;94 h+='<tr><td>'+s.name+'</td><td>'+p[0]+'</td><td>'+p[1]+'</td><td>'+CH.thousand(p[2])+'</td></tr>';95 });96 });97 $('#tbl').innerHTML=h+'</tbody>';98 $('#ptcnt').textContent = n + ' 个数据点';99}100loading($('#c1'));101DS.get('ad').then(function(j){102 DATA = JSON.parse(JSON.stringify(j));103 DATA.__from = j.__from;104 $('#tt').textContent = DATA.name;105 $('#src').innerHTML = srcBadge(DATA);106 $('#axis').textContent = 'X 轴:' + DATA.xname + ' Y 轴:' + DATA.yname + ' 气泡面积:' + DATA.zname;107 draw(); corr(); eff(); table();108 CH.legend($('#lg'), DATA.series, draw);109 $('#jsonbox').innerHTML = hlJSON(j);110})['catch'](function(e){ failBox($('#c1'), e); });111112segGroup('#mode', function(v){ mode=v; draw(); });113$('#viewjson').addEventListener('click', function(e){ e.preventDefault(); openSheet('#sjson'); });114115var qm=(location.search.match(/mode=(\w+)/)||[])[1];116if(qm==='bubble'){ mode='bubble'; $$('#mode button').forEach(function(b){ b.classList.toggle('on', b.dataset.v==='bubble'); }); }117118</script>119</body>120</html>121