Error using emoji as input with Highcharts WordCloud

huangapple go评论86阅读模式
英文:

Error using emoji as input with Highcharts WordCloud

问题

I've run into a problem using Highcharts WordCloud with React when using emoji as the input data. I'm using the highcharts-react-official wrapper. Most of the time the emojis display fine, but occasionally I'm getting TypeError: Cannot convert undefined or null to object during the render.

我在使用React时遇到了一个问题,使用emoji作为输入数据时,我正在使用highcharts-react-official包装器。大多数时候,表情符号显示正常,但偶尔在渲染过程中出现TypeError: Cannot convert undefined or null to object的错误。

I've played around with the input data sets to ensure they are non-null, and non-undefined, and also with the arrays of emoji themselves to test whether specific emoji are causing the problem. The result of that testing highlighted a couple of emoji that, at first, caused a problem, but then started behaving correctly again. Sometimes resizing the browser window or adjusting a weighting, or removing an input value would also re-create the error, but I can't pin it down to any particular input value.

我已经尝试了各种输入数据集,以确保它们不是null或undefined,还尝试了emoji数组本身,以测试是否有特定的emoji引起了问题。测试的结果突出显示了一些emoji,起初会出现问题,但后来又开始正常运行。有时调整浏览器窗口的大小、调整权重或删除输入值也会重新引发错误,但我无法确定是哪个具体的输入值导致了错误。

From digging a little through the Highcharts WordCloud src code, I think I've narrowed the problem down to the attempted iteration of the keys of animatableAttribs object of the emoji to be rendered, which turn out to be null or undefined when the error occurs. So I figured perhaps the fault was in the attempted animation of that particular emoji, which may explain the difficulty in reproducing the error as the animation, orientation or positioning of the emoji may be slightly different on render or window resize. To test this, I set the animation property of the series to false but the error still occurred.

通过对Highcharts WordCloud源代码进行简单的研究,我认为问题可以归结为试图迭代要渲染的emoji的animatableAttribs对象的键,当出现错误时,这些键会变成null或undefined。因此,我认为问题可能出现在试图对该特定emoji进行动画时,这可能解释了很难复制错误的原因,因为在渲染或调整窗口大小时,emoji的动画、方向或定位可能会略有不同。为了测试这一点,我将系列的动画属性设置为false,但错误仍然发生。

Can anyone tell me if I'm doing something wrong here, or if emojis just aren't fully supported by Highcharts wordcloud?

有人能告诉我我在这里做错了什么,或者是Highcharts wordcloud不完全支持表情符号吗?

Edit It appears that adding text to the emoji, so the input becomes a short line of text with an emoji at the end, prevents the error from occurring. The minimum length of prepended text required seems to be 2 characters. So "to 😃" instead of "😃" works reliably. Empty strings or strings with just white space, with an emoji appended on the end do not work.

编辑 看起来,如果在表情符号中添加文本,使输入变成以表情符号结尾的短文本行,可以防止出现错误。需要添加的前置文本的最小长度似乎为2个字符。因此,可靠的工作方式是"to 😃",而不是"😃"。空字符串或只包含空格的字符串,最后附加了一个表情符号,是不起作用的。

I've recreated a codesandbox example here. If you cycle through the emoji array lists by clicking the button, the error will eventually occur. Below is also a stacktrace of the console error in my browser with a ref to the wordcloud src at line 99, also below.

我重新创建了一个codesandbox示例 这里。如果你通过点击按钮循环遍历emoji数组列表,最终会出现错误。下面还有一个控制台错误的堆栈跟踪,我的浏览器在wordcloud源代码中的第99行引用也在下面。

WordCloud.jsx

import React, { useEffect, useState } from "react";
import HighchartsReact from "highcharts-react-official";
import Highcharts from "highcharts";
import addWordcloudModule from "highcharts/modules/wordcloud";

addWordcloudModule(Highcharts);

