通过水合反应 Highcharts 问题

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

我有一个代表一些数据的图表。该图表可以在两种类型的单位(Mwh 和 Kwh)之间切换。 当数据初始化加载时,它们是 100% 正确的,并且被放置在需要的位置。 但切换之后,它会产生一些“问题”。 作为系列选项传递的数据,它们是正确的,但图中的块放置不正确。

有问题截图:

  1. enter image description here
  2. enter image description here
  3. enter image description here

我尝试使用静态数据,未排序,但仍然存在同样的问题。 另外,我尝试重新绘制图表但没有帮助。

这是部分代码:

  const setBuildingNamesAndDataForChart = (sortedData: BuildingData[]) => {
    const tempNames: string[] = [];
    const districtHeatings: number[] = [];
    const districtCoolings: number[] = [];
    const gasImports: number[] = [];
    const electricityDemands: number[] = [];
    const electricityGenerations: number[] = [];
    const co2Uses: number[] = [];
    const energyUses: number[] = [];

    sortedData.forEach(
      ({
        building,
        year,
        USED_HEATING_IMPORT,
        DISTRICT_HEATING_IMPORT,
        USED_COOLING_IMPORT,
        DISTRICT_COOLING_IMPORT,
        USED_GAS_IMPORT,
        GAS_IMPORT_KWH,
        USED_ELECTRICITY_DEMAND,
        ELECTRICITY_DEMAND,
        USED_ELECTRICITY_GENERATION,
        ELECTRICITY_GENERATION,
        CO2_USE,
      }) => {
        tempNames.push(`${building.buildingName} ${year}`);

        districtHeatings.push(
          parseFloat(
            (toggleState
              ? USED_HEATING_IMPORT ?? 0
              : (DISTRICT_HEATING_IMPORT ?? 0) / 1000
            ).toFixed(1)
          )
        );
        districtCoolings.push(
          parseFloat(
            (toggleState
              ? USED_COOLING_IMPORT ?? 0
              : (DISTRICT_COOLING_IMPORT ?? 0) / 1000
            ).toFixed(1)
          )
        );
        gasImports.push(
          parseFloat(
            (toggleState
              ? USED_GAS_IMPORT ?? 0
              : (GAS_IMPORT_KWH ?? 0) / 1000
            ).toFixed(1)
          )
        );
        electricityDemands.push(
          parseFloat(
            (toggleState
              ? USED_ELECTRICITY_DEMAND ?? 0
              : (ELECTRICITY_DEMAND ?? 0) / 1000
            ).toFixed(1)
          )
        );
        electricityGenerations.push(
          parseFloat(
            (toggleState
              ? (USED_ELECTRICITY_GENERATION ?? 0) * -1
              : (ELECTRICITY_GENERATION ?? 0) / -1000
            ).toFixed(1)
          )
        );
        co2Uses.push(parseFloat((CO2_USE ?? 0).toFixed(1)));
      }
    );

    setBuildingNames(tempNames);
    setDataForChart([
      districtHeatings,
      districtCoolings,
      gasImports,
      electricityDemands,
      electricityGenerations,
      co2Uses,
      energyUses,
    ]);
  };

  const sortOnToggle = (data: BuildingData[]): BuildingData[] => {
    return [...data].sort((a, b) => {
      const sumA = toggleState
        ? (a.USED_HEATING_IMPORT ?? 0) +
          (a.USED_COOLING_IMPORT ?? 0) +
          (a.USED_GAS_IMPORT ?? 0) +
          (a.USED_ELECTRICITY_DEMAND ?? 0) +
          (a.USED_ELECTRICITY_GENERATION ?? 0)
        : (a.DISTRICT_HEATING_IMPORT ?? 0) +
          (a.DISTRICT_COOLING_IMPORT ?? 0) +
          (a.GAS_IMPORT_KWH ?? 0) +
          (a.ELECTRICITY_DEMAND ?? 0) +
          (a.ELECTRICITY_GENERATION ?? 0);

      const sumB = toggleState
        ? (b.USED_HEATING_IMPORT ?? 0) +
          (b.USED_COOLING_IMPORT ?? 0) +
          (b.USED_GAS_IMPORT ?? 0) +
          (b.USED_ELECTRICITY_DEMAND ?? 0) +
          (b.USED_ELECTRICITY_GENERATION ?? 0)
        : (b.DISTRICT_HEATING_IMPORT ?? 0) +
          (b.DISTRICT_COOLING_IMPORT ?? 0) +
          (b.GAS_IMPORT_KWH ?? 0) +
          (b.ELECTRICITY_DEMAND ?? 0) +
          (b.ELECTRICITY_GENERATION ?? 0);

      return sumB - sumA;
    });
  };

  const reflowCharts = () => {
    Highcharts.charts.forEach((chart) => chart?.reflow());
  };

  useEffect(() => {
    if (data) {
      const sorted = co2
        ? [...data].sort((a, b) => b.CO2_USE - a.CO2_USE)
        : sortOnToggle(data);

      setBuildingNamesAndDataForChart(sorted);
    }
  }, [data, co2, toggleState]);

  useEffect(() => {
    setTimeout(() => {
      reflowCharts();
    }, 10);
  }, []);

  const options = {
    chart: {
      type: "column",
      polar: false,
    },
    exporting: {
      ...chartExportOption,
      chartOptions: {
        title: {
          text: `${
            co2 ? t("co2EmissionPerBuilding") : t("energyUsePerBuilding")
          }`,
        },
      },
    },
    plotOptions: {
      series: {
        stacking: "normal",
      },
    },

    title: {
      useHTML: true,
      text: `${co2 ? t("co2EmissionPerBuilding") : t("energyUsePerBuilding")} 
      <span class="custom-tooltip custom-tooltip-left" id="question">?<span class="tooltip-text">${
        co2 ? t("h4") : t("h9")
      }</span>
</span>
      `,
      align: "center",
      style: {
        fontFamily: "Inter, sans-serif",
        fontSize: "15px",
        fontWeight: "600",
        color: "#333333",
      },
    },
    subtitle: {
      text: co2
        ? t("mostRecentCo2UseAvailable")
        : t("mostRecentEnergyUseAvailable"),
    },
    series: co2
      ? [
          {
            data: dataForChart[5],
            name: t("co2Use"),
            color: colorScheme3.renorBlue,
            turboThreshold: 0,
            showInLegend: haveValues(dataForChart[5] ?? []),
          },
        ]
      : [
          {
            data: dataForChart[0],
            name: t("districtHeating"),
            color: colorScheme3.renorRed,
            turboThreshold: 0,
            rounded: false,
            showInLegend: haveValues(dataForChart[0] ?? []),
          },
          {
            data: dataForChart[1],
            name: t("districtCooling"),
            color: colorScheme3.renorBlue,
            turboThreshold: 0,
            showInLegend: haveValues(dataForChart[1] ?? []),
          },
          {
            data: dataForChart[2],
            name: t("gas"),
            color: colorScheme3.renorMediumGray,
            turboThreshold: 0,
            showInLegend: haveValues(dataForChart[2] ?? []),
          },
          {
            data: dataForChart[3],
            name: t("electricity"),
            color: colorScheme3.renorGreen,
            turboThreshold: 0,
            showInLegend: haveValues(dataForChart[3] ?? []),
          },
          {
            data: dataForChart[4],
            name: t("electricityGenerated"),
            color: colorScheme3.renorYellow,
            turboThreshold: 0,
            showInLegend: haveValues(dataForChart[4] ?? []),
          },
        ],
    legend: {
      enabled: true,
      verticalAlign: "top",
    },
    tooltip: {
      formatter() {
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        const point: any = this;
        const pointsArray = point?.points;
        const seriesName = point?.x.split(" ");
        const lastPart = seriesName?.pop();
        const firstPart = seriesName?.join(" ");

        const returningData = pointsArray.map((el: any) => {
          const valueToShow = el?.point?.y >= 0 ? el?.point?.y : -el?.point?.y; // Convert negative value back to positive for tooltip display
          if (el?.point?.y !== 0)
            return `<span style="color:${el.point?.color}" >${
              el.point?.series.name
            }</span>: <b>${parseFloat(valueToShow?.toFixed(1))?.toLocaleString(
              "de"
            )}</b> ${co2 ? " kg" : !toggleState ? " MWh" : " kWh/m²"}<br/>`;
        });
        return `<span> ${firstPart}</span><br/>${t(
          "year"
        )}: ${lastPart}<br/> ${returningData.join("")}`;
      },
      shared: true,
    },
    credits: {
      text: "© Renor",
      href: "www.renor.nl",
    },
    pane: {
      background: [],
    },
    responsive: {
      rules: [],
    },
    yAxis: [
      {
        title: {
          text: co2
            ? t("co2Cons") + " [kg/" + t("yearSingular_nocaps") + "]"
            : !toggleState
              ? t("energyUse") + " MWh/" + t("yearSingular_nocaps")
              : t("energyUse") + " kWh/m²." + t("yearSingular_nocaps"),
        },
        labels: {
          formatter: function () {
            // eslint-disable-next-line @typescript-eslint/no-this-alias
            const point: any = this;
            return formatYAxisLabel(point.value);
          },
        },
      },
    ],
    xAxis: [
      {
        categories: buildingNames,
        reversed: false,
        visible: data.length < 25,
        type: "category",
        title: { text: " " },
        labels: {
          formatter() {
            if (data.length === 0) return "";
            // eslint-disable-next-line @typescript-eslint/no-this-alias
            const point: any = this;
            const valueArray = point?.value?.split(" ");
            const lastValue = valueArray?.pop();
            const firstPart = valueArray?.join(" ");
            return `<span> ${firstPart}</span>`;
          },
        },
      },
    ],

    lang: chartDownloadOptionsTranslations(language || "nl"),
  };```
reactjs highcharts
1个回答
0
投票

更新图表选项的最佳方法是将它们保留在 useState 挂钩内。更新状态时,仅将新选项传递给

chart.update
方法。

演示: https://stackblitz.com/edit/react-jbcrlq?file=index.js

API: https://github.com/highcharts/highcharts-react?tab=readme-ov-file#optimal-way-to-update

© www.soinside.com 2019 - 2024. All rights reserved.