正确返回获取的JSON,但无法将其放入Chart.JS

时间:2019-10-19 20:59:24

标签: javascript json rest chart.js fetch

我花了几个月时间学习网络开发人员,并试图通过做一些自己的项目来逃脱炼狱的教训。第一个是用于chrome扩展程序,可使用内容填充新标签页。在这种情况下,我希望该内容是一些加密价格图表,新闻文章和推文。这个问题是关于图表的。

我在这里设置了一个Codepen,其中包含该问题的所有代码:https://codepen.io/diggitydoge/pen/QWWGMNb

问题 我可以使用以下内容在控制台中看到我想要的数据(一个价格数组和一个时间数组),但不知道如何将其放入图表,也无法在此处找到任何指南或答案来清楚地说明我会:

const btcTime = async () => {
    const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=BTC&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
    const json = await response.json();
    const data = json.Data.Data
    const times = data.map(obj => obj.time)
    return times;
}

const btcPrice = async () => {
    const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=BTC&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
    const json = await response.json();
    const data = json.Data.Data
    const price = data.map(obj => obj.high)
    return {
      price
    }
}

async function btcTimeArray(){
  let results = await btcTime()
  
  console.log(results)
}

btcTimeArray() 

async function btcPriceArray(){
  let results = await btcPrice()
  
  console.log(results)
}

btcPriceArray() 


//---HELPER FUNCTIONS---//
  function checkStatus(response) {
    if (response.ok) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(new Error(response.statusText));
    }
  }

我让btcTime返回一个数组,让btcPrice返回一个包含数组的对象,只是为了看看这两种方法是否在下一步中有所不同:

将结果插入Chart.JS数据集中

这是可以正常工作的虚拟数据集的样子

