最近在用akshare抓取金融数据做分析的过程中遇到了一个数据刷新的问题,就是在数据更新以后,echarts图表没有根据新数据变化,而是需要重启项目才能改变,这里讲一下怎么解决问题。
我的项目做了前后端分离,在蓝图中,我利用akshare提供的数据接口获取金融数据,并存到本地的json文件中。然后,读取JSON文件,把数据交给前端,并用echarts画出图表。这个项目主要是做股票的复盘,因此我不会每次加载页面都爬去和刷新数据。
python
def refresh_data():
fund_stock_position_lg_data = ak.fund_stock_position_lg()
item_title = fund_stock_position_lg_data.columns.tolist()
getdata = {}
for item in item_title:
getdata[f"{item}"] = fund_stock_position_lg_data[f"{item}"]
data = pd.DataFrame(getdata)
json_data = data.to_json(orient="records")
# 将 JSON 字符串写入文件
with open(file_path_stock, "w", encoding="utf-8") as json_file:
json_file.write(json_data)
fund_linghuo_position_lg_data = ak.fund_linghuo_position_lg()
linghuo_item_title = fund_linghuo_position_lg_data.columns.tolist()
这是一个数据刷新函数,他的目的是获取数据并保存到本地json。
python
# =============================================================
# 读取 股票基金仓位详情
# =============================================================
global json_data_stock, stock_date, stock_close, stock_position
with open(file_path_stock, "r") as json_file:
json_data_stock = json.load(json_file)
stock_date = [
datetime.datetime.fromtimestamp(item["date"] / 1000).strftime("%Y-%m-%d")
for item in json_data_stock
]
stock_close = [item["close"] for item in json_data_stock]
stock_position = [item["position"] for item in json_data_stock]
@bp.route("/get_fund_stock_position_map")
def get_fund_stock_position_map():
position_data = [
{"name": b, "value": t} for b, t in zip(stock_date, stock_position)
]
return jsonify(data=position_data)
这段代码用于读取数据和发送数据。
python
# 定义路由:手动更新数据
@bp.route("/refresh-Fundsdata", methods=["POST"])
def handle_update_data():
refresh_data()
return redirect("Funds.html")
# 调用定时器
scheduler = BackgroundScheduler()
scheduler.add_job(
refresh_data, "cron", hour=19, minute=0, timezone=timezone("Asia/Shanghai")
)
scheduler.start()
在更新数据上,我设置了定时更新和手动更新两种方式。
js
function getFundStockPositionMap() {
$.ajax({
url: "/get_fund_stock_position_map",
method: "GET",
success: function (response) {
var data = response.data;
var xAxisData = [];
var seriesData = []; // 折线图数据
for (var i = 0; i < data.length; i++) {
var item = data[i];
xAxisData.push(item.name);
seriesData.push(item.value);
}
var chart = echarts.init(document.getElementById("get_fund_stock_position_map"));
var option = {
xAxis: {
type: "category",
data: xAxisData,
},
yAxis: {
type: "value"
},
series: [
{
name: "Value",
type: "line",
data: seriesData,
tooltip: {
trigger: "axis", // 设置触发类型为坐标轴
axisPointer: { // 坐标轴指示器配置
type: "shadow" // 设置指示器类型为阴影
}
}
}
],
tooltip: {
trigger: "axis",
formatter: '基金仓位 <br/>{b} : {c}%',
axisPointer: {
type: "cross",
animation: false,
label: {
backgroundColor: "#283b56"
}
}
},
dataZoom: [ // 添加数据区域缩放组件
{
type: "inside", // 内置缩放
start: 0, // 起始位置
end: 100 // 结束位置
},
{
show: true, // 显示滑动条
type: "inside", // 滑动条缩放
y: "90%", // 滑动条位置
start: 0, // 起始位置
end: 100 // 结束位置
}
]
};
;
chart.setOption(option);
},
error: function (error) {
console.log("Error:", error);
}
});
}
我们利用ajax接收数据并画图,但此时我们发现,我们使用更新数据,图表没有变化。
网上介绍了许多解决方法,但尝试以后,都没有解决问题。最后发现是在刷新以后,虽然本地JSON数据变了,但是发送给echarts的数据没有改变,而是缓存和使用了刷新以前的数据。我们需要在刷新数据的时候,重新获取作图需要的数据。
在reflash函数中加上数据的读取就可以解决问题 ,注意这里要把 stock_date , stock_close,stock_position这些用到的数据设置为全局变量,否则会失败。而reflash函数外的数据读取也要保留,否则第一次加载页面时是看不到数据的,因为我没有设置每次进入页面都使用reflash。
python
def refresh_data():
fund_stock_position_lg_data = ak.fund_stock_position_lg()
item_title = fund_stock_position_lg_data.columns.tolist()
getdata = {}
for item in item_title:
getdata[f"{item}"] = fund_stock_position_lg_data[f"{item}"]
data = pd.DataFrame(getdata)
json_data = data.to_json(orient="records")
# 将 JSON 字符串写入文件
with open(file_path_stock, "w", encoding="utf-8") as json_file:
json_file.write(json_data)
fund_linghuo_position_lg_data = ak.fund_linghuo_position_lg()
linghuo_item_title = fund_linghuo_position_lg_data.columns.tolist()
# =============================================================
# 读取 股票基金仓位详情
# =============================================================
global json_data_stock, stock_date, stock_close, stock_position
with open(file_path_stock, "r") as json_file:
json_data_stock = json.load(json_file)
stock_date = [
datetime.datetime.fromtimestamp(item["date"] / 1000).strftime("%Y-%m-%d")
for item in json_data_stock
]
stock_close = [item["close"] for item in json_data_stock]
stock_position = [item["position"] for item in json_data_stock]