r111/line.html · 约 4826 字符
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="line" 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="chips" id="dsw" style="padding-top:12px">13 <button class="on" data-v="sales">年度销售趋势</button>14 <button data-v="visits">近七日访问量</button>15</div>16<div class="card mt12">17 <div class="ch"><b id="tt">--</b><span id="src"></span></div>18 <div class="seg" id="mode" style="margin-bottom:10px">19 <button class="on" data-v="line">折线</button>20 <button data-v="smooth">平滑曲线</button>21 <button data-v="step">阶梯</button>22 </div>23 <div class="chart" id="c1"></div>24 <div class="legend" id="lg"></div>25</div>2627<div class="card">28 <div class="ch"><b>显示选项</b><span>点击即时重绘</span></div>29 <div class="tags" id="opts">30 <button class="tag" data-k="area">面积填充</button>31 <button class="tag" data-k="dots" style="background:var(--brand);color:#fff">显示数据点</button>32 <button class="tag" data-k="zero" style="background:var(--brand);color:#fff">Y 轴从零开始</button>33 </div>34 <div class="muted mt8">提示:在图表上左右滑动可查看每个数据点的十字准星提示框。</div>35</div>3637<div class="card">38 <div class="ch"><b>数据明细</b><span id="unit"></span></div>39 <div class="tblwrap"><table class="tbl" id="tbl"></table></div>40</div>4142<div class="card">43 <div class="ch"><b>统计摘要</b></div>44 <div id="stat"></div>45</div>46<div style="height:18px"></div>4748<div class="sheet" id="sjson">49 <div class="sh"><b>数据源 JSON</b><span class="x">×</span></div>50 <div class="sb"><pre class="code" id="jsonbox"></pre></div>51</div>525354<div class="mask" id="mask"></div>55<div class="toast" id="toast"></div>56<script src="data/fallback.js"></script>57<script src="chart.js"></script>58<script src="app.js"></script>59<script>6061var cur='sales', mode='line', opt={area:false,dots:true,zero:true}, DATA=null;6263function draw(){64 if(!DATA) return;65 CH.line($('#c1'), {66 cats:DATA.cats, series:DATA.series, mode:mode, area:opt.area,67 dots:opt.dots, zero:opt.zero, h:238, unit:DATA.unit68 });69}70function table(){71 var h='<thead><tr><th>指标</th>'+DATA.cats.map(function(c){return '<th>'+c+'</th>';}).join('')+'</tr></thead><tbody>';72 DATA.series.forEach(function(s){73 h+='<tr><td>'+s.name+'</td>'+s.data.map(function(v){return '<td>'+CH.thousand(v)+'</td>';}).join('')+'</tr>';74 });75 h+='</tbody>';76 $('#tbl').innerHTML=h;77}78function stat(){79 $('#stat').innerHTML = DATA.series.map(function(s){80 var mx=Math.max.apply(null,s.data), mn=Math.min.apply(null,s.data);81 var sum=s.data.reduce(function(a,b){return a+b;},0);82 var first=s.data[0]||1, last=s.data[s.data.length-1];83 var gr=((last-first)/Math.abs(first)*100);84 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>'+85 '<span>'+s.name+'</span><b>'+CH.thousand(sum)+(DATA.unit||'')+'</b></div>'+86 '<div class="muted">峰值 '+CH.num(mx)+' · 谷值 '+CH.num(mn)+' · 均值 '+CH.num(sum/s.data.length)+87 ' · 期末较期初 <b style="color:'+(gr>=0?'#fa5252':'#12b886')+'">'+(gr>=0?'+':'')+gr.toFixed(1)+'%</b></div></div>';88 }).join('');89}90function load(name){91 loading($('#c1'));92 DS.get(name).then(function(j){93 DATA = JSON.parse(JSON.stringify(j));94 DATA.__from = j.__from;95 $('#tt').textContent = DATA.name;96 $('#unit').textContent = '单位:' + (DATA.unit || '—');97 $('#src').innerHTML = srcBadge(DATA);98 draw(); table(); stat();99 CH.legend($('#lg'), DATA.series, draw);100 $('#jsonbox').innerHTML = hlJSON(j);101 })['catch'](function(e){ failBox($('#c1'), e); });102}103segGroup('#dsw', function(v){ cur=v; load(v); });104segGroup('#mode', function(v){ mode=v; draw(); });105$('#opts').addEventListener('click', function(e){106 var b=e.target.closest('button'); if(!b) return;107 var k=b.dataset.k; opt[k]=!opt[k];108 b.style.background = opt[k] ? 'var(--brand)' : 'var(--brand-l)';109 b.style.color = opt[k] ? '#fff' : 'var(--brand-d)';110 draw();111});112$('#viewjson').addEventListener('click', function(e){ e.preventDefault(); openSheet('#sjson'); });113114var qm = (location.search.match(/mode=(\w+)/)||[])[1];115if(qm){116 mode = qm;117 $$('#mode button').forEach(function(b){ b.classList.toggle('on', b.dataset.v===qm); });118}119load(cur);120121</script>122</body>123</html>124