How to Create Charts with Bitquery And Chart.js
Table of Contents
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
andweekAgo
variable into the query. Can be as many days as you want, just change theweekAgo
arguments
For react you can check:
References
If you have any specific problem with bitquery or chart.js, maybe these links will help you: