使用Django后端将数据传递给D3.js

发布于 2025-02-13 14:45:07 字数 5545 浏览 2 评论 0原文

我想按照代码在这里。我对通过包含时期时间和收盘价的数据进行了略有更改。 代码

{% load static %}
<html>
<script src="https://d3js.org/d3.v4.js"></script>

<body> 
    <h1> Hello! </h1>
    <div id="my_dataviz"></div>
</body>


<script>

    // set the dimensions and margins of the graph
    var margin = {top: 10, right: 30, bottom: 30, left: 60},
        width = 460 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
    // append the svg object to the body of the page
    var svg = d3.select("#my_dataviz")
      .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform",
              "translate(" + margin.left + "," + margin.top + ")");
    
    //Read the data
    var d = {
               "Date":{
                  "0":1641168000000,
                  "1":1641254400000,
                  "2":1641340800000
               },
               "Close":{
                  "0":182.01,
                  "1":179.7,
                  "2":174.92
               }
            };

    
    
    // When reading the csv, I must format variables:
    d3.json(d,
      function(d){
        return { date : d3.timeParse("%s")(d.Date), value : d.Close }
      },
    
      // Now I can use this dataset:
      function(data) {
    
        // Add X axis --> it is a date format
        var x = d3.scaleTime()
          .domain(d3.extent(data, function(d) { return d.date; }))
          .range([ 0, width ]);
        svg.append("g")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
    
        // Add Y axis
        var y = d3.scaleLinear()
          .domain([0, d3.max(data, function(d) { return +d.value; })])
          .range([ height, 0 ]);
        svg.append("g")
          .call(d3.axisLeft(y));
    
        // Add the line
        svg.append("path")
          .datum(data)
          .attr("fill", "none")
          .attr("stroke", "steelblue")
          .attr("stroke-width", 1.5)
          .attr("d", d3.line()
            .x(function(d) { return x(d.date) })
            .y(function(d) { return y(d.value) })
            )
    
    })
     
</script>
</html>

以下是我无法生成图形的 。我已经连接了下面的控制台屏幕截图。

似乎存在错误传递数据,如下面的HTML文件中

所示href =“ https://i.sstatic.net/fbtqa.png” rel =“ nofollow noreferrer”>

我不知道如何传递数据,应该做什么?

编辑

应用的建议更改如下

{% load static %}
<html>
<script src="https://d3js.org/d3.v6.js"></script>
<body> 
    <h1> Hello! </h1>
    <div id="my_dataviz"></div>
    <!-- <canvas id="chart" width="100" height="100"></canvas>   -->
    <!-- <script src={% static "js\linechart.js" %}></script>  
    <script>
        var data = {{ AAPL|safe }};

        var chart = LineChart(data, {
        x: d => d.date,
        y: d => d.close,
        yLabel: "↑ Daily close ($)",
        width: 400,
        height: 400,
        color: "steelblue"
      });
    
    </script>     -->
</body>


<script>

    // set the dimensions and margins of the graph
    const margin = {top: 10, right: 30, bottom: 30, left: 60},
        width = 460 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
    // append the svg object to the body of the page
    const svg = d3.select("#my_dataviz")
      .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);

    var d = [
       {
         "Date": 1641168000000,
         "Close": 182.01
       },
       {
         "Date": 1641254400000,
         "Close": 179.7
       },
       {
         "Date": 1641168000000,
         "Close": 174.92
       },
    ];

       d3.json(d,
    
      // When reading the csv, I must format variables:
      function(d){
        return { date : d3.timeParse("%s")(d.Date), value : d.Close }
      }).then(
    
      // Now I can use this dataset:
      function(data) {
    
        // Add X axis --> it is a date format
        const x = d3.scaleTime()
          .domain(d3.extent(data, function(d) { return d.date; }))
          .range([ 0, width ]);
        svg.append("g")
          .attr("transform", `translate(0, ${height})`)
          .call(d3.axisBottom(x));
    
        // Add Y axis
        const y = d3.scaleLinear()
          .domain([0, d3.max(data, function(d) { return +d.value; })])
          .range([ height, 0 ]);
        svg.append("g")
          .call(d3.axisLeft(y));
    
        // Add the line
        svg.append("path")
          .datum(data)
          .attr("fill", "none")
          .attr("stroke", "steelblue")
          .attr("stroke-width", 1.5)
          .attr("d", d3.line()
            .x(function(d) { return x(d.date) })
            .y(function(d) { return y(d.value) })
            )
    
    })
    </script>
