React + AntdでのEChartsの使用法と一般的なエラー

最近、プロジェクトでEChartsを使用してグラフを作成し始めましたが、React + AntdでEChartを使用する際に多くの落とし穴に遭遇しました。ソリューションを記録することで、すべての人に役立つことを願っています。初めて使用するため、コードを最適化する余地がたくさんあります。皆さんが私を助けてくれることを願っています。ありがとう〜

最終効果

1.折れ線グラフ上の点をクリックして、2つの円グラフデータのリンクを実現します
。2。ECharts円グラフデータが0であるか、円グラフが空になると消えるという問題に対処します

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

ReactでEChartsを使用する方法

1.レンダーにdivを追加します

<div id='echartLine' style={
    
    {
    
     width: '100%', height: 300, margin: '24px 0' }} />
<div id='pieTotal' style={
    
    {
    
     width: '100%', height: 300, margin: '24px 0' }} />
<div id='pieReject' style={
    
    {
    
     width: '100%', height: 300, margin: '24px 0' }} />

2.EChartsチャートを初期化します

	// 饼图初始option
	const initPieOption = {
    
    
	  // tooltip: {
    
    
	  //   show: false,
	  // },
	  dataset: {
    
    
	    dimensions: ['desc', 'type', 'value'],
	    source: [{
    
     desc: '', type: '', value: 1 }], // 当无数据时,给饼图个初始数据
	  },
	  grid: {
    
    
	    left: '3%',
	    right: '3%',
	    bottom: '0%',
	    containLabel: true,
	  },
	  series: [
	    {
    
     type: 'pie',
	      radius: ['75%', '45%'],
	      stillShowZeroSum: false,
	      itemStyle: {
    
    
	        color: '#e7e7e7',
	      },
	      label: {
    
    
	        normal: {
    
    
	          show: true,
	          position: 'center',
	          formatter: function () {
    
    
	            var result = ''
	            result = '暂无数据'
	
	            return result
	          },
	          textStyle: {
    
    
	            fontSize: 16,
	            color: '#e2e2e2',
	          },
	        },
	      },
	    },
	  ],
	}
  // 初始化图表
  initChart = () => {
    
    
    // const { trendList } = this.state

    // 折线图
    var lineChart = echarts.init(document.getElementById('echartLine'))
    // 建议将ECharts图表实例进行储存,而不是每次数据变化都进行实例初始化
    this.setState({
    
     lineChart })
    lineChart.setOption({
    
    
      title: {
    
    
        text: '趋势',
      },
      tooltip: {
    
    
        trigger: 'axis',
        axisPointer: {
    
    
          type: 'cross',
        },
      },
      legend: {
    
    
        formatter: function (name) {
    
    
          switch (name) {
    
    
            case 'total':
              return '总量 ' + name
            case 'passCount':
              return '通过量 ' + name
            case 'rejectCount':
              return '拒绝量 ' + name
          }
        },
      },
      dataset: {
    
    
        // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
        // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
        dimensions: ['date', 'total', 'passCount', 'rejectCount'],
        source: [],
      },
      xAxis: {
    
     type: 'category' },
      yAxis: {
    
    
        type: 'value',
      },
      grid: {
    
    
        left: '3%',
        right: '6%',
        bottom: '0%',
        containLabel: true,
      },
      series: [
        {
    
     type: 'line' },
        {
    
     type: 'line' },
        {
    
     type: 'line' },
      ],
    })
    // 饼图总量
    var pieChartTotal = echarts.init(document.getElementById('pieTotal'))
    this.setState({
    
     pieChartTotal })

    // 饼图拒绝量
    var pieChartReject = echarts.init(document.getElementById('pieReject'))
    this.setState({
    
     pieChartReject })

	// 使图表自适应div大小,防止图表溢出
    window.addEventListener('resize', function () {
    
    
      lineChart.resize()
      pieChartTotal.resize()
      pieChartReject.resize()
    })
  }

3.データが変更されたら、グラフを再レンダリングします

 // 获取趋势图
  fetchBaseTrend = async () => {
    
    
    const res = await api.getBaseTrend()
    this.setState({
    
    
      trendList: res,
    }, () => {
    
    
      // 获取到数据后再去调用渲染图表函数
      this.generateChart()
    })
  }
  generateChart = () => {
    
    
    const {
    
     trendList, lineChart, pieChartTotal, pieChartReject } = this.state

    lineChart.setOption({
    
    
      dataset: {
    
    
        // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
        // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
        dimensions: ['date', 'total', 'passCount', 'rejectCount'],
        source: trendList,
      },
    })
	// 由于我对饼图无数据做了处理,所以每次setOption之前都要先执行clear(),防止之前setOption内的灰色背景属性仍生效
    pieChartTotal.clear()
    pieChartReject.clear()

	// 默认用数据加载第一条渲染饼图,可能存在无数据情况,因此需要判断
    pieChartTotal.setOption(trendList[0] && !!trendList[0].totalRatio.length ? this.PieOption('total') : initPieOption)
    pieChartReject.setOption(trendList[0] && !!trendList[0].rejectRatio.length ? this.PieOption('reject') : initPieOption)
 }

