REACTJS CHARTJS 在用户单击按钮时更改图表上的数据

问题描述 投票:0回答:0

对不起,我发了很多次问题,但仍然没有用。

所以我的问题是=

有用户想在树形菜单中点击菜单时,在条形图上看到数据和更改数据

有关更多详细信息=

  1. 这是用户点击树形菜单中的数据之前的默认图表显示。

  1. 当用户点击树形菜单中的数据时,比如ACEH数据,条形图将变为ACEH数据

我试过了,这是代码片段。

USESTATE =

const [dataProvinsi, setDataProvinsi] = useState([]);
  const [dataKota, setDataKota] = useState([]);
  const [dataKecamatan, setDataKecamatan] = useState([]);
  const [dataKelurahan, setDataKelurahan] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isLoadingKota, setIsLoadingKota] = useState(false);
  const [isLoadingKecamatan, setIsLoadingKecamatan] = useState(false);
  const provinsiRef = useRef([]);
  const kotaRef = useRef([]);
  const kecamatanRef = useRef([]);

获取=

  const getDataAllProvinsi = () => {
    setIsLoading(true);
    getBuildingOLDallProvinsi()
      .then((resolve) => {
        setDataProvinsi(resolve);
        // setSelectedData(resolve);
        console.log();
      })
      .catch((reject) => {
        console.log(reject);
      })
      .finally(setIsLoading(false));
  };

  const handleProvinsi = async (index) => {
    try {
      const provinsi = provinsiRef.current[index].dataset.prov;
      setIsLoading(true);
      const result = await getBuildingOLDallKota(provinsi);
      setDataKota(result);
      // setSelectedData(result);
      console.log(result);
    } catch (error) {
      console.log("salah");
    } finally {
      setIsLoading(false);
    }
  };

  const handleKota = async (provinsi, index) => {
    try {
      const kota = kotaRef.current[index].dataset.city;
      setIsLoadingKota(true);
      const result = await getBuildingOLDallKecamatan(provinsi, kota);
      setDataKecamatan(result);
      // setSelectedData(result);
      console.log(result);
    } catch (error) {
      console.log("salah");
    } finally {
      setIsLoadingKota(false);
    }
  };

  const handleKecamatan = async (provinsi, kota, index) => {
    try {
      const kecamatan = kecamatanRef.current[index].dataset.camat;
      setIsLoadingKecamatan(true);
      const result = await getBuildingOLDallKelurahan(
        provinsi,
        kota,
        kecamatan
      );
      setDataKelurahan(result);
      // setSelectedData(result);
      console.log(result);
    } catch (error) {
      console.log("salah");
      console.log(error);
    } finally {
      setIsLoadingKecamatan(false);
    }
  };

  useEffect(() => {
    getDataAllProvinsi();
  }, [dataKota, dataKecamatan, dataKelurahan]);

数据图表=

const colorCode = "#0066FF";
  const colorFont = "#8E9093";
  const dataChart = useMemo(
    () => ({
      dataProv: {
        labels: dataProvinsi.map((o) => o.provinsi),
        datasets: [
          {
            fill: true,
            label: null,
            backgroundColor: colorCode,
            borderColor: colorCode,
            borderWidth: 2,
            borderRadius: 12,
            data: dataProvinsi.map((o) => o.total_building),
          },
        ],
      },
      dataCity: {
        labels: dataKota.map((o) => o.kota),
        datasets: [
          {
            fill: true,
            label: null,
            backgroundColor: colorCode,
            borderColor: colorCode,
            borderWidth: 2,
            borderRadius: 12,
            data: dataKota.map((o) => o.total_building),
          },
        ],
      },
    }),
    [dataKota, dataProvinsi]
  );

  const options = {
    plugins: {
      legend: {
        display: false,
        labels: {
          font: {
            color: colorFont,
          },
        },
      },
    },
    scales: {
      x: {
        grid: {
          display: false,
        },
        beginAtZero: false,
        ticks: {
          color: colorFont,
        },
      },
      y: {
        grid: {
          display: false,
        },
        beginAtZero: true,
        ticks: {
          color: colorFont,
        },
      },
    },
  };

  const plugins = [
    {
      beforeDraw: function (chart) {
        if (chart.chartArea) {
          let ctx = chart.ctx;
          let chartArea = chart.chartArea;
          let barArray = chart.getDatasetMeta(0).data;

          ctx.fillStyle = "#B2D1FF85";

          for (let i = 0; i < barArray.length; i++) {
            const { x, width } = barArray[i];

            ctx.fillRect(
              x - width / 2,
              chartArea.top,
              width,
              chartArea.bottom - chartArea.top
            );
          }
        }
      },
    },
  ];

