I'm using chartjs
/ react-chartjs-s
to draw some plots in React/NextJS. I want to use an image for the pointStyle
for one plot in specific. In plain JavaScript, an image can be created using const i = new Image()
and used as a pointStyle
in ChartJS.
In React I get an error ReferenceError: Image is not defined
. If I try to import Image
from next/image
and use that, then the image does not appear on initial render (like here which interestingly can use new Image()
), and if I click on a datum on the chart I get an error Error: Rendered more hooks than during the previous render.
TLDR: Does anyone know how to use an image/icon as a pointStyle
using Next.js, ChartJS, and react-chartjs-2? Thanks!
I'm using:
react
v. 18.2.0 react-dom
v. 18.2.0 next
v 13.0.05 chart.js
v. 4.1.1 react-chartjs-2
v. 5.1.0 Solution:
new Image()
reference the DOM, but since Next uses SSR, you have to utilize the useRef
, useState
, and useEffect
hooks to circumvent the issue of trying to access the DOM.
import React, { useEffect, useRef, useState } from "react";
import {
Chart as ChartJS,
RadialLinearScale,
PointElement,
LineElement,
Filler,
Tooltip,
Legend
} from "chart.js";
import { Radar } from "../node_modules/react-chartjs-2/dist";
ChartJS.register(
RadialLinearScale,
PointElement,
LineElement,
Filler,
Tooltip,
Legend
);
function App() {
// useRef lets you reference a DOM object, persistent between renders
const ref = useRef();
const [onClient, setOnClient] = useState();
// On first render, set onClient flag to true
useEffect(() => {
setOnClient(true);
}, []);
// On first render, set the current value of the ref to the image
useEffect(() => {
ref.current = new Image(25, 25);
ref.current.src = "https://i.stack.imgur.com/gXQrT.png";
}, []);
const data = {
labels: ["Business 1", "Business 2", "Business 3"],
datasets: [
{
label: "Number of Businesses",
data: [1300, 400, 160],
backgroundColor: "rgba(255, 99, 132, 0.2)",
borderColor: "rgba(255, 99, 132, 1)",
borderWidth: 1,
// Set the value of pointStyle to the ref value
pointStyle: ref.current
}
]
};
return (
<div className="App">
// Return the graph if rendering is happening on the client
{onClient && <Radar data={data} />}
<form>
<input type="text" placeholder="Label" />
<input type="text" placeholder="Dataset" />
<button>Add Data</button>
</form>
</div>
);
}
export default App;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.