labels: ['a', 'b', 'c', 'd', 'e', 'f'],
        datasets: [{
            label: 'Population',
            data: [
               610994,
               181045,
               153060,
               106519,
               105162,
               95072 
            ],

所以在这一点上,我...

  1. 在控制台中查看我的比特币价格和时间数据
  2. 需要知道如何存储/调用/定位/以何种方式将时间放入Chart.JS标签属性,并将价格放入数据集对象的Chart.js数据键中。

我尝试了类似的方法,但是它似乎没有用:

labels: btcTime,
        datasets: [{
            label: 'Population',
            data: btcPrice,

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

免责声明:我不太喜欢async-await-stuff。也许我有关此问题的代码太可怕了。请随时纠正我。

您必须等待获取请求及其数据来创建图表,或者必须在数据到达时进行更新。我使用了更新方法。 I put my code in a JSBin.

async function btcTimeArray() {
  let results = await btcTime()

  console.log(results)
  updateTime(results)
}

function updateTime(results) {
  btcChart.data.labels = results
  btcChart.update()
}

P.S .:您应该将我的代码与您的代码进行比较。我做了一些我认为更好的更改,但这可以是个人观点。这只是我的时间来处理您的代码,可能不是您想要的。我使用此网站来显示代码差异:https://www.diffchecker.com/diff

P.P.S:我会在当前悬停的索引处添加一条彩色的垂直线,而不是对悬停的数据使用大点,而是显示工具提示。

答案 1 :(得分:0)

感谢@headhunterkev!

我实际上是自己想出来的,但我必须检查一下您的出路!

这是我的做法:https://codepen.io/diggitydoge/pen/MWWmgJp

///  Calling API and modeling data for each chart ///
const btcData = async () => {
  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=BTC&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
  const json = await response.json();
  const data = json.Data.Data
  const times = data.map(obj => obj.time)
  const prices = data.map(obj => obj.high)
  return {
    times,
    prices
  }
}


const cosmosData = async () => {
  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=ATOM&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
  const json = await response.json();
  const data = json.Data.Data
  const times = data.map(obj => obj.time)
  const prices = data.map(obj => obj.high)
  return {
    times,
    prices
  }
}


const ethereumData = async () => {
  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=ETH&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
  const json = await response.json();
  const data = json.Data.Data
  const times = data.map(obj => obj.time)
  const prices = data.map(obj => obj.high)
  return {
    times,
    prices
  }
}


const checker = async () => {
  //enter API URL into fetch to see data in console
  const response = await fetch('https://min-api.cryptocompare.com/data/v2/histominute?fsym=BTC&tsym=USD&limit=119&api_key=0646cc7b8a4d4b54926c74e0b20253b57fd4ee406df79b3d57d5439874960146');
  const json = await response.json();
  const data = json.Data.Data
  return {
   data
  }
}


/// console.log functions to check data ///
async function btcDataCheck() {
  let results = await btcData()

  console.log(results)
}
btcDataCheck()

async function checkerFunction() {
  let results = await checker()

  console.log(results)
}
checkerFunction()

/// Error handling ///
function checkStatus(response) {
  if (response.ok) {
    return Promise.resolve(response);
  } else {
    return Promise.reject(new Error(response.statusText));
  }
}



/// Charts ///
let createBtcChart
let createCosmosChart
let createethereumChart

async function printBtcChart() {
  let { times, prices } = await btcData()

  let btcChart = document.getElementById('btcChart').getContext('2d');

  let gradient = btcChart.createLinearGradient(0, 0, 0, 400);

  gradient.addColorStop(0, 'rgba(247,147,26,.5)');
  gradient.addColorStop(.425, 'rgba(255,193,119,0)');

  Chart.defaults.global.defaultFontFamily = 'Red Hat Text';
  Chart.defaults.global.defaultFontSize = 12;

  createBtcChart = new Chart(btcChart, {
    type: 'line',
    data: {
      labels: times,
      datasets: [{
        label: '$',
        data: prices,
        backgroundColor: gradient,
        borderColor: 'rgba(247,147,26,1)',
        borderJoinStyle: 'round',
        borderCapStyle: 'round',
        borderWidth: 3,
        pointRadius: 0,
        pointHitRadius: 10,
        lineTension: .2,
      }]
    },

    options: {
      title: {
        display: false,
        text: 'Heckin Chart!',
        fontSize: 35
      },

      legend: {
        display: false
      },

      layout: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      },

      scales: {
        xAxes: [{
          display: false,
          gridLines: {}
        }],
        yAxes: [{
          display: false,
          gridLines: {}
        }]
      },

      tooltips: {
        callbacks: {
          //This removes the tooltip title
          title: function() {}
       },
        //this removes legend color
        displayColors: false,
        yPadding: 10,
        xPadding: 10,
        position: 'nearest',
        caretSize: 10,
        backgroundColor: 'rgba(255,255,255,.9)',
        bodyFontSize: 15,
        bodyFontColor: '#303030' 
      }
    }
  });
}



async function printCosmosChart() {
  let { times, prices } = await cosmosData()

  let cosmosChart = document.getElementById('cosmosChart').getContext('2d');

  let gradient = cosmosChart.createLinearGradient(0, 0, 0, 400);

  gradient.addColorStop(0, 'rgba(27,30,54,.5)');
  gradient.addColorStop(.425, 'rgba(46,49,72,0)');

  Chart.defaults.global.defaultFontFamily = 'Red Hat Text';
  Chart.defaults.global.defaultFontSize = 12;

  createCosmosChart = new Chart(cosmosChart, {
    type: 'line',
    data: {
      labels: times,
      datasets: [{
        label: "",
        data: prices,
        backgroundColor: gradient,
        borderColor: 'rgba(46,49,72,1)',
        borderJoinStyle: 'round',
        borderCapStyle: 'round',
        borderWidth: 3,
        pointRadius: 0,
        pointHitRadius: 10,
        lineTension: .2,
      }]
    },

    options: {
      title: {
        display: false,
        text: 'Heckin Chart!',
        fontSize: 35
      },

      legend: {
        display: false
      },

      layout: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      },

      scales: {
        xAxes: [{
          display: false,
          gridLines: {}
        }],
        yAxes: [{
          display: false,
          gridLines: {}
        }]
      },

      tooltips: {
        callbacks: {
          //This removes the tooltip title
          title: function() {}
       },
        //this removes legend color
        displayColors: false,
        yPadding: 10,
        xPadding: 10,
        position: 'nearest',
        caretSize: 10,
        backgroundColor: 'rgba(255,255,255,.9)',
        bodyFontSize: 15,
        bodyFontColor: '#303030' 
      }
    }
  });
}


async function printEthereumChart() {
  let { times, prices } = await ethereumData()

  let ethereumChart = document.getElementById('ethereumChart').getContext('2d');

  let gradient = ethereumChart.createLinearGradient(0, 0, 0, 400);

  gradient.addColorStop(0, 'rgba(78,56,216,.5)');
  gradient.addColorStop(.425, 'rgba(118,106,192,0)');

  Chart.defaults.global.defaultFontFamily = 'Red Hat Text';
  Chart.defaults.global.defaultFontSize = 12;

  createEthereumChart = new Chart(ethereumChart, {
    type: 'line',
    data: {
      labels: times,
      datasets: [{
        label: '$',
        data: prices,
        backgroundColor: gradient,
        borderColor: 'rgba(118,106,192,1)',
        borderJoinStyle: 'round',
        borderCapStyle: 'round',
        borderWidth: 3,
        pointRadius: 0,
        pointHitRadius: 10,
        lineTension: .2,
      }]
    },

    options: {
      title: {
        display: false,
        text: 'Heckin Chart!',
        fontSize: 35
      },

      legend: {
        display: false
      },

      layout: {
        padding: {
          left: 0,
          right: 0,
          top: 0,
          bottom: 0
        }
      },

      scales: {
        xAxes: [{
          display: false,
          gridLines: {}
        }],
        yAxes: [{
          display: false,
          gridLines: {}
        }]
      },

      tooltips: {
        callbacks: {
          //This removes the tooltip title
          title: function() {}
       },
        //this removes legend color
        displayColors: false,
        yPadding: 10,
        xPadding: 10,
        position: 'nearest',
        caretSize: 10,
        backgroundColor: 'rgba(255,255,255,.9)',
        bodyFontSize: 15,
        bodyFontColor: '#303030' 
      }
    }
  });
}

async function updateEthereumPrice() {
  let { times, prices } = await ethereumData()
  let currentPrice = prices[prices.length-1].toFixed(2);

  document.getElementById("ethPrice").innerHTML = "$" + currentPrice;
}

async function updateCosmosPrice() {
  let { times, prices } = await cosmosData()
  let currentPrice = prices[prices.length-1].toFixed(2);

  document.getElementById("atomPrice").innerHTML = "$" + currentPrice;
}

async function updateBitcoinPrice() {
  let { times, prices } = await btcData()
  let currentPrice = prices[prices.length-1].toFixed(2);

  document.getElementById("btcPrice").innerHTML = "$" + currentPrice;
}

updateEthereumPrice()
updateCosmosPrice()
updateBitcoinPrice()

printBtcChart()
printCosmosChart()
printEthereumChart()
$card-text-color: #303030;

///  FONTS  ///
h1 {
    font-size: 1.5em;
}

h2 {
    font-size: 1.25em;
}

h1, 
h2, 
p {
    font-family: 'Red Hat Text', sans-serif;
    color: $card-text-color;
}

/// Card Container ///
.container {
    display: flex;
    justify-content: center;
}


/// Cards ///
cards {
    width: 90%;
    display: inline-flex;
    flex-direction: row;
    justify-content: space-between;
    flex-wrap: wrap;
    padding-top: 30px;
    padding-bottom: 30px;
}

.btc,
.cosmos,
.ethereum {
    display: grid;
    max-width: 300px;
    min-width: 250px;
    grid-template-columns: 1fr;
    grid-template-rows: minmax(50px, 60px) 1fr;
    grid-template: 
        "info"
        "chart";
    border-radius: 30px;
}

.btc {
    box-shadow: 10px 10px 20px 1px rgba(247,147,26,.15);
}

.cosmos {
    box-shadow: 10px 10px 20px 1px rgba(46,49,72,.15);
}

.ethereum {
    box-shadow: 10px 10px 20px 1px rgba(78,56,216,.15);
}

.asset-info {
    grid-area: info;
    display: inline-flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 5% 0 5%;
}

.title {
    display: inline-flex;
}

card h1 {
    margin-left: 10px;
}

// .asset-price {

// }


/// Charts ///
#btcChart,
#cosmosChart,
#ethereumChart {
    grid-area: chart;
    border-radius: 0px 0px 30px 30px;
    margin-top: auto;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.js"></script>
    <link href="https://fonts.googleapis.com/css?family=Red+Hat+Text:400,500&display=swap" rel="stylesheet">
    <title>Issa Chart!</title>
</head>
<body>
  <container class="container">
    <cards class="cards">
        <bitcoin style="width: 30%" class="btc">
            <card class="asset-info">
                <div class="title">
                    <img src="https://s3.us-east-2.amazonaws.com/nomics-api/static/images/currencies/btc.svg" width="15%"> 
                    <h1>Bitcoin</h1>
                </div>
                <div class="details">
                    <h2 class="asset-price" id="btcPrice"></h2>
                </div>
            </card>
            <canvas id="btcChart"></canvas>
        </bitcoin>

        <cosmos style="width: 30%" class="cosmos">
            <card class="asset-info">
                <div class="title">
                    <img src="https://s3.us-east-2.amazonaws.com/nomics-api/static/images/currencies/atm.svg" width="15%"> 
                    <h1>Cosmos</h1>
                </div>
                <div class="details">
                    <h2 class="asset-price" id="atomPrice"></h2>
                </div>
            </card>
            <canvas id="cosmosChart"></canvas>
        </cosmos>

        <ethereum style="width: 30%" class="ethereum">
            <card class="asset-info">
                <div class="title">
                    <img src="https://s3.us-east-2.amazonaws.com/nomics-api/static/images/currencies/eth.svg" width="10%"> 
                    <h1>Ethereum</h1>
                </div>
                <div class="details">
                    <h2 class="asset-price" id="ethPrice"></h2>
                </div>
            </card>
            <canvas id="ethereumChart"></canvas>
        </ethereum>
    </cards>
  </container>
</body>
<script src="app.js"></script>
</html>