我是一个初学者,我正在学习d3.js,但是我无法弄清楚如何根据api中json格式的数据绘制图形或代码。 这是我尝试过的事情之一,但是我无法根据另一个api中的新数据进行更改。有谁能够帮助我? 我在哪里进行更改?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>
</head>
<style>
body {
text-align: center;
margin-top: 5em;
background-color: #74b9ff;
}
h1 {
color: snow;
}
</style>
<body>
<h1>Bitcoin Prices in U.S. Dollars</h1>
<script>
var url = "https://min-api.cryptocompare.com/data/histoday?fsym=BTC&tsym=USD&limit=200&aggregate=3&e=CCCAGG";
d3.json(url).get(function(error, d) {
var data = d.Data;
data.forEach(function(d){ d.time = new Date(d.time * 1000) });
if (error) throw error;
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleTime()
.range([0, width])
var y = d3.scaleLinear()
.range([height, 0]);
var line = d3.line()
.x(function(d) { return x(d.time); })
.y(function(d) { return y(d.close); });
x.domain(d3.extent(data, function(d) { return d.time; }));
y.domain(d3.extent(data, function(d) { return d.close; }));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.attr("stroke-width", 2)
.attr("fill", "none")
.style("font-size",".8em");
g.append("g")
.call(d3.axisLeft(y))
.attr("stroke-width", 2)
.style("font-size",".8em")
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 20)
.attr("text-anchor", "end")
.attr("font-size", "1.2em")
.text("Price ($)")
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "#ffeaa7")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 2)
.attr("d", line);
});
</script>
</body>
</html>
我获得了上述代码的正确输出,但是我想将api更改为 https://blockchain.info/ticker
在哪里可以进行更改以使其起作用?
答案 0 :(得分:0)
因为是比特币与其他硬币的兑换率,所以将它们全部绘制在一张图中没有意义。 JPY
会压碎所有其他条。
如果只是以当前汇率给出的转换,为什么要使用不同的硬币购买/出售比特币。
如果绘制单个硬币值,则会得到下图
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("https://blockchain.info/ticker", function(error, data) {
if (error) throw error;
data = data.EUR;
var keys = ["15m", "last", "buy", "sell"];
x.domain(keys);
y.domain([0, d3.max(keys, function(k) { return data[k]; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("price");
g.selectAll(".bar")
.data(keys)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(k) { return x(k); })
.attr("y", function(k) { return y(data[k]); })
.attr("width", x.bandwidth())
.attr("height", function(k) { return height - y(data[k]); });
});
</script>
也没有用。因为所有变化都在前几个像素中。
您需要的是一种方法,可以随着时间的推移记录JSON文件中与原始数据集相似的特定硬币和图形的值。
可以通过每隔x分钟获取一次数据,然后使用enter / exit / remove data()
调用来修改图形,或者像这样重新绘制图形来完成。
在调试部分之前放置注释,以获取真实数据。并取消注释以下行
//setInterval(getData, 5 * 60 * 1000);
在这里,我每5秒钟为演示生成一次虚拟数据。
为防止内存不足data
,长度不得超过1000个样本。
修改
现在它在x轴上显示样品的日期。
<!DOCTYPE html>
<style>
.p15m { stroke: steelblue;}
.pbuy { stroke: red;}
.plast { stroke: green;}
.psell { stroke: orange;}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var data = [];
var x = d3.scaleTime()
.range([0, width]);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var line = d3.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });
function getData() {
//DEBUG
data.push( {"15m": Math.random()*100 + 100, "last": Math.random()*100 + 100, "buy": Math.random()*100 + 100, "sell": Math.random()*100 + 100, "date": new Date() } );
updateGraph();
return;
// DEBUG END
d3.json("https://blockchain.info/ticker", function(error, dataNew) {
if (error) throw error;
var d = dataNew.EUR;
d.date = new Date();
data.push();
if (data.length > 1000) data = data.shift();
updateGraph();
});
}
getData();
setTimeout(getData, 5000);
//DEBUG
setInterval(getData, 5 * 1000);
//DEBUG END
//setInterval(getData, 5 * 60 * 1000);
function updateGraph() {
if (data.length < 2) return;
svg.select("g").remove(); // clean the graph
var keys = ["15m", "last", "buy", "sell"];
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(d3.extent(data, d => d.date));
var flat = [];
data.map( d => keys.map(k => d[k]) ).forEach(e => { flat = flat.concat(e); });
y.domain(d3.extent(flat , function(d) { return d; }));
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.select(".domain")
.remove();
g.append("g")
.call(d3.axisLeft(y))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Price (EUR)");
g.selectAll("g.key")
.data(keys)
.enter()
.append("g")
.attr("class", d => "key p" + d )
.append("path")
.datum(k => data.map( (d, i) => [d.date, d[k]]))
.attr("fill", "none")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
}
</script>