flask全栈开发中的echarts图表刷新问题

最近在用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]
相关推荐
小_太_阳6 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
智慧老师15 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
搬码后生仔2 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net
凡人的AI工具箱2 小时前
每天40分玩转Django:Django国际化
数据库·人工智能·后端·python·django·sqlite
Lx3522 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas
小池先生2 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
百罹鸟3 小时前
【vue高频面试题—场景篇】:实现一个实时更新的倒计时组件,如何确保倒计时在页面切换时能够正常暂停和恢复?
vue.js·后端·面试
qq_589568103 小时前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
小蜗牛慢慢爬行4 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
wm10434 小时前
java web springboot
java·spring boot·后端