</html>

I want to build a line chart following the code here. I've made slight change to the data being passed with contains epoch time and a closing price. Following is the code

{% load static %}
<html>
<script src="https://d3js.org/d3.v4.js"></script>

<body> 
    <h1> Hello! </h1>
    <div id="my_dataviz"></div>
</body>


<script>

    // set the dimensions and margins of the graph
    var margin = {top: 10, right: 30, bottom: 30, left: 60},
        width = 460 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
    // append the svg object to the body of the page
    var svg = d3.select("#my_dataviz")
      .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform",
              "translate(" + margin.left + "," + margin.top + ")");
    
    //Read the data
    var d = {
               "Date":{
                  "0":1641168000000,
                  "1":1641254400000,
                  "2":1641340800000
               },
               "Close":{
                  "0":182.01,
                  "1":179.7,
                  "2":174.92
               }
            };

    
    
    // When reading the csv, I must format variables:
    d3.json(d,
      function(d){
        return { date : d3.timeParse("%s")(d.Date), value : d.Close }
      },
    
      // Now I can use this dataset:
      function(data) {
    
        // Add X axis --> it is a date format
        var x = d3.scaleTime()
          .domain(d3.extent(data, function(d) { return d.date; }))
          .range([ 0, width ]);
        svg.append("g")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
    
        // Add Y axis
        var y = d3.scaleLinear()
          .domain([0, d3.max(data, function(d) { return +d.value; })])
          .range([ height, 0 ]);
        svg.append("g")
          .call(d3.axisLeft(y));
    
        // Add the line
        svg.append("path")
          .datum(data)
          .attr("fill", "none")
          .attr("stroke", "steelblue")
          .attr("stroke-width", 1.5)
          .attr("d", d3.line()
            .x(function(d) { return x(d.date) })
            .y(function(d) { return y(d.value) })
            )
    
    })
     
</script>
</html>

I am unable to generate the graph. I've attached the console screenshot below.

enter image description here

There seems to be an error passing data as seen in html file below

enter image description here

I can't figure out how to pass the data, what should be the correct way to do it?

Edit

Applied suggested changes as follows

{% load static %}
<html>
<script src="https://d3js.org/d3.v6.js"></script>
<body> 
    <h1> Hello! </h1>
    <div id="my_dataviz"></div>
    <!-- <canvas id="chart" width="100" height="100"></canvas>   -->
    <!-- <script src={% static "js\linechart.js" %}></script>  
    <script>
        var data = {{ AAPL|safe }};

        var chart = LineChart(data, {
        x: d => d.date,
        y: d => d.close,
        yLabel: "↑ Daily close ($)",
        width: 400,
        height: 400,
        color: "steelblue"
      });
    
    </script>     -->
</body>


