如何根据d3.js中api的json数据进行编码? [英] how to code according to json data from api in d3.js?

查看:78
本文介绍了如何根据d3.js中api的json数据进行编码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个初学者,我正在学习d3.js,但是我无法弄清楚如何根据api中json格式的数据绘制图形或代码. 这是我尝试过的事情之一,但是我无法根据另一个api中的新数据进行更改.有谁能够帮我? 我在哪里进行更改?

I am a beginner, I am learning d3.js but I am unable to figure out on how to draw a graph or code according to the data is in json format from api. Here is one of the things I have tried but I am unable to change it according to the new data in another api. Can anybody help me? where do I make the changes?

<!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

I get the correct output for the above mentioned code but I want to change the api to https://blockchain.info/ticker

在哪里可以进行更改以使其起作用?

where could I make the changes to make it work?

推荐答案

因为这是比特币与其他硬币相比的转换率,所以将它们全部绘制在一张图中是没有意义的. JPY会压碎其他所有条形.

Because it is the convertion rate of bitcoin compared to other coins it does not make sense to plot them all in one graph. The JPY would crush all the other bars.

如果给定当前汇率,只是使用转换方式,为什么要使用不同的硬币购买/出售比特币.

Why buy/sell bitcoin using different coins if they just are conversions given the current rate.

如果绘制单个硬币值,则会得到下图

If you draw a single coin values you get the following graph

<!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>

也没有用.因为所有变化都在前几个像素中.

Also not useful. Because all the variation is in the top few pixels.

您需要的是一种随着时间的推移记录JSON文件中与原始数据集相似的特定硬币和图形的值的方法.

What you need is a way to record the values from the JSON file over time for a particular coin and graph that like your original dataset.

可以通过每隔x分钟获取一次数据,然后使用enter/exit/remove data()调用修改图形,或者像这样重新绘制图形来完成.

Can be done by fetching the data every x minutes and then modify the graph with the enter/exit/remove data() call or just redraw the graph like this.

DEBUG 部分之前放置注释,以获取真实数据.并取消注释以下行

Place comments before the DEBUG sections for the real data. And uncomment the following line

//setInterval(getData, 5 * 60 * 1000);

在这里,我每5秒钟为演示生成一次虚拟数据.

Here I generate dummy data every 5 seconds for the demo.

为防止内存不足,data的长度限制为1000个样本.

To prevent out of memory data length is limited to 1000 samples.

修改

现在它在x轴上显示样品的日期.

It now shows the date of the sample on the x-axis.

<!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>

这篇关于如何根据d3.js中api的json数据进行编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