用户点击时更改数据的逻辑=

const changeData2 = () => {
    const data = [dataChart.dataCity];
    setDataKota(data);
    console.log(data);
  };

和回报=

return (
    <>
      <div className="mx-auto mt-8 w-[70rem] h-[32rem] bg-white px-5 py-3 md:px-8 md:py-5 rounded-xl drop-shadow-xl">
        <h1 className="font-bold text-lg mb-4">Diagram Data</h1>
        <Bar
          type={"bar"}
          height={120}
          data={dataChart.dataProv}
          options={options}
          plugins={plugins}
          redraw
        />
      </div>
      <div className="mx-auto my-8 w-[70rem] bg-white px-5 py-3 md:px-8 md:py-5 rounded-md drop-shadow-xl">
        <h1 className="font-bold text-lg">Data Per Daerah</h1>
        <div className="flex justify-between mt-6">
          <h3 className="font-bold">Nama Daerah</h3>
          <h3 className="font-bold">TOTAL BUILDING</h3>
        </div>
        <Accordion allowZeroExpanded>
          {dataProvinsi.map((provinsi, index) => (
            <AccordionItem className="p-1" key={index}>
              <AccordionItemHeading
                onClick={() => {
                  handleProvinsi(index);
                  changeData2();
                }}
              >
                <AccordionItemButton>
                  <div className="w-full inline-flex justify-between items-center">
                    <div className="inline-flex items-center gap-2">
                      <div>
                        <MdKeyboardArrowDown size={20} />
                      </div>
                      <div
                        ref={(ref) => provinsiRef.current.push(ref)}
                        data-prov={provinsi?.provinsi}
                      >
                        {provinsi?.provinsi}
                      </div>
                    </div>
                    <div>{provinsi?.total_building}</div>
                  </div>
                </AccordionItemButton>
              </AccordionItemHeading>
              <AccordionItemPanel className="ml-4">
                <Accordion className="flex flex-col gap-2" allowZeroExpanded>
                  {isLoading ? (
                    <div role="status">
                      <svg
                        className="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-red-600"
                        viewBox="0 0 100 101"
                        fill="none"
                        xmlns="http://www.w3.org/2000/svg"
                      >
                        <path
                          d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
                          fill="currentColor"
                        />
                        <path
                          d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
                          fill="currentFill"
                        />
                      </svg>
                      <span className="sr-only">Loading...</span>
                    </div>
                  ) : (
                    dataKota.map((kota, index) => (
                      <AccordionItem className="p-1" key={kota?.id}>
                        <AccordionItemHeading
                          onClick={() => {
                            handleKota(provinsi?.provinsi, index);
                          }}
                        >
                          <AccordionItemButton>
                            <div className="w-full inline-flex justify-between items-center">
                              <div className="inline-flex items-center gap-2">
                                <div>
                                  <MdKeyboardArrowDown size={20} />
                                </div>
                                <div
                                  ref={(ref) => kotaRef.current.push(ref)}
                                  data-city={kota?.kota}
                                >
                                  {kota?.kota}
                                </div>
                              </div>
                              <div>{kota?.total_building}</div>
                            </div>
                          </AccordionItemButton>
                        </AccordionItemHeading>
                        <AccordionItemPanel className="ml-8">
                          <Accordion
                            className="flex flex-col gap-2"
                            allowZeroExpanded
                          >
                            {isLoadingKota ? (
                              <div role="status">
                                <svg
                                  className="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-red-600"
                                  viewBox="0 0 100 101"
                                  fill="none"
                                  xmlns="http://www.w3.org/2000/svg"
                                >
                                  <path
                                    d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
                                    fill="currentColor"
                                  />
                                  <path
                                    d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
                                    fill="currentFill"
                                  />
                                </svg>
                                <span className="sr-only">Loading...</span>
                              </div>
                            ) : (
                              dataKecamatan.map((kecamatan, index) => (
                                <AccordionItem
                                  className="p-1"
                                  key={kecamatan?.id}
                                >
                                  <AccordionItemHeading
                                    onClick={() => {
                                      handleKecamatan(
                                        provinsi?.provinsi,
                                        kota?.kota,
                                        index
                                      );
                                    }}
                                  >
                                    <AccordionItemButton>
                                      <div className="w-full inline-flex justify-between items-center">
                                        <div className="inline-flex items-center gap-2">
                                          <div>
                                            <MdKeyboardArrowDown size={20} />
                                          </div>
                                          <div
                                            ref={(ref) =>
                                              kecamatanRef.current.push(ref)
                                            }
                                            data-camat={kecamatan?.kecamatan}
                                          >
                                            {kecamatan?.kecamatan}
                                          </div>
                                        </div>
                                        <div>{kecamatan?.total_building}</div>
                                      </div>
                                    </AccordionItemButton>
                                  </AccordionItemHeading>
                                  <AccordionItemPanel className="ml-12">
                                    <Accordion
                                      className="flex flex-col gap-2"
                                      allowZeroExpanded
                                    >
                                      {isLoadingKecamatan ? (
                                        <div role="status">
                                          <svg
                                            className="inline mr-2 w-8 h-8 text-gray-200 animate-spin dark:text-gray-600 fill-red-600"
                                            viewBox="0 0 100 101"
                                            fill="none"
                                            xmlns="http://www.w3.org/2000/svg"
                                          >
                                            <path
                                              d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
                                              fill="currentColor"
                                            />
                                            <path
                                              d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
                                              fill="currentFill"
                                            />
                                          </svg>
                                          <span className="sr-only">
                                            Loading...
                                          </span>
                                        </div>
                                      ) : (
                                        dataKelurahan.map((item, index) => (
                                          <AccordionItem
                                            className="p-1"
                                            key={index}
                                          >
                                            <AccordionItemHeading>
                                              <AccordionItemButton>
                                                <div className="w-full inline-flex justify-between items-center">
                                                  <div className="inline-flex items-center gap-2">
                                                    <div>
                                                      <MdKeyboardArrowDown
                                                        size={20}
                                                      />
                                                    </div>
                                                    <div>{item?.kelurahan}</div>
                                                  </div>
                                                  <div>
                                                    {item?.total_building}
                                                  </div>
                                                </div>
                                              </AccordionItemButton>
                                            </AccordionItemHeading>
                                          </AccordionItem>
                                        ))
                                      )}
                                    </Accordion>
                                  </AccordionItemPanel>
                                </AccordionItem>
                              ))
                            )}
                          </Accordion>
                        </AccordionItemPanel>
                      </AccordionItem>
                    ))
                  )}
                </Accordion>
              </AccordionItemPanel>
            </AccordionItem>
          ))}
        </Accordion>
      </div>
    </>
  );

当我在浏览器中尝试时,当我点击菜单树中的 ACEH 数据时没有任何变化。例如像下面的视频

https://va.media.tumblr.com/tumblr_rqe2h1npcr1zb5h2t.mp4

我的代码有问题吗?请帮助大家。非常感谢你,感谢你的回答和帮助。

javascript reactjs chart.js react-chartjs-2
© www.soinside.com 2019 - 2024. All rights reserved.