const WordCloud = ({ data }) => {
  const [chartOptions, setChartOptions] = useState({
    title: {
      text: ""
    },
    series: [
      {
        type: "wordcloud",
        data: [],
        name: "frequency"
      }
    ],
    tooltip: {
      headerFormat:
        '<span style="font-size: 16px"><b>{point.key}</b></span><br>'
    },
    plotOptions: {
      series: {
        minFontSize: 2,
        animation: false
      }
    }
  });

  const updateSeries = (data) => {
    const newSeries = [
      { type: "wordcloud", data: data.data, name: data.name ?? "frequency" }
    ];
    console.log(newSeries);
    setChartOptions({
      ...chartOptions,
      series: newSeries
    });
  };

  useEffect(() => {
    console.log(data);
    if (data) {
      updateSeries(data);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  return <HighchartsReact highcharts={Highcharts} options={chartOptions} />;
};

export default WordCloud;

App.jsx

import { useState } from "react";
import "./styles.css";
import WordCloud from "./WordCloud";

const emojis = [
  {
    data: [
      {
        name: "&#128536;",
        weight: 176
      },
      {
        name: "&#127939;&#127995;‍♀️",
        weight: 1
      },
      {
        name: "&#129311;",
        weight: 1
      },
      {
        name: "&#129305;",
        weight: 1

<details>
<summary>英文:</summary>

I&#39;ve run into a problem using Highcharts WordCloud with React when using emoji as the input data. I&#39;m using the highcharts-react-official wrapper. Most of the time the emojis display fine, but occasionally I&#39;m getting `TypeError: Cannot convert undefined or null to object` during the render.

I&#39;ve played around with the input data sets to ensure they are non-null, and non-undefined, and also with the arrays of emoji themselves to test whether specific emoji are causing the problem. The result of that testing highlighted a couple of emoji that, at first, caused a problem, but then started behaving correctly again. Sometimes resizing the browser window or adjusting a weighting, or removing an input value would also re-create the error, but I can&#39;t pin it down to any particular input value.

From digging a little through the Highcharts WordCloud src code, I think I&#39;ve narrowed the problem down to the attempted iteration of the keys of `animatableAttribs` object of the emoji to be rendered, which turn out to be null or undefined when the error occurs. So I figured perhaps the fault was in the attempted animation of that particular emoji, which may explain the difficulty in reproducing the error as the animation, orientation or positioning of the emoji may be slightly different on render or window resize. To test this, I set the animation property of the series to false but the error still occurred. 

Can anyone tell me if I&#39;m doing something wrong here, or if emojis just aren&#39;t fully supported by Highcharts wordcloud?

**Edit** It appears that adding text to the emoji, so the input becomes a short line of text with an emoji at the end, prevents the error from occurring. The minimum length of prepended text required seems to be 2 characters. So &quot;to &#128515;&quot; instead of &quot;&#128515;&quot; works reliably. Empty strings or strings with just white space, with an emoji appended on the end do not work.

I&#39;ve recreated a codesandbox example [here](https://codesandbox.io/s/thirsty-field-21ese6?file=/src/WordCloud.jsx). If you cycle through the emoji array lists by clicking the button, the error will eventually occur. Below is also a stacktrace of the console error in my browser with a ref to the wordcloud src at line 99, also below.

WordCloud.jsx

    import React, { useEffect, useState } from &quot;react&quot;;
    import HighchartsReact from &quot;highcharts-react-official&quot;;
    import Highcharts from &quot;highcharts&quot;;
    import addWordcloudModule from &quot;highcharts/modules/wordcloud&quot;;
    
    addWordcloudModule(Highcharts);
    
    const WordCloud = ({ data }) =&gt; {
      const [chartOptions, setChartOptions] = useState({
        title: {
          text: &quot;&quot;
        },
        series: [
          {
            type: &quot;wordcloud&quot;,
            data: [],
            name: &quot;frequency&quot;
          }
        ],
        tooltip: {
          headerFormat:
            &#39;&lt;span style=&quot;font-size: 16px&quot;&gt;&lt;b&gt;{point.key}&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&#39;
        },
        plotOptions: {
          series: {
            minFontSize: 2,
            animation: false
          }
        }
      });
    
      const updateSeries = (data) =&gt; {
        const newSeries = [
          { type: &quot;wordcloud&quot;, data: data.data, name: data.name ?? &quot;frequency&quot; }
        ];
        console.log(newSeries);
        setChartOptions({
          ...chartOptions,
          series: newSeries
        });
      };
    
      useEffect(() =&gt; {
        console.log(data);
        if (data) {
          updateSeries(data);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, [data]);
    
      return &lt;HighchartsReact highcharts={Highcharts} options={chartOptions} /&gt;;
    };
    
    export default WordCloud;

App.jsx

    import { useState } from &quot;react&quot;;
    import &quot;./styles.css&quot;;
    import WordCloud from &quot;./WordCloud&quot;;
    
    const emojis = [
      {
        data: [
          {
            name: &quot;&#128536;&quot;,
            weight: 176
          },
          {
            name: &quot;&#127939;&#127995;‍♀️&quot;,
            weight: 1
          },
          {
            name: &quot;&#129311;&quot;,
            weight: 1
          },
          {
            name: &quot;&#129305;&quot;,
            weight: 1
          },
          {
            name: &quot;&#128547;&quot;,
            weight: 1
          },
          {
            name: &quot;&#128641;&quot;,
            weight: 1
          },
          {
            name: &quot;&#128556;&quot;,
            weight: 1
          },
          {
            name: &quot;&#129505;&quot;,
            weight: 1
          }
        ]
      }
    ];
    
    export default function App() {
      const [index, setIndex] = useState(0);
    
      const updateData = () =&gt; {
        const newIndex = (index + 1) % emojis.length;
        console.log(newIndex);
        setIndex(newIndex);
      };
    
      return (
        &lt;div className=&quot;App&quot;&gt;
          &lt;button onClick={updateData}&gt;Update Data&lt;/button&gt;
          &lt;h5&gt;index = {index}&lt;/h5&gt;
          &lt;WordCloud data={emojis[index]} /&gt;
        &lt;/div&gt;
      );
    }

[console log of error](https://i.stack.imgur.com/JtBZk.png)

[wordcloud.src](https://i.stack.imgur.com/PmILS.png)

</details>


# 答案1
**得分**: 1

下面是您要翻译的部分

"我会感激Highcharts专家对此问题提供适当的解决方案的回应,但我目前的解决方法是通过在plotOptions的dataLabels中添加useHTML标志来将表情呈现为HTML,然后在每个表情的两侧添加两个字符的span,这些字符的样式与背景颜色相同,因此它们不可见。如果将不透明度设置为0,或者在表情前后只有1个字符,似乎不起作用。这是一个可怕的妙招,但似乎能够可靠地工作。

const data = emojiData.map(({emoji, count}) => {
  return {
    name: `&lt;span style=&quot;color:white&quot;&gt;&#39;&#39;&lt;/span&gt;` + emoji + `&lt;span style=&quot;color:white&quot;&gt;&#39;&#39;&lt;/span&gt;`,
    weight: count,
  };
});"

<details>
<summary>英文:</summary>

I would appreciate a response from the Highcharts gurus as to a proper solution to this problem, but my current workaround is to render the emoji as html by adding the useHTML flag to the dataLabels in plotOptions

    plotOptions: {
      series: {
        dataLabels: {
          useHTML: true,
        },
      },
    },

and then adding a span of 2 chars on either side of each emoji, styled the same color as the background, so they&#39;re not visible. It doesn&#39;t seem to work if opacity is set to 0 instead or if there is only 1 char before and after the emoji. It&#39;s a horrible hack but it seems to work reliably.

    const data = emojiData.map(({emoji, count}) =&gt; {
      return {
        name: `&lt;span style=&quot;color:white&quot;&gt;&#39;&#39;&lt;/span&gt;` + emoji + `&lt;span style=&quot;color:white&quot;&gt;&#39;&#39;&lt;/span&gt;`,
        weight: count,
      };
    });

</details>



huangapple
  • 本文由 发表于 2023年3月12日 19:01:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定