系列文章目录
前言
前面2章我们搭建了web的基础框架并实现了基本的功能,接下来我们开始添砖上瓦。本章我们新增一个小功能就是可以点击列表里面的基金就可以查看当前基金的历史走势,这样有助于我们从全局上来审核和预测接下来的涨跌幅。
备注: 这次新加的功能完全由前端实现没有涉及到python代码
一. 设计思路
- 在table的每一列前面添加一个小按钮
- 点击按钮可以在当前列下面展开一个box
- 在这个新展开的box里面展示出我们需要的历史数据
- 这个历史数据最好是用图表的方式呈现
二. 使用到的工具
- JS 图表库 chartJS Chart.js | Chart.js (chartjs.org)
- Support chartJS的一个工具库luxon Home (moment.github.io)
- 获取基金详细信息的接口 http://fund.eastmoney.com/pingzhongdata/{基金代码}.js
三. 详细步骤
1.点击table行进行div展开
这个功能我们借由bootstrap的Collapse来实现 Collapse · Bootstrap v5 中文文档 v5.1 | Bootstrap 中文网 (bootcss.com)
- 首先我们在每一行的开始添加一个按钮链接
<tr> <td> <a data-bs-toggle="collapse" href="#collapse_{{fund.fund_id}}" role="button" aria-expanded="false" aria-controls="collapse_{{fund.fund_id}}" onclick="showChart({{fund}})" >>></a> </td>
- 然后我们新加一行来放置我们的详情图表,因为我们的html table 行是循环输出的,所以ID也要用参数生成不然的每行的ID都是相同的
<tr> <td colspan="9"> <div class="collapse" id="collapse_{{fund.fund_id}}"> <canvas id="myChart_{{fund.fund_id}}" height="100" width="500"></canvas> </div> </td> </tr>
2.展开TR的时候画出图表
- 首先我们要知道一点就是那个基金API返回的是一个JS文件,然后里面已经吧你需要的各种参数定义好了,所以我们加载完这个JS就可以直接下面的function里面使用他这些参数
- 然后我不想每次页面加载的时候就把所有的基金API都请求到html里面,这样会浪费浏览器资源而且使用太多次人家的API也有可能被封IP,所以这边的思路是点击展开按钮的时候触发图表事件的时候才去load JS,下面是具体实现
function loadJS(url, callback, params) { var script = document.createElement('script'), fn = callback || function () { }; script.type = 'text/javascript'; //IE if (script.readyState) { script.onreadystatechange = function () { if (script.readyState == 'loaded' || script.readyState == 'complete') { script.onreadystatechange = null; fn(params); } }; } else { //其他浏览器 script.onload = function () { fn(params); }; } script.src = url; document.getElementsByTagName('head')[0].appendChild(script); }
-
所以当我们点击当前基金的扩展按钮的时候,首先bootstrap的Collapse会先帮我们展开第二个tr,然后我们自己写的showCart也会触发,去执行画图表的操作
function showChart(fund) { let chartHave = $("#myChart_" + fund.fund_id).attr("chart") if (chartHave) { console.log("this chart {0} is already print in web".format(fund.fund_id)) return } let fund_detail_js_url = "http://fund.eastmoney.com/pingzhongdata/{0}.js".format(fund.fund_id) loadJS(fund_detail_js_url, callbak, fund.fund_id) }
- 因为load JS需要时间,所以我们传了了一个callbak进去,等API JS确定load完了才触发我们的callbak, 这个callbak才是我们真正的绘画chart的方法,这边我们画一个图表,然后里面有3个数据一个是本基金的历史数据,然后一个是同类基金的平均数据,最后一个是沪深300的数据,方便我们进行比较,关于chartJS的具体用法和配置可以看这个wiki Chart.js | Chart.js (chartjs.org)
function callbak(fund_id) {
console.log(Data_grandTotal)
let fund_rates = Data_grandTotal[0].data
let labels = []
let data = {
labels: labels,
datasets: []
};
let fundDateSets = {
label: Data_grandTotal[0].name,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
borderWidth:1,
pointRadius: 2,
data: []
}
let averageDateSets = {
label: "同类平均",
backgroundColor: '#1473d34a',
borderColor: '#1473d34a',
borderDash: [2, 2],
borderWidth:1,
pointRadius: 2,
data: []
}
let hs300DateSets = {
label: "沪深300",
backgroundColor: '#92c1044f',
borderColor: '#92c1044f',
borderWidth:1,
pointRadius: 2,
data: []
}
for (let i = 0; i < fund_rates.length; i++) {
let fund_rate = fund_rates[i]
// labels.push(transformTime(fund_rate[0]))
labels.push(newDate(fund_rate[0]))
fundDateSets.data.push(fund_rate[1])
}
let average_rate = Data_grandTotal[1].data
for (let i = 0; i < average_rate.length; i++) {
let avg_rate = average_rate[i]
averageDateSets.data.push(avg_rate[1])
}
let hs300_rate = Data_grandTotal[2].data
for (let i = 0; i < hs300_rate.length; i++) {
let hs_rate = hs300_rate[i]
hs300DateSets.data.push(hs_rate[1])
}
data.datasets.push(fundDateSets)
data.datasets.push(averageDateSets)
data.datasets.push(hs300DateSets)
let config = {
type: 'line',
data: data,
options: {
plugins: {
title: {
display: true,
text: '累计收益率走势'
},
legend:{
position:"right"
}
},
scales: {
x: {
type: 'time',
display: true,
offset: true,
time: {
unit: 'month'
}
}
}
}
};
console.log(config)
const myChart = new Chart(
document.getElementById('myChart_' + fund_id),
config
);
$("#myChart_" + fund_id).attr("chart", 'yes');
}
四. 结果预览
总结
写这个新功能大概话了半天左右,期间也需要查官方wiki和文档,学习本来就是不断学习的查阅的过程,要不断的遇坑填坑才能不断的完善自己,希望每天都可以学习一些新东西吧
==> 需要源码的可以评论留下邮箱,一起交流 <==