How to Create Charts with Bitquery And Chart.js

How to Create Charts with Bitquery And Chart.js

Table of Contents

  1. What Will We Learn?
  2. Preparing Our Query
  3. Simple Use Of chart.js with Bitquery
  4. A More Complex Use
  5. References

What Will We Learn?

In this article we will learn how to get OHLC data with bitquery and process it with chart.js and chartjs-chart-financial.

OHLC stand for Open, High, Low, Close with that we will be able to represent the data in a chart.

Requirements:

  • Bitquery Account, API Key
  • Know JS and a bit of HTML
  • Browser
  • OHLC Query

Preparing Our Query

Before implementing any code we will need to test our query in Bitquery IDE, in this article we will use the following query:

{
			ethereum(network: bsc) {
			  dexTrades(options: {limit: 5, asc: "timeInterval.hour"}, 
				date: {since:"2022-08-09", till: "2022-08-10"}
				exchangeName: {in:["Pancake","Pancake v2"]}, 
				baseCurrency: {is: "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"}, 
				quoteCurrency: {is: "0xe9e7cea3dedca5984780bafc599bd69add087d56"}) {
				
				
				timeInterval {
				  hour(count: 1)
				}
		  
				baseCurrency {
				  symbol
				  address
				}
				baseAmount
				quoteCurrency {
				  symbol
				  address
				}
				quoteAmount
				
				trades: count
				quotePrice
				
				maximum_price: quotePrice(calculate: maximum)
				minimum_price: quotePrice(calculate: minimum)
				
				open_price: minimum(of: block get: quote_price)
				close_price: maximum(of: block get: quote_price)
				
			
			  }
			}
		  }

This query basically what it does is to obtain the OHLC in the WBNB/BUSD pair in an interval of one hour, with the limit we will obtain a maximum of 30 candles between the dates 2022-08-09 and 2022-08-10.

The output is something like this:

{
  "ethereum": {
    "dexTrades": [
      {
        "timeInterval": {
          "hour": "2022-08-09 00:00:00"
        },
        "baseCurrency": {
          "symbol": "WBNB",
          "address": "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"
        },
        "baseAmount": 4281.959399497331,
        "quoteCurrency": {
          "symbol": "BUSD",
          "address": "0xe9e7cea3dedca5984780bafc599bd69add087d56"
        },
        "quoteAmount": 1393152.0249397147,
        "trades": 2027,
        "quotePrice": 325.35386138954516,
        "maximum_price": 326.9902840549255,
        "minimum_price": 323.73982316156366,
        "open_price": "325.43478999787095",
        "close_price": "325.98389277785907"
      },
      {
        "timeInterval": {
          "hour": "2022-08-09 01:00:00"
        },
        "baseCurrency": {
          "symbol": "WBNB",
          "address": "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"
        },
        "baseAmount": 2465.0520510354845,
        "quoteCurrency": {
          "symbol": "BUSD",
          "address": "0xe9e7cea3dedca5984780bafc599bd69add087d56"
        },
        "quoteAmount": 798432.5928199171,
        "trades": 1848,
        "quotePrice": 323.90090606181025,
        "maximum_price": 326.1928744596275,
        "minimum_price": 322.37227969954904,
        "open_price": "325.99016583086626",
        "close_price": "322.72763793369444"
      }
    ]
  }
}

The limit in this case was two, so that the example would not be so long

Simple Use Of chart.js with Bitquery

This chart is very simple, it is ideal for those who want to display data with few lines of code, it is very easy to implement.

Let’s start with the code

HTML - index.html:

<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Financial | Chart.js</title>
		<script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
		<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
		<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
		<script src="https://www.chartjs.org/chartjs-chart-financial/chartjs-chart-financial.js"></script>
		<link rel="stylesheet" type="text/css" href="style.css">
	</head>
	<body>
		<h1>Chart.js - Bitquery</h1>
		<div style="width:1000px">
			<canvas id="chart"></canvas>
		</div>
		<button id="update-data">Update Data</button>
		<script type="text/javascript" src="script.js"></script>
	</body>
</html>

Nothing relevant, we will import the css, our script and some modules.

