Передача данных в D3.js с помощью Django Backend

Я хочу построить линейный график, следуя коду здесь. Я немного изменил передаваемые данные, добавив в них время эпохи и цену закрытия. Ниже приведен код

{% 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>

Я не могу сгенерировать график. Я приложил снимок экрана консоли ниже.

enter image description here

Похоже, произошла ошибка при передаче данных, как показано в html-файле ниже

enter image description here

Я не могу понять, как передать данные, как правильно это сделать?

Я думаю, что здесь происходят две вещи:

  1. Когда вы вызываете функцию d3.json(data, parsingFunction), d3 ожидает, что данные будут представлены в виде массива элементов, где каждый элемент содержит всю информацию для этой записи в данных. Функция парсинга делает здесь то, что получает каждый элемент в массиве, и вы должны написать логику того, как обработать ваши данные (в вашем случае, разобрать эпоху и сохранить цену закрытия как она была).
  2. .

Следовательно, вы должны изменить способ отправки данных так, чтобы это был массив, где каждая запись является объектом, содержащим соответствующее время и цену закрытия, т.е.:

    var d = [
       {
         "Date": 1641168000000,
         "Close": 182.01
       },
       {
         "Date": 1641254400000,
         "Close": 179.7
       },
       {
         "Date": 1641168000000,
         "Close": 174.92
       },
    ];
  1. На самом деле это не то, что вызывает вашу ошибку, но я скажу это, потому что увидел это в вашем коде: d3.json return a promise. Это означает, что вы должны ждать, пока оно придет. Вы можете сделать это, либо явно используя var data = await d3.json(.., ..) и затем используя данные, чтобы сделать все, что вы хотите. ИЛИ, указать функцию обратного вызова (что вы и пытались сделать, я полагаю). Однако для этого вам нужно указать, что вы хотите вызвать эту функцию, когда обещание разрешится, используя оператор .then(callback).

Сделав это, вы сможете правильно разобрать данные с помощью кода, который вы отправили выше:

d3.json(d, function(d){
    return { date : d3.timeParse("%s")(d.Date), value : d.Close }
    }
).then(function(data){
     // Use the data
})
Вернуться на верх