Reputation: 23
I am using vite and react to build a node.js program where I am collecting data from coinbase exchange API to rebuild a dashboard. This is my code, where the API returns: an array of arrays of the form [timestamp, price_low, price_high, price_open, price_close].
import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { getProductCandles } from "../api/api";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
TimeScale,
Tooltip,
Title,
Legend,
elements,
} from "chart.js";
import {
CandlestickController,
CandlestickElement,
} from "chartjs-chart-financial";
import { Chart } from "react-chartjs-2";
import "chartjs-adapter-date-fns";
// Register necessary components for the candlestick chart
ChartJS.register(
CategoryScale,
LinearScale,
TimeScale,
Tooltip,
Title,
Legend,
CandlestickController,
CandlestickElement
);
const ProductPage = () => {
const { productId } = useParams();
const [data, setData] = useState([0, 0, 0, 0, 0]);
const [granularity, setGranularity] = useState(3600);
useEffect(() => {
const fetchData = async () => {
const end = new Date().toISOString();
const start = new Date(
new Date().setDate(new Date().getDate() - 1)
).toISOString();
try {
const candleData = await getProductCandles(
productId,
granularity,
start,
end
);
setData(candleData);
} catch (error) {
console.error("Error fetching candle data:", error);
}
};
fetchData(); // Call the fetchData function
}, [productId, granularity]);
const array = data.map((d) => ({
x: new Date(d[0] * 1000),
l: d[1],
h: d[2],
o: d[3],
c: d[4],
}));
console.log(data);
console.log("array = ", array);
const chartData = {
datasets: [
{
label: "Price",
data: array,
borderColor: "rgba(75, 192, 192, 1)",
borderWidth: 1,
fill: false,
barWidth: 0.8,
},
],
};
const options = {
scales: {
x: {
title: {
display: true,
text: "Time",
},
type: "time",
time: {
unit: "hour",
stepSize: 1,
displayFormats: {
hour: "MMM DD",
},
},
},
y: {
beginAtZero: false,
},
},
};
return (
<div
className="page"
style={{ width: "100vw", height: "80vh", margin: "0 auto" }}
>
<h1 className="text-2xl font-bold">Stock Prices</h1>
<div style={{ height: "100%", width: "100%" }}>
<Chart type="candlestick" data={chartData} options={options} />
</div>
</div>
);
};
export default ProductPage;
The chart ends up looking like this
API returns:
Array(24)
0: (6) [1717596000, 0.7071, 0.7129, 0.7102, 0.7127, 205255.5]
1: (6) [1717592400, 0.7088, 0.713, 0.7123, 0.71, 179778.4]
2: (6) [1717588800, 0.7112, 0.7149, 0.7145, 0.7122, 204489.5]
3: (6) [1717585200, 0.7126, 0.7149, 0.7133, 0.7144, 85185.7]
4: (6) [1717581600, 0.7124, 0.7146, 0.714, 0.7131, 178411.5]
5: (6) [1717578000, 0.7124, 0.716, 0.7143, 0.7137, 207845.7]
6: (6) [1717574400, 0.714, 0.7182, 0.7181, 0.7144, 172882.4]
7: (6) [1717570800, 0.7169, 0.7202, 0.7193, 0.7175, 137006.6]
8: (6) [1717567200, 0.7166, 0.7215, 0.7171, 0.7196, 319441.8]
9: (6) [1717563600, 0.7136, 0.7174, 0.7171, 0.717, 170088.6]
10: (6) [1717560000, 0.714, 0.7178, 0.7174, 0.7171, 195534.8]
11: (6) [1717556400, 0.715, 0.7178, 0.7152, 0.7171, 122120.9]
12: (6) [1717552800, 0.7142, 0.7185, 0.7184, 0.7152, 208780.8]
13: (6) [1717549200, 0.7154, 0.7199, 0.7163, 0.7184, 274857.9]
14: (6) [1717545600, 0.7144, 0.7183, 0.7155, 0.7168, 75366.8]
15: (6) [1717542000, 0.7136, 0.716, 0.7146, 0.7152, 106694.8]
16: (6) [1717538400, 0.7122, 0.7153, 0.7145, 0.7146, 137940.1]
17: (6) [1717534800, 0.7116, 0.7147, 0.7139, 0.7144, 147603.1]
18: (6) [1717531200, 0.7114, 0.7146, 0.7139, 0.7137, 297552.5]
19: (6) [1717527600, 0.7094, 0.7168, 0.7168, 0.7139, 280444.1]
20: (6) [1717524000, 0.7152, 0.7195, 0.7156, 0.7164, 158904.1]
21: (6) [1717520400, 0.7116, 0.7159, 0.7137, 0.7152, 206150.3]
22: (6) [1717516800, 0.7118, 0.715, 0.7136, 0.7137, 189808.8]
23: (6) [1717513200, 0.7098, 0.7157, 0.7116, 0.7134, 247950.2]
length: 24
Mapping function output:
array = Array(24)
0: {x: Wed Jun 05 2024 15:00:00 GMT+0100 (British Summer Time), l: 0.7071, h: 0.7129, o: 0.7102, c: 0.7127}
1: {x: Wed Jun 05 2024 14:00:00 GMT+0100 (British Summer Time), l: 0.7088, h: 0.713, o: 0.7123, c: 0.71}
2: {x: Wed Jun 05 2024 13:00:00 GMT+0100 (British Summer Time), l: 0.7112, h: 0.7149, o: 0.7145, c: 0.7122}
3: {x: Wed Jun 05 2024 12:00:00 GMT+0100 (British Summer Time), l: 0.7126, h: 0.7149, o: 0.7133, c: 0.7144}
4: {x: Wed Jun 05 2024 11:00:00 GMT+0100 (British Summer Time), l: 0.7124, h: 0.7146, o: 0.714, c: 0.7131}
5: {x: Wed Jun 05 2024 10:00:00 GMT+0100 (British Summer Time), l: 0.7124, h: 0.716, o: 0.7143, c: 0.7137}
6: {x: Wed Jun 05 2024 09:00:00 GMT+0100 (British Summer Time), l: 0.714, h: 0.7182, o: 0.7181, c: 0.7144}
7: {x: Wed Jun 05 2024 08:00:00 GMT+0100 (British Summer Time), l: 0.7169, h: 0.7202, o: 0.7193, c: 0.7175}
8: {x: Wed Jun 05 2024 07:00:00 GMT+0100 (British Summer Time), l: 0.7166, h: 0.7215, o: 0.7171, c: 0.7196}
9: {x: Wed Jun 05 2024 06:00:00 GMT+0100 (British Summer Time), l: 0.7136, h: 0.7174, o: 0.7171, c: 0.717}
10: {x: Wed Jun 05 2024 05:00:00 GMT+0100 (British Summer Time), l: 0.714, h: 0.7178, o: 0.7174, c: 0.7171}
11: {x: Wed Jun 05 2024 04:00:00 GMT+0100 (British Summer Time), l: 0.715, h: 0.7178, o: 0.7152, c: 0.7171}
12: {x: Wed Jun 05 2024 03:00:00 GMT+0100 (British Summer Time), l: 0.7142, h: 0.7185, o: 0.7184, c: 0.7152}
13: {x: Wed Jun 05 2024 02:00:00 GMT+0100 (British Summer Time), l: 0.7154, h: 0.7199, o: 0.7163, c: 0.7184}
14: {x: Wed Jun 05 2024 01:00:00 GMT+0100 (British Summer Time), l: 0.7144, h: 0.7183, o: 0.7155, c: 0.7168}
15: {x: Wed Jun 05 2024 00:00:00 GMT+0100 (British Summer Time), l: 0.7136, h: 0.716, o: 0.7146, c: 0.7152}
16: {x: Tue Jun 04 2024 23:00:00 GMT+0100 (British Summer Time), l: 0.7122, h: 0.7153, o: 0.7145, c: 0.7146}
17: {x: Tue Jun 04 2024 22:00:00 GMT+0100 (British Summer Time), l: 0.7116, h: 0.7147, o: 0.7139, c: 0.7144}
18: {x: Tue Jun 04 2024 21:00:00 GMT+0100 (British Summer Time), l: 0.7114, h: 0.7146, o: 0.7139, c: 0.7137}
19: {x: Tue Jun 04 2024 20:00:00 GMT+0100 (British Summer Time), l: 0.7094, h: 0.7168, o: 0.7168, c: 0.7139}
20: {x: Tue Jun 04 2024 19:00:00 GMT+0100 (British Summer Time), l: 0.7152, h: 0.7195, o: 0.7156, c: 0.7164}
21: {x: Tue Jun 04 2024 18:00:00 GMT+0100 (British Summer Time), l: 0.7116, h: 0.7159, o: 0.7137, c: 0.7152}
22: {x: Tue Jun 04 2024 17:00:00 GMT+0100 (British Summer Time), l: 0.7118, h: 0.715, o: 0.7136, c: 0.7137}
23: {x: Tue Jun 04 2024 16:00:00 GMT+0100 (British Summer Time), l: 0.7098, h: 0.7157, o: 0.7116, c: 0.7134}
length: 24
I've tried changing the options of the chart such as bar width but it doesn’t change the way the graph looks. Is this an issue with the data or my code for the chart? I would like the graph to look like a traditional candlestick chart with the candlesticks being thin enough that you can tell them apart.
Here is an example:
Upvotes: 1
Views: 165
Reputation: 8870
The problem with your data is that the financial plugin requires numerical values for x
; it doesn't accept neither
Date
objects nor date strings for time, but only timestamps, see for instance this line on their example file.
So, in order to start having right time values on the x axis you have to replace x: new Date(d[0] * 1000),
with just
x: d[0] * 1000
, see the snippet below, with that change.
const data = [[1717596000, 0.7071, 0.7129, 0.7102, 0.7127, 205255.5],
[1717592400, 0.7088, 0.713, 0.7123, 0.71, 179778.4],
[1717588800, 0.7112, 0.7149, 0.7145, 0.7122, 204489.5],
[1717585200, 0.7126, 0.7149, 0.7133, 0.7144, 85185.7],
[1717581600, 0.7124, 0.7146, 0.714, 0.7131, 178411.5],
[1717578000, 0.7124, 0.716, 0.7143, 0.7137, 207845.7],
[1717574400, 0.714, 0.7182, 0.7181, 0.7144, 172882.4],
[1717570800, 0.7169, 0.7202, 0.7193, 0.7175, 137006.6],
[1717567200, 0.7166, 0.7215, 0.7171, 0.7196, 319441.8],
[1717563600, 0.7136, 0.7174, 0.7171, 0.717, 170088.6],
[1717560000, 0.714, 0.7178, 0.7174, 0.7171, 195534.8],
[1717556400, 0.715, 0.7178, 0.7152, 0.7171, 122120.9],
[1717552800, 0.7142, 0.7185, 0.7184, 0.7152, 208780.8],
[1717549200, 0.7154, 0.7199, 0.7163, 0.7184, 274857.9],
[1717545600, 0.7144, 0.7183, 0.7155, 0.7168, 75366.8],
[1717542000, 0.7136, 0.716, 0.7146, 0.7152, 106694.8],
[1717538400, 0.7122, 0.7153, 0.7145, 0.7146, 137940.1],
[1717534800, 0.7116, 0.7147, 0.7139, 0.7144, 147603.1],
[1717531200, 0.7114, 0.7146, 0.7139, 0.7137, 297552.5],
[1717527600, 0.7094, 0.7168, 0.7168, 0.7139, 280444.1],
[1717524000, 0.7152, 0.7195, 0.7156, 0.7164, 158904.1],
[1717520400, 0.7116, 0.7159, 0.7137, 0.7152, 206150.3],
[1717516800, 0.7118, 0.715, 0.7136, 0.7137, 189808.8],
[1717513200, 0.7098, 0.7157, 0.7116, 0.7134, 247950.2]];
const array = data.map((d) => ({
x: d[0] * 1000,
l: d[1],
h: d[2],
o: d[3],
c: d[4],
}));
const chartData = {
datasets: [
{
label: "Price",
data: array,
borderColor: "rgba(75, 192, 192, 1)",
borderWidth: 1,
//fill: false, // doesn't apply
//barWidth: 0.8, // doesn't exist
},
],
};
const options = {
scales: {
x: {
title: {
display: true,
text: "Time",
},
type: "time",
time: {
unit: "hour",
stepSize: 1,
// displayFormats: {
// hour: "MMM DD", // I used fns, it doesn't get that
// },
},
},
y: {
//beginAtZero: false, // default
},
},
};
new Chart(document.querySelector('#myChart'),
{type: "candlestick", data: chartData, options});
<div style="min-height: 250px">
<canvas id="myChart">
</canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-chart-financial.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
Upvotes: 0