<script>

    // set the dimensions and margins of the graph
    const margin = {top: 10, right: 30, bottom: 30, left: 60},
        width = 460 - margin.left - margin.right,
        height = 400 - margin.top - margin.bottom;
    
    // append the svg object to the body of the page
    const svg = d3.select("#my_dataviz")
      .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", `translate(${margin.left},${margin.top})`);

    var d = [
       {
         "Date": 1641168000000,
         "Close": 182.01
       },
       {
         "Date": 1641254400000,
         "Close": 179.7
       },
       {
         "Date": 1641168000000,
         "Close": 174.92
       },
    ];

       d3.json(d,
    
      // When reading the csv, I must format variables:
      function(d){
        return { date : d3.timeParse("%s")(d.Date), value : d.Close }
      }).then(
    
      // Now I can use this dataset:
      function(data) {
    
        // Add X axis --> it is a date format
        const x = d3.scaleTime()
          .domain(d3.extent(data, function(d) { return d.date; }))
          .range([ 0, width ]);
        svg.append("g")
          .attr("transform", `translate(0, ${height})`)
          .call(d3.axisBottom(x));
    
        // Add Y axis
        const y = d3.scaleLinear()
          .domain([0, d3.max(data, function(d) { return +d.value; })])
          .range([ height, 0 ]);
        svg.append("g")
          .call(d3.axisLeft(y));
    
        // Add the line
        svg.append("path")
          .datum(data)
          .attr("fill", "none")
          .attr("stroke", "steelblue")
          .attr("stroke-width", 1.5)
          .attr("d", d3.line()
            .x(function(d) { return x(d.date) })
            .y(function(d) { return y(d.value) })
            )
    
    })
    </script>
</html>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拥抱没勇气 2025-02-20 14:45:09

我认为这里有两件事发生:

  1. 当您调用funciton d3.json(data,parsingFunction)时,D3期望数据输入是一系列元素,每个元素都包含所有信息该条目在您的基准中。 ParsingFunction在这里所做的是收到阵列中的每个元素,您必须编写如何处理数据的逻辑(在您的情况下,分析时代并保持近距离价格)。

因此,您应该做的是更改数据的发送方式,以便它是一个数组,每个条目是一个包含您相应时间和接近价格的对象,即:

    var d = [
       {
         "Date": 1641168000000,
         "Close": 182.01
       },
       {
         "Date": 1641254400000,
         "Close": 179.7
       },
       {
         "Date": 1641168000000,
         "Close": 174.92
       },
    ];
  1. 这实际上不是导致您的错误的原因,但是我会说它是因为我在您的代码中看到了它:d3.json返回a Promise 。这意味着您必须等待它到达。您可以使用var data =等待d3.son(..,..)明确地执行此操作,然后使用数据来完成您想要的任何事情。或者,指定回调函数(我相信这是您要做的)。为此,您还需要通过使用

通过这样做,您可以使用上面发送的代码正确解析数据:

d3.json(d, function(d){
    return { date : d3.timeParse("%s")(d.Date), value : d.Close }
    }
).then(function(data){
     // Use the data
})

I think there's two things happeningg here:

  1. When you call the funciton d3.json(data, parsingFunction), d3 is expecting the data entry to be an array of elements, where each element contains all the information for that entry in your datum. What the parsingFunction does here, is recievee each element in the array and you have to write the logic of how to treat your data (in your case, parse the epoch and keep the close price as it was).

Therefore, what you should do is change the way your data is being sent so that it's an array where each entry is an object containing thee corresponding time and close price, i.e:

    var d = [
       {
         "Date": 1641168000000,
         "Close": 182.01
       },
       {
         "Date": 1641254400000,
         "Close": 179.7
       },
       {
         "Date": 1641168000000,
         "Close": 174.92
       },
    ];
  1. This is actually not what's causing your mistake, but I'll say it because i saw it in your code: d3.json return a promise. Which means you have to wait for it to arrive. You can do this by either explicitely using var data = await d3.json(.., ..) and then using data to do whatever you want. OR, specify a callback function (which is what you were trying to do, I believe). To do that though, you need too specify that you want to call that function when the promise has resolved, by using a .then(callback) statement.

And by doing that, you can correctly parse the data with the code you sent above:

d3.json(d, function(d){
    return { date : d3.timeParse("%s")(d.Date), value : d.Close }
    }
).then(function(data){
     // Use the data
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文