Reputation: 11
This is my code
import "chartjs-adapter-moment";
import LoacalLoader from "@components/Loaders/LocalLoader";
import Text from "@components/Text";
import {
CategoryScale,
Chart as ChartJS,
Filler,
Legend,
LineElement,
LinearScale,
PointElement,
TimeScale,
TimeSeriesScale,
Title,
Tooltip,
} from "chart.js";
import zoom from "chartjs-plugin-zoom";
import { useRef } from "react";
import { Line } from "react-chartjs-2";
import styles from "./styles.module.scss";
import PropTypes from "prop-types";
import useTranslations from "@hooks/useTranslations";
ChartJS.register(
CategoryScale,
LinearScale,
LineElement,
PointElement,
TimeScale,
TimeSeriesScale,
Title,
Tooltip,
Legend,
Filler,
zoom
);
const zoomOptions = {
pan: {
enabled: true,
limits: {
x: { max: "original", min: "original" },
y: { max: "original", min: "original" },
},
mode: "x",
modifierKey: "shift",
speed: 10,
threshold: 10,
},
zoom: {
drag: {
enabled: true,
},
limits: {
x: { max: "original", min: "original" },
y: { max: "original", min: "original" },
},
mode: "x",
pinch: {
enabled: true,
},
sensitivity: 3,
speed: 0.1,
},
};
const dateFormat = (value) => {
if ([0, "0"].includes(value)) {
return "0";
}
const dt = new Date(value);
const date = dt.getDate();
const month = dt.getMonth() + 1;
const year = dt.getFullYear();
return `${date}/${month}/${year}`;
};
const formatValue = (value) => {
if (typeof value === "number") {
return `${value.toLocaleString()}`;
}
return value;
};
const createData = (data = [], xLabel = "", yLabel = "", label = "") => {
const values = [];
const labels = [];
data.forEach((item) => {
labels.push(item[xLabel]);
values.push(item[yLabel]);
});
const datasets = [
{
backgroundColor: (context) => {
const ctx = context.chart.ctx;
const gradient = ctx.createLinearGradient(0, 0, 0, 240);
gradient.addColorStop(0.24, "#0156FC");
gradient.addColorStop(0.994, "rgba(0, 30, 104, 0)");
return gradient;
},
borderColor: "#0156FC",
data: values,
fill: true,
label,
pointBackgroundColor: "#ffffff",
},
];
return { datasets, labels };
};
const createConfig = ({ yValueFormatter = formatValue, unit = "day" }) => ({
elements: {
line: {
tension: 0.2,
},
point: {
radius: 0,
},
tooltips: {
intersect: false,
},
},
interaction: {
axis: "x",
intersect: false,
mode: "index",
},
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
tooltip: {
callbacks: {
label: (yDatapoint) => {
return `${yDatapoint.dataset.label}: ${yValueFormatter(
yDatapoint.raw
)}`;
},
title: (xDatapoint) => {
return dateFormat(xDatapoint[0].label);
},
},
displayColors: false,
},
zoom: zoomOptions,
},
responsive: true,
scales: {
x: {
bounds: "ticks",
grid: {
display: false,
},
ticks: {
auto: false,
autoSkip: true,
maxTicksLimit: 10,
source: "data",
},
time: {
day: "DD",
isoWeekday: true,
month: "MMM",
round: "day",
unit,
unitStepSize: 1000,
week: "DD MMM",
year: "YYYY",
},
type: "timeseries",
},
y: {
beginAtZero: true,
grid: {
display: false,
},
ticks: {
callback: function (val) {
if (typeof val === "number") {
if (Number.isInteger(val)) {
return yValueFormatter(val);
}
return;
}
return yValueFormatter(val);
},
maxTicksLimit: 10,
},
},
},
});
const AreaGraph = ({
data = [],
xValueFormatter = formatValue,
yValueFormatter = formatValue,
loading = true,
xLabel = "timestamp",
yLabel = "value",
title = "",
unit = "day",
}) => {
const { translate } = useTranslations();
const chartRef = useRef();
if (loading) {
return (
<section className={`${styles.loader}`}>
<LoacalLoader />
</section>
);
}
if (!loading && data.length > 0) {
const values = createData(data, xLabel, yLabel, translate(title));
const handleResetZoom = () => {
if (chartRef && chartRef.current) {
chartRef.current.resetZoom();
}
};
return (
<section className={styles.chart}>
<section className={styles["reset-zoom"]}>
<Text text={"reset_zoom"} onClick={handleResetZoom} />
</section>
<Line
ref={chartRef}
options={createConfig({
unit,
values,
xValueFormatter,
yValueFormatter,
})}
data={values}
className={styles.graph}
/>
</section>
);
}
return <section className={`${styles.chart}`}></section>;
};
AreaGraph.propTypes = {
data: PropTypes.any,
loading: PropTypes.any,
title: PropTypes.any,
unit: PropTypes.string,
xLabel: PropTypes.any,
xValueFormatter: PropTypes.any,
yLabel: PropTypes.any,
yValueFormatter: PropTypes.any,
};
export default AreaGraph;
When I send some data and change the unit
its showing ticks which are not there in data. The same happening when I zoom in.
I am expecting it should not show any data or ticks which are not there in the source data.
I am sending date in ISOString format. starting from 2023-01-01. Also, some of the dates in the series are missing, But the graph is showing them also, when I zoom in.
Also, I want to restrict how much user can zoom in, like +2 or +3
Also, if possible is there any way to show dates like this.
Upvotes: 0
Views: 49