React Native 中Echarts 饼图不渲染原因剖析

正常来说,导致Echarts 图表不渲染的原因有以下几个:

(1)图表的data数据源不正确(无论是legend.data还是series.data的值,比如series数组里有一些值是null)

(2)图表的legend数组长度与series数组长度不一致

(3)图表的配置项不正确,如下配置是正确的:

const chartOption = {

      tooltip: {

        trigger: 'item',

        confine: true,

        formatter: '{b} : {c} ({d}%)',

        backgroundColor: 'rgba(0, 0, 0, .7)',

        textStyle: {

          fontSize: 12,

        },

      },

      legend: {

        left: '30%',

        top: 'center',

        orient: 'vertical',

        data: legend,

        itemGap: 8,

        itemWidth: 4, // 设置宽度

        itemHeight: 4, // 设置高度

        textStyle: {

          fontSize: 12,

          color: OAColor.lightText

        },

      },

      series: {

        name: '拜访统计',

        type: 'pie',

        radius: ['18%', '45%'],

        center: ['17%', '37%'],

        avoidLabelOverlap: false,

        data: seriesData,

        label: {

          normal: {

            show: false,

            position: 'center'

          },

        },

        labelLine: {

          normal: {

            show: false

          }

        },

      }

    };

(4)没有给图表一个高度和宽度(例如:flex: 1, width: '100%')

(5)图表库版本bug

 

 

下面举一个博主真实遇到且坑了我2天半的例子:

首页饼图:

 

 

错误❌代码:

// 渲染图表

  _renderChart = () => {

    let { chartData, total } = this.state;

    const seriesData = chartData.map((item, index) => {

      if (index < 5) {

        if (!item.name) item.name = '其他'

        return {

          name: item.name,

          value: item.count,

        } // 问题就出在这里,使用map函数,并且if限制在5条记录以内,多余的统计归为‘其他’
          // 由于数组chartData的长度length是大于5的,因此超出5以外的都会返回null,
          // 这就直接导致了数据异常,图表无法渲染出来

      }

    });


    let legend = chartData.map(item => item.name);

    let otherTotal = 0;

    chartData.forEach((item, index) => {

      if (index >= 5)

        otherTotal += item.count;

    });

    if (chartData.length > 5) {

      seriesData.push({ name: '其他', value: otherTotal })

    };




    const chartOption = {

      tooltip: {

        trigger: 'item',

        confine: true,

        formatter: '{b} : {c} ({d}%)',

        backgroundColor: 'rgba(0, 0, 0, .7)',

        textStyle: {

          fontSize: 12,

        },

      },

      legend: {

        left: '30%',

        top: 'center',

        orient: 'vertical',

        data: legend,

        itemGap: 8,

        itemWidth: 4, // 设置宽度

        itemHeight: 4, // 设置高度

        textStyle: {

          fontSize: 12,

          color: OAColor.lightText

        },

      },

      series: {

        name: '拜访统计',

        type: 'pie',

        radius: ['18%', '45%'],

        center: ['17%', '37%'],

        avoidLabelOverlap: false,

        data: seriesData,

        label: {

          normal: {

            show: false,

            position: 'center'

          },

        },

        labelLine: {

          normal: {

            show: false

          }

        },

      }

    };



    return <View style={styles.pieContainer}>

      <Charts cellType='pie' chartOption={chartOption} chartHeight={150} />

      <View style={{ flexDirection: 'row', position: 'absolute', right: '13%' }}>

        <View style={{ flexDirection: 'column', paddingRight: 20 }}>

          {

            chartData ? chartData.map((item, index) => {

              if (index < 5)

                return <Text key={index} style={styles.vcount}>{item.count}</Text>

              else if (index == 5)

                return <Text key={index} style={styles.vcount}>{otherTotal}</Text>

            }) : null

          }

        </View>

        <View style={{ flexDirection: 'column' }}>

          {

            chartData ? chartData.map((item, index) => {

              if (index < 5)

                return <Text key={index} style={styles.vcount}>{this._computeRate(item.count, total)}</Text>

              else if (index == 5)

                return <Text key={index} style={styles.vcount}>{this._computeRate(otherTotal, total)}</Text>

            }) : null

          }

        </View>

      </View>

    </View>

  };

 

 