4.折れ線グラフをクリックして円グラフをレンダリングする方法

コードのこの部分を最適化する余地はたくさんありますが、私は長い間それを変更していて、より良い方法を見つけられませんでした。皆さんがコメントを手伝ってくれることを願っています。ありがとう〜

  generateChart = () => {
    
    
  
    lineChart.on('click', function (event) {
    
    
      pieChartTotal.clear()

      pieChartTotal.setOption(event.data && !!event.data.totalRatio.length ? {
    
    
        dataset: {
    
    
          // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
          // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
          dimensions: ['desc', 'type', 'value'],
          source: event.data && event.data.totalRatio,
        },
        legend: {
    
    
          orient: 'vertical',
          left: 70,
        },
        tooltip: {
    
    
          trigger: 'item',
          formatter: function (params) {
    
    
            var result = ''
            result = params.name + ' : ' + params.data.value + ' ( ' + params.percent + '% )'

            return result
          },
        },
        series: [
          {
    
     type: 'pie',
            radius: ['75%', '50%'],
            label: {
    
    
              normal: {
    
    
                show: true,
                position: 'center',
                color: '#4c4a4a',
                formatter: function (data) {
    
    
                  var result = ''
                  result = event.name + '\n' + '总量' + ' ' + event.data.total

                  return result
                },
                textStyle: {
    
    
                  fontSize: 16,
                  color: '#00c0ef',
                },
              },
            },
          },
        ],
      } : initPieOption)
      pieChartReject.clear()
      pieChartReject.setOption(event.data.rejectRatio && !!event.data.rejectRatio.length ? {
    
    
        dataset: {
    
    
          // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
          // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
          dimensions: ['desc', 'type', 'value'],
          source: event.data && event.data.rejectRatio,
        },
        legend: {
    
    
          orient: 'vertical',
          right: 70,
        },
        series: [
          {
    
     type: 'pie',
            radius: ['75%', '45%'],
            label: {
    
    
              normal: {
    
    
                show: true,
                position: 'center',
                color: '#4c4a4a',
                formatter: function (data) {
    
    
                  var result = ''
                  result = event.name + '\n' + '拒绝量' + ' ' + event.data.rejectCount

                  return result
                },
                textStyle: {
    
    
                  fontSize: 16,
                  color: '#00c0ef',
                },
              },
            },
          },
        ],
      } : initPieOption)
    })
  }

4.TrendListデータ構造

[{
    
    
	"date": "2020-03-23",
	"total": 52,
	"passCount": 51,
	"rejectCount": 1,
	"totalRatio": [{
    
    
		"type": "text",
		"desc": "文本",
		"value": 27
	}, {
    
    
		"type": "picture",
		"desc": "图片",
		"value": 25
	}],
	"rejectRatio": [{
    
    
		"type": "picture",
		"desc": "图片",
		"value": 1
	}]
}, {
    
    
	"date": "2020-03-24",
	"total": 25,
	"passCount": 18,
	"rejectCount": 7,
	"totalRatio": [{
    
    
		"type": "picture",
		"desc": "图片",
		"value": 15
	}, {
    
    
		"type": "text",
		"desc": "文本",
		"value": 10
	}],
	"rejectRatio": [{
    
    
		"type": "picture",
		"desc": "图片",
		"value": 7
	}]
}]

ECharts FAQ

問題:エラー:コンポーネントseries.pieが存在しません。最初にロードしてください。
理由:パイコンポーネントが導入されていません。
解決策:

import 'echarts/lib/chart/pie'

問題:ECharts3はnoDataLoadingOptionを削除します。データがない場合、コンテナーにデータが表示されません。切り替え後、グラフを表示できません。
解決策:

  1. データに値があるかどうかを判断し、値がない場合は処理します
  2. setOptionでインスタンスのオプションをクリアします
  3. EChartsインスタンスを抽出し、毎回作成しないでください
  4. 特定のコードは上記のコードブロックで見ることができます。よくわからない場合は、個人的に私に尋ねることができます
	// 默认用数据加载第一条渲染饼图,可能存在无数据情况,因此需要判断
    pieChartTotal.setOption(trendList[0] && !!trendList[0].totalRatio.length ? this.PieOption('total') : initPieOption)

問題:ラベルフォーマッター形式のコンテンツ、折り返す必要があります。
理由:ラベルはキャンバスに基づいており、htmlをサポートしておらず、折り返しのみをサポートしています\ n解決

formatter: function (data) {
    
    
	var result = ''
	result = event.name + '\n' + '总量' + ' ' + event.data.total

	return result
},

問題:チャートがdivをオーバーフローし、適応的に解決できない

   window.addEventListener('resize', function () {
    
    
      lineChart.resize()
    })

問題:クリックイベントが複数回バインドされ、コールバックが複数回トリガーされる原因になります

  myChart.off('click')// 防止累计触发
  myChart.on('click', function (event) {
    
    
     const url = reportTypesMap[item.key]['url']

     if (!url) return false
     const href = window.location.href.split('#')[0]
     window.open(`${
      
      href}#${
      
      url}?time=${
      
      event.name}`)
   })

おすすめ

転載: blog.csdn.net/zn740395858/article/details/105181685