crypto-viewer/src/components/coin-chart.js
2026-01-20 11:20:04 +01:00

108 lines
3.1 KiB
JavaScript

import { useState, useEffect } from "react";
import { Line } from "react-chartjs-2";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Tooltip,
Legend,
TimeScale,
} from "chart.js";
import "chartjs-adapter-date-fns";
import { useCoinPricesStore, fetchCoinPrices } from "../store/coins-prices";
import Spinner from "./spinner";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Tooltip,
Legend,
TimeScale
);
const CoinChart = ({ coinId }) => {
const [chartData, setChartData] = useState(null);
const error = useCoinPricesStore(state => state.error);
const coinPrices = useCoinPricesStore(state => state.coinPrices);
const loading = useCoinPricesStore(state => state.loading);
useEffect(() => {
fetchCoinPrices(coinId);
}, [coinId])
useEffect(() => {
if (coinPrices) {
const quotes = coinPrices.prices.map(price => {
return {
x: price[0],
y: price[1],
}
});
setChartData({
datasets: [
{
label: "Price (USD)",
data: quotes,
fill: true,
borderColor: "#007bff",
backgroundColor: "rgba(0, 123, 255, 0.1)",
pointRadius: 0,
tension: 0.3,
}
]
});
}
}, [coinPrices])
if (!chartData) return <p>Loading</p>;
return (
<>
{loading && <Spinner color="#3b88c3" />}
{!loading && error && <div>Loading Price Data Error</div>}
{!loading && !error && (
<div style={{ marginTop: "30px" }}>
<Line
data={chartData}
options={{
responsive: true,
plugins: {
legend: { display: false },
tooltip: { mode: "index", intersect: false },
},
scales: {
x: {
type: "time",
time: {
unit: "day",
},
ticks: {
autoSkip: true,
maxTicksLimit: 7,
},
},
y: {
ticks: {
callback: (val) => `$${val.toLocaleString()}`,
},
},
},
}}
/>
</div>
)}
</>
);
}
export default CoinChart;