supervons / react-native-echarts-pro

A React-Native charts based on Apache ECharts, support various charts and map.
https://supervons.github.io/react-native-echarts-pro-docs/
MIT License
216 stars 32 forks source link

formatter函数内拿不到组件中动态state #100

Closed Dream-nb closed 6 months ago

Dream-nb commented 1 year ago

react-native-echarts-pro: 1.9.0 react-native: 0.68.2 react: 17.0.2


const target: any = ['弹幕数', '总观看时长', '人均观看时长', '观看5分钟用户占比', '弹幕人数占比', '消费用户占比'];
const InteractionAnalysis = ({ interactionData, loading }: InteractionProps) => {
  const [active, setActive] = useState(0); // 切换
  const echarts = useRef<any>(null); // 保存额chartDom
  // echart配置项
  const getOption = useCallback(() => {
    return {
      tooltip: {
        trigger: 'axis',
        confine: true,
        show: loading,
        backgroundColor: '#fff',
        lineStyle: {
          opacity: loading ? 1 : 0,
        },
        position: function (point: any, params: any, dom: any, rect: any, size: any) {
          'show source';
          // 浮窗固定在顶部处理
          const obj: any = { top: -30 };
          const num = parseInt(`${point[0] - size.contentSize[0]}`);
          if (num > 0) {
            obj['left'] = num;
          } else {
            obj['left'] = 0;
          }
          return [obj.left, obj.top];
        },
        formatter(value: any) {
          'show source';
          // 浮窗内容及数字处理
          const data = value[0];
          let num = data.value;
          alert(num);
          alert(active);
          if (num >= 1e8) {
            num = Math.trunc(num / 1e7) / 10 + '亿';
          }
          if (num >= 1e4) {
            num = Math.trunc(num / 1e3) / 10 + '万';
          }
          return `${new Date().getFullYear()}.${data.name} <br />${data.marker} ${data.seriesName}: ${num}`;
        },
      },
      grid: {
        top: '10%',
        left: '12%',
        right: '8%',
        bottom: '20%',
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: interactionData.date,
      },
      yAxis: {
        type: 'value',
        offset: 5,
        axisLabel: {
          formatter(value: any) {
            'show source';
            // Y轴坐标数字处理
            if (value >= 1e8) {
              return parseInt(`${value / 1e8}`) + '亿';
            }
            if (value >= 1e4) {
              return parseInt(`${value / 1e4}`) + '万';
            }
            return value;
          },
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: 'solid',
            color: '#EFEFEF',
          },
        },
      },
      series: [
        {
          name: `${target[active]}`,
          type: 'line',
          smooth: true,
          itemStyle: {
            color: xColor[0],
          },
          lineStyle: {
            color: xColor[0],
          },
          data: interactionData[targetOrData[active]],
          showSymbol: false,
        },
      ],
    };
  }, [active, interactionData, loading]);

  // tab切换函数,区分打点
  const handleChange = (value: number) => {
    setActive(value);
  };

  useEffect(() => {
    if (!echarts.current) return;
    // 更新echart图表函数
    if (interactionData[targetOrData[active]]) {
      echarts.current.setNewOption(getOption(), {
        notMerge: true,
        lazyUpdate: true,
        replaceMerge: 'tooltip',
      });
    }
  }, [active, getOption, interactionData, loading]);

  return (
    <View style={styles.beginShowWarp}>
      <View style={styles.echartBtnAllWarp}>
        <ScrollView
          contentContainerStyle={styles.echartBtnAll}
          showsVerticalScrollIndicator={false}
          showsHorizontalScrollIndicator={false}
          scrollIndicatorInsets={{ bottom: 1 }}
          horizontal
        >
          {target.map((item: any, index: number) => {
            return (
              <DYButton
                key={index + 1}
                onPress={() => handleChange(index)}
                containerStyle={[
                  styles.containerBtn,
                  active === index ? { borderColor: 'transparent', backgroundColor: 'rgba(255,72,35,0.1)' } : {},
                ]}
                style={[styles.echartsBtn, active === index ? { color: '#ff4823' } : {}]}
              >
                {item}
              </DYButton>
            );
          })}
        </ScrollView>
      </View>
      <View style={styles.echartWarp}>
        {interactionData[targetOrData[active]] ? (
          <RNEChartsPro
            ref={echarts}
            key="interaction"
            height={pxToDp2x(328)}
            option={getOption()}
            enableParseStringFunction
            formatterVariable={{ active }}
          />
        ) : null}
      </View>
    </View>
  );
}```
congshengwu commented 1 year ago

你好,因为formatter函数是在WebView环境中执行的,所以无法直接读取到react中的变量。

需要配合使用这个属性formattervariable才能在formatter函数中访问外部变量。

需要这样调用:

formatter(value) {
  return formatterVariable.active ? 'A' : 'B';
}