正确✅代码: 

// 渲染图表

  _renderChart = () => {

    let { chartData, total } = this.state;

    const arr = [];

    chartData.forEach((item, index) => {

      if (index < 5) {

        if (!item.name) item.name = '其他'

        arr.push({

          name: item.name,

          value: item.count,

        })

      }

    });

    const seriesData = arr;

    let legend = chartData.map(item => item.name);

    let otherTotal = 0;

    chartData.forEach((item, index) => {

      if (index >= 5)

        otherTotal += item.count;

    });

    if (chartData.length > 5) {

      seriesData.push({ name: '其他', value: otherTotal })

    };




    const chartOption = {

      tooltip: {

        trigger: 'item',

        confine: true,

        formatter: '{b} : {c} ({d}%)',

        backgroundColor: 'rgba(0, 0, 0, .7)',

        textStyle: {

          fontSize: 12,

        },

      },

      legend: {

        left: '30%',

        top: 'center',

        orient: 'vertical',

        data: legend,

        itemGap: 8,

        itemWidth: 4, // 设置宽度

        itemHeight: 4, // 设置高度

        textStyle: {

          fontSize: 12,

          color: OAColor.lightText

        },

      },

      series: {

        name: '拜访统计',

        type: 'pie',

        radius: ['18%', '45%'],

        center: ['17%', '37%'],

        avoidLabelOverlap: false,

        data: seriesData,

        label: {

          normal: {

            show: false,

            position: 'center'

          },

        },

        labelLine: {

          normal: {

            show: false

          }

        },

      }

    };



    return <View style={styles.pieContainer}>

      <Charts cellType='pie' chartOption={chartOption} chartHeight={150} />

      <View style={{ flexDirection: 'row', position: 'absolute', right: '13%' }}>

        <View style={{ flexDirection: 'column', paddingRight: 20 }}>

          {

            chartData ? chartData.map((item, index) => {

              if (index < 5)

                return <Text key={index} style={styles.vcount}>{item.count}</Text>

              else if (index == 5)

                return <Text key={index} style={styles.vcount}>{otherTotal}</Text>

            }) : null

          }

        </View>

        <View style={{ flexDirection: 'column' }}>

          {

            chartData ? chartData.map((item, index) => {

              if (index < 5)

                return <Text key={index} style={styles.vcount}>{this._computeRate(item.count, total)}</Text>

              else if (index == 5)

                return <Text key={index} style={styles.vcount}>{this._computeRate(otherTotal, total)}</Text>

            }) : null

          }

        </View>

      </View>

    </View>

  };

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在使用 React 和 TypeScript 引入 ECharts 时,你需要按照以下步骤进行操作: 1. 首先,确保你已经安装了 ECharts 的相关依赖。你可以使用 npm 或 yarn 来进行安装: ```shell npm install echarts ``` ```shell yarn add echarts ``` 2. 创建一个新的 React 组件,用于显示 ECharts 。例如,你可以创建一个名为 `PieChart` 的组件: ```tsx import React, { useEffect, useRef } from 'react'; import echarts from 'echarts'; interface PieChartProps { data: any[]; // 的数据 } const PieChart: React.FC<PieChartProps> = ({ data }) => { const chartRef = useRef<HTMLDivElement>(null); useEffect(() => { if (chartRef.current) { const chart = echarts.init(chartRef.current); const option = { series: [ { type: 'pie', data, }, ], }; chart.setOption(option); } }, [data]); return <div ref={chartRef} style={{ width: '100%', height: '300px' }} />; }; export default PieChart; ``` 3. 在你的页面或其他组件使用 `PieChart` 组件,并传入所需的数据。例如: ```tsx import React from 'react'; import PieChart from './PieChart'; const App: React.FC = () => { const data = [ { value: 335, name: 'Category 1' }, { value: 310, name: 'Category 2' }, { value: 234, name: 'Category 3' }, { value: 135, name: 'Category 4' }, { value: 1548, name: 'Category 5' }, ]; return ( <div> <h1>ECharts Pie Chart</h1> <PieChart data={data} /> </div> ); }; export default App; ``` 这样,你就可以在 React 应用引入并使用 ECharts 了。记得根据你的实际需求修改数据和样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值