BarChart 中工具提示不显示带有动态键的数据

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

描述

嗨!我正在制作条形图。一切都按预期运行,除了默认的工具提示,当我将鼠标悬停在栏上时,它显示为空。我的图表使用动态键作为图例,可以正常工作,但相同的键似乎不适用于工具提示。

问题

尽管使用动态生成的键正确显示了条形图,但工具提示为空。使用同一组按键可以正确显示图例。

代码片段

图表配置

<ResponsiveBar
      data={barData}
      keys={chartKeys}
      indexBy="year"
      margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
      padding={0.3}
      valueScale={{ type: "linear" }}
      indexScale={{ type: "band", round: true }}
      colors={{ scheme: "nivo" }}
      borderColor={{
        from: "color",
        modifiers: [["darker", 1.6]],
      }}
      axisTop={null}
      axisRight={null}
      axisBottom={{
        tickSize: 5,
        tickPadding: 5,
        tickRotation: 0,
        legend: "year",
        legendPosition: "middle",
        legendOffset: 32,
      }}
      axisLeft={{
        tickSize: 5,
        tickPadding: 5,
        tickRotation: 0,
        legend: "credito_vigente",
        legendPosition: "middle",
        legendOffset: -40,
      }}
      enableTotals={true}
      labelSkipWidth={12}
      labelSkipHeight={12}
      labelTextColor={{ from: "color", modifiers: [["darker", 1.6]] }}
      legends={[
        {
          dataFrom: "keys",
          anchor: "bottom-right",
          direction: "column",
          justify: false,
          translateX: 120,
          translateY: 0,
          itemsSpacing: 1, // Reduced spacing between items
          itemWidth: 80, // Smaller width
          itemHeight: 15, // Smaller height
          itemDirection: "left-to-right",
          itemOpacity: 0.85,
          symbolSize: 12, // Smaller symbol size
          effects: [
            {
              on: "hover",
              style: {
                itemOpacity: 1,
              },
            },
          ],
        },
      ]}
      role="application"
      ariaLabel="Nivo bar chart demo"
      barAriaLabel={(e) =>
        `${e.id}: ${e.formattedValue} in year: ${e.indexValue}`
      }
    />

数据处理

 const [dataByYear, setDataByYear] = useState<AñoConSusActividades[]>([]);
  const [chartKeys, setChartKeys] = useState<string[]>([]); // State to store unique keys
  const transformAndSetData = useCallback(
    (data: PresupuestoPorProgramaUNI[]) => {
      const groupedData = data.reduce((acc, curr) => {
        // Find an existing year entry in the accumulated data
        const yearEntry = acc.find(
          (entry) => entry.year === curr.impacto_presupuestario_anio
        );

        // Construct a new activity object
        const activity = {
          actividad_desc: curr.actividad_desc,
          credito_vigente: Number(curr.credito_vigente.toFixed(0)),
        };

        if (yearEntry) {
          // If an entry for the year already exists, push the new activity into this year's activities array
          yearEntry.activities.push(activity);
        } else {
          // If no entry for the year exists, create a new one with the current activity
          acc.push({
            year: curr.impacto_presupuestario_anio,
            activities: [activity],
          });
        }
        return acc;
      }, [] as AñoConSusActividades[]);

      // Update the state with the new grouped data
      setDataByYear(groupedData);

      // Update the chart keys based on the new data
      setChartKeys(extractUniqueKeys(groupedData));
    },
    [setDataByYear, setChartKeys]
  ); // Include these as dependencies

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch("/api/presupuestoUni");
        const jsonData = await response.json();
        const dataRes: PresupuestoPorProgramaUNI[] = jsonData.dataRes;
        console.log("Fetched Data:", dataRes); // Log the raw fetched data
        transformAndSetData(dataRes);
      } catch (error) {
        console.error("Failed to fetch data:", error);
      }
    }

    fetchData();
  }, [transformAndSetData]); // Now only re-runs if transformAndSetData changes, which shouldn’t happen due to useCallback

  const extractUniqueKeys = (data: AñoConSusActividades[]): string[] => {
    const allKeys = new Set(
      data.flatMap((yearGroup) =>
        yearGroup.activities.map((activity) => activity.actividad_desc)
      )
    );
    return Array.from(allKeys);
  };

  //PENSAR SI PUEDO HACER ESTO DIRECTAMENTE EN transformAndSetData
  const barData = dataByYear.map((yearGroup) => {
    // Define the accumulator with an index signature.
    // This tells TypeScript that the object will have any number of properties,
    // where each property key is a string and each property value is a number.
    const activitiesAccumulator: Record<string, number> = {};

    yearGroup.activities.forEach((activity) => {
      activitiesAccumulator[activity.actividad_desc] = activity.credito_vigente;
    });

    return {
      year: yearGroup.year.toString(), // This maps directly to 'indexBy' in the ResponsiveBar component
      ...activitiesAccumulator,
    };
  });

默认工具提示不起作用的视频:

https://github.com/plouc/nivo/assets/55926702/ac72b3c4-6f12-4faa-8be4-4ef3af06f711

reactjs typescript next.js nivo-react
1个回答
0
投票

来源:https://github.com/pluc/nivo/discussions/2583#discussioncomment-9310618

解决方案作者:

因此工具提示正常工作,问题出在您的样式上:

@media (prefers-color-scheme: dark) {
  :root {
    --foreground-rgb: 255, 255, 255;
  }
}

body {
  color: rgb(var(--foreground-rgb));
}

默认情况下,文本颜色为白色,工具提示背景也是白色,这就是为什么它看起来是空的,您可以调整 css 或将主题传递给图表:

theme={{ tooltip: { wrapper: { color: "#000000" } } }}
© www.soinside.com 2019 - 2024. All rights reserved.