使用 EJS 渲染 OHLC 图并传递数据的问题

问题描述 投票:0回答:1

我正在尝试在我的

chart.ejs
文件中渲染 Plotly OHLC 图,并将名为
result
的变量传递给它。但是,当我尝试使用 EJS 模板将
result
包含在
chart.ejs
文件中时,该图不会显示。我还尝试使用
<script>
标签进行逻辑,但绘图仍然不显示。我制作了另一个文件
chart.js
来包含有关情节的逻辑,但我不确定如何使其工作。

可能导致此问题的原因是什么?如何使用 EJS 模板中的结果数据成功渲染 Plotly OHLC 图?

index.js:

import express from "express";
import axios from "axios";

const app = express();
const port = 3000;

app.use(express.static("public"));
app.set("view engine", "ejs"); // Set EJS as the view engine

const base_url = "https://api.coingecko.com/api/v3";

app.get("/", (req, res) => {
  res.render("index.ejs", { result: null, error: null });
});

app.get("/ohlc", async (req, res) => {
  const { id, currency, days } = req.query;

  if (!id || !currency || !days) {
    return res
      .status(400)
      .json({ error: "Please provide id, currency, and days parameters." });
  }

  try {
    const ohlc_result = await axios.get(`${base_url}/coins/${id}/ohlc`, {
      params: {
        vs_currency: currency,
        days: days,
      },
    });

    let day = [];
    let open = [];
    let high = [];
    let low = [];
    let close = [];

    for (let i = 0; i < ohlc_result.data.length; i++) {
      const unix_timestamp = ohlc_result.data[i][0];
      const date = new Date(unix_timestamp);
      const formattedDate = date.toISOString().split('T')[0];

      if (!day.includes(formattedDate)) {
        day.push(formattedDate);
        open.push(ohlc_result.data[i][1]);
        high.push(ohlc_result.data[i][2]);
        low.push(ohlc_result.data[i][3]);
        close.push(ohlc_result.data[i][4]);
      }
    }

    // Create the OHLC trace
    const result = {
      x: day,
      open: open,
      high: high,
      low: low,
      close: close,
      type: "ohlc",
      increasing: { line: { color: "#17BECF" } },
      decreasing: { line: { color: "#7F7F7F" } },
    };

    console.log("OHLC Result:", ohlc_result.data);
    console.log("Formatted Result:", result);
    res.render("chart.ejs", { result: result });

  } catch (error) {
    console.log(error.message);
    res.status(500).send(error.message);
  }
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

chart.js:

const trace = {
    x: result.x,
    open: result.open,
    high: result.high,
    low: result.low,
    close: result.close,
    type: "ohlc",
    increasing: { line: { color: "#17BECF" } },
    decreasing: { line: { color: "#7F7F7F" } },
};

const layout = {
    title: "OHLC Chart",
    dragmode: "zoom",
    xaxis: {
        title: "Date",
        type: "date",
    },
    yaxis: {
        title: "Price",
        type: "linear",
    },
};

Plotly.newPlot("ohlc-result-div", [trace], layout);

图表.ejs:

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>CryptoLens</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <link rel="stylesheet" href="styles/main.css">
        <script src='https://cdn.plot.ly/plotly-2.35.2.min.js'></script>

        <!-- <script src="/chart.js" defer></script> -->

    </head>

    <body>
        <h1>OHLC Chart</h1>

        <!-- THE FOLLOWING DOES NOT WORK -->
        <!-- <script>
            const trace = {
                x: result.x,
                open: result.open,
                high: result.high,
                low: result.low,
                close: result.close,
                type: "ohlc",
                increasing: { line: { color: "#17BECF" } },
                decreasing: { line: { color: "#7F7F7F" } },
            };

            const layout = {
                title: "OHLC Chart",
                dragmode: "zoom",
                xaxis: {
                    title: "Date",
                    type: "date",
                },
                yaxis: {
                    title: "Price",
                    type: "linear",
                },
            };

            Plotly.newPlot("ohlc-result", [trace], layout);
        </script> -->

        <div id="ohlc-result-div"><!-- Plotly chart will be drawn inside this DIV --></div>
    </body>

</html>

我知道将

result
发送到
chart.ejs
时存在一些问题,我只是不确定是什么。

javascript express plotly ejs ohlc
1个回答
0
投票

这里的问题是如何使用传递给渲染引擎的变量。

您传递给

render()
函数的变量仅在渲染期间可用,并且仅适用于 EJS 标签
<% ... %>
中的代码。您可以在这个答案上阅读有关 EJS 变量的更多信息。

这意味着在

<script>
中没有定义
result
变量。据我所知,您有两个选择:

  1. 将 EJS 变量传递给脚本

    可能更快、更简单的解决方案是将变量传递给脚本标记。从技术上讲,它就像

    一样简单
    <script>
        let resultInScript = <%= result %>
        ...
    

    但有一些注意事项。首先也是最重要的,大多数 IDE 都会将其显示为错误,即使它会执行。这只是因为它不知道

    <script>
    内的 EJS 语法,并且可以通过使用任何字符串分隔符(
    "
    引号、
    '
    撇号、
    `
    反引号)来避免它,如下所示:

    <script>
        let resultInScript = "<%= result %>"
        ...
    

    下一个问题是对象。回顾上一期,如果我们想一想,无论EJS标签中的变量到底是什么,它在javascript端总是一个字符串。因此,如果我们像之前那样简单地传递

    result
    ,那么
    resultInScript
    就只是
    [object Object]
    作为字符串。所以所有这一切的最终形式看起来像

    <script>
        let resultInScript = JSON.parse("<%= JSON.stringify(result) %>");
        ...
    
  2. AJAX 请求服务器

    另一种解决方案是在页面加载时向服务器发送异步请求并获取数据。 因此,您可以在服务器上创建一条路由,例如

    app.get('/ohcl/data'...
    ,并在页面加载时立即向服务器发送请求。根据数据的重要程度,您可以仅使用数据作为查询参数发出 GET 请求,也可以使用正文中的数据发出 POST 请求。这并不是说它超级安全,但至少没有将它们作为查询参数。

    这也将使您的页面加载时间更短,并且数据/图表的加载速度类似,具体取决于数据检索的速度,最多几秒,最多几毫秒。

希望对你有帮助,如有不清楚的地方请随时询问。

© www.soinside.com 2019 - 2024. All rights reserved.