CSS - style.css

* {
	font-family: Sans-Serif;
}

h1 {
	font-size: 1.5em;
}

h2 {
	font-size: 1.25em;
}

JS - script.js

let ctx = document.getElementById('chart').getContext('2d');
ctx.canvas.width = 800;
ctx.canvas.height = 400;

let chart = new Chart(ctx, {
	type: 'candlestick',
	data: {
		datasets: [{
			label: 'Bitquery - Chart.js',
			data: ''
		}]
	}
});

const getOHLC = () => {

	fetch('https://graphql.bitquery.io/', {
	  method: 'POST',
  
	  headers: {
		"Content-Type": "application/json",
		'X-API-KEY': "API-KEY",
	  },
  
	  body: JSON.stringify({
		query: `{
			ethereum(network: bsc) {
			  dexTrades(options: {limit: 30, asc: "timeInterval.hour"}, 
				date: {since:"2022-08-09", till: "2022-08-10"}
				exchangeName: {in:["Pancake","Pancake v2"]}, 
				baseCurrency: {is: "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c"}, 
				quoteCurrency: {is: "0xe9e7cea3dedca5984780bafc599bd69add087d56"}) {
				
				timeInterval {
				  hour(count: 1)
				}
		  
				baseCurrency {
				  symbol
				  address
				}
				baseAmount
				quoteCurrency {
				  symbol
				  address
				}
				quoteAmount
				
				trades: count
				quotePrice
				
				maximum_price: quotePrice(calculate: maximum)
				minimum_price: quotePrice(calculate: minimum)
				
				open_price: minimum(of: block get: quote_price)
				close_price: maximum(of: block get: quote_price)
				
			  }
			}
		  }
  `
	  })
	}).then(request => {
		request.json().then(data => {
			//data.data.ethereum.dexTrades
			let ohlc = data.data.ethereum.dexTrades.map(item => {
				return {
				  x: new Date(item.timeInterval.hour).getTime(),
				  o: parseInt(item.open_price),
				  h: parseInt(item.maximum_price),
				  l: parseInt(item.minimum_price),
				  c: parseInt(item.close_price)
				};
			  });
			  console.log(chart)
			  chart.config.data.datasets = [
				{
					label: 'WBNB - BUSD 1h',
					data: ohlc
				}	
			];

			chart.update();

		})
	})
  }


document.getElementById('update-data').addEventListener('click', getOHLC);

What do we essentially have to change here?

We have to change the API Key and the query to our needs.

Basically what this code does is to make the POST request to Bitquery to get the data and put it in the chart.

fetch data --> iterates through the output --> creates a new array with objects that have x, o, h, l, c --> sets the data in the chart

The script is very simple (and maybe not even optimal) but it will allow you to play with the chart.js module to create your own charts in a simple way.

A More Complex Use

This module is very flexible and allows you to make modifications very easily. However, adding certain functionalities such as zooming, moving in the chart, can be difficult and incompatible in some browsers (according to what I have tested).

To set the dates automatically you will see the following function that will allow you to get the dates in ISO8601 to work with bitquery:

/**
 * Function to add or subtract days
 * @param  {Date} startDate Date object JS
 * @param  {Number} days Days to be added or subtracted
 * @param  {bool}  add Add or subtract arg
 * @return {string}      Return string with "yyyy-mm-dd" style
 */
const dateFunc = (startDate, days, add) => {
    if (add) {
      return (new Date(new Date().setDate(startDate.getDate() + days))).toISOString().split('T')[0];
    } else {
      return (new Date(new Date().setDate(startDate.getDate() - days))).toISOString().split('T')[0];
    }
  }
  
  let today = new Date();
  let todayFormatted = today.toISOString().split('T')[0];
  let weekAgo = dateFunc(today, 7, false)

You will need to put todayFormatted and weekAgo variable into the query. Can be as many days as you want, just change the weekAgo arguments

For react you can check:

References

If you have any specific problem with bitquery or chart.js, maybe these links will help you:

chartjs-chart-financial

Chart.js

Bitquery Official Page

Bitquery Forum

Bitquery on Telegram