Chartjs-In react hooks, how can i pass the filtered values to the chart?

4👍

your code has many problems regarding how you handle state date inside the component.

If data is constant then you can move it outside the component.

The function filterData can be replaced with a state holding the filtered data and a useEffect that will be triggered when another filterdatanumber state changes.

Here is an example code with these changes.

import React, { useState, useEffect } from "react";
import { Bar } from "react-chartjs-2";

const data = {
  labels: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
  datasets: [
    {
      label: "Weekly Sales",
      data: [18, 12, 6, 9, 11, 3, 9],
      backgroundColor: [
        "rgba(255, 26, 104, 0.2)",
        "rgba(54, 162, 235, 0.2)",
        "rgba(255, 206, 86, 0.2)",
        "rgba(75, 192, 192, 0.2)",
        "rgba(153, 102, 255, 0.2)",
        "rgba(255, 159, 64, 0.2)",
        "rgba(0, 0, 0, 0.2)",
      ],
      borderColor: [
        "rgba(255, 26, 104, 1)",
        "rgba(54, 162, 235, 1)",
        "rgba(255, 206, 86, 1)",
        "rgba(75, 192, 192, 1)",
        "rgba(153, 102, 255, 1)",
        "rgba(255, 159, 64, 1)",
        "rgba(0, 0, 0, 1)",
      ],
      borderWidth: 1,
    },
  ],
};

export default function VerticalBar() {
  const [firstNumber, setFirstNumber] = useState("");
  const [filterdatanumber, setFilterdatanumber] = useState(
    Number.MIN_SAFE_INTEGER
  );
  const [filteredData, setFilteredData] = useState(data);
  const textChangeHandler = (i) => {
    setFirstNumber(i.target.value);
    console.log("target.value", i.target.value);
    filterChart(Number(i.target.value));
  };

  useEffect(() => {
    const newData = { ...data };
    const filteredData = [];
    const filterLabels = [];
    const filterColors = [];
    for (let i = 0; i < newData.datasets[0].data.length; i++) {
      const value = newData.datasets[0].data[i]
      if (value > Number(filterdatanumber)) {
        const labelsResult = newData.labels[i];
        const colorssResult = newData.datasets[0].backgroundColor[i];
        filterLabels.push(labelsResult);
        filterColors.push(colorssResult);
        filteredData.push(value)
      }
    }
    console.log("filteredData", filteredData);
    console.log("filterLabels", filterLabels);
    console.log("filterColors", filterColors);
    newData.datasets[0].data = filteredData;
    newData.labels = filterLabels;
    newData.datasets[0].backgroundColor = filterColors;
    setFilteredData(newData);
  }, [filterdatanumber]);

  return (
    <div>
      <Bar data={filteredData} />
      <input
        value={firstNumber}
        type="number"
        name="firstNumber"
        onChange={textChangeHandler}
      />
    </div>
  );
}

Please remember that this code is just an example, maybe it will need some edits in order to match your needs.

0👍

Here is my final solution fully working and with a refactored 3rd approach. The values are matching the keys consistently when filtered and displayed correctly in the chart.

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Bar } from "react-chartjs-2";

export default function VerticalBar() {
  const [data, setData] = useState ([
    {val: 18, label: "Mon"},
    {val: 1, label: "Tue"},
    {val: 5, label: "Wed"}, 
    {val: 8, label: "Thu"}, 
    {val: 19, label: "Fri"}, 
    {val: 5, label: "Sat"}, 
    {val: 7, label: "Sun"}
  ])

  const chartConfig = useMemo(() => {
    return  {
        labels: data.map(el => el.label), 
        datasets: [
          {
            label: "Weekly Sales",
            data: data.map(el => el.val),
            backgroundColor: [
              "rgba(255, 26, 104, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)",
              "rgba(153, 102, 255, 0.2)",
              "rgba(255, 159, 64, 0.2)",
              "rgba(0, 0, 0, 0.2)",
            ],
            borderColor: [
              "rgba(255, 26, 104, 1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)",
              "rgba(153, 102, 255, 1)",
              "rgba(255, 159, 64, 1)",
              "rgba(0, 0, 0, 1)",
            ],
            borderWidth: 1,
          },
        ],
      };
    
  }, [data])

  const textChangeHandler = useCallback(
    (event) => {
    setData(prevData => {
      return prevData.filter((el) => parseInt(event.target.value, 10) < el.val)
    })
  }, [setData]);

  return (
    <div>
      <Bar data={chartConfig} />
      <input
        type="number"
        name="firstNumber"
        onChange={textChangeHandler}
      />
    </div>
  );
}

Leave a comment