使用Django后端将数据传递给D3.js
我想按照代码在这里。我对通过包含时期时间和收盘价的数据进行了略有更改。 代码
{% 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.
There seems to be an error passing data as seen in html file below
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这里有两件事发生:
d3.json(data,parsingFunction)
时,D3期望数据输入是一系列元素,每个元素都包含所有信息该条目在您的基准中。 ParsingFunction在这里所做的是收到阵列中的每个元素,您必须编写如何处理数据的逻辑(在您的情况下,分析时代并保持近距离价格)。因此,您应该做的是更改数据的发送方式,以便它是一个数组,每个条目是一个包含您相应时间和接近价格的对象,即:
d3.json
返回a Promise 。这意味着您必须等待它到达。您可以使用var data =等待d3.son(..,..)
明确地执行此操作,然后使用数据来完成您想要的任何事情。或者,指定回调函数(我相信这是您要做的)。为此,您还需要通过使用。
通过这样做,您可以使用上面发送的代码正确解析数据:
I think there's two things happeningg here:
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:
d3.json
return a promise. Which means you have to wait for it to arrive. You can do this by either explicitely usingvar 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: