echarts 雷达图实现悬浮显示单轴数据

898 阅读2分钟

echarts的雷达图,自带的悬浮是显示一组数据,如果要显示一组中的单个数据,需要进行特殊处理,本文封装了一个能够显示单轴数据的方法,具体实现如下:

import { useMount } from 'ahooks';
import * as echarts from 'echarts';
import React, { forwardRef, useEffect, useRef, useState } from 'react';

interface writeScoreInfoProps {
  contentAverageScore: number; //内容平均得分
  languageAverageScore: number; //语言平均得分
  specificationAverageScore: number; //技术规范平均得分
  structureAverageScore: number; //篇章结构平均得分
  writeAverageScore: number; //写作平均得分
}

interface IComponentProps {
  chartData: {
    studentWriteScoreInfo: writeScoreInfoProps;
    writeScoreInfo: writeScoreInfoProps;
  };
  ref: any;
  legendSelectParams: any;
}

let myChart: echarts.ECharts;
const writeChart: React.FC<IComponentProps> = forwardRef(({ chartData, legendSelectParams }: IComponentProps, ref: any) => {
  const chartRef = useRef<HTMLDivElement>(null);
  const { studentWriteScoreInfo, writeScoreInfo } = chartData;

  const indicator = [
    { name: '总分', max: 100, min: 5 },
    { name: '语言', max: 100, min: 5 },
    { name: '内容', max: 100, min: 5 },
    { name: '篇章结构', max: 100, min: 5 },
    { name: '技术规范', max: 100, min: 5 },
  ];

  const buildSeries = function (dataList: any, dataIndex: number) {
    const data = dataList[dataIndex].data;
    const helper = data.map((item: any, index: number) => {
      const arr = new Array(data.length);
      arr.splice(index, 1, item);
      return arr;
    });

    return [data, ...helper].map((item, index) => {
      const itemcolor = dataList[dataIndex].itemStyleColor;
      return {
        name: dataList[dataIndex].name,
        type: 'radar',
        symbol: index === 0 ? 'circle' : 'none',
        symbolSize: 8,
        itemStyle: {
          color: itemcolor,
        },
        lineStyle: {
          color: index === 0 ? itemcolor : 'transparent',
        },
        areaStyle: {
          color: index === 0 ? dataList[dataIndex].areaStyleColor : 'transparent',
        },
        tooltip: {
          show: index === 0 ? false : true,
          formatter: (params: any) => {
            let res = indicator[index - 1].name + ':<br>';
            for (let x of dataList) {
              let str =
                '<i style="display: inline-block;width: 10px;height: 10px;background: ' +
                x.color +
                ';margin-right: 5px;border-radius: 50%;}"></i>' +
                x.name +
                ':' +
                `<span style="color:${x.name == '个人' ? '#00CBC1' : '#1D69FF'}">` +
                x.data[index - 1] +
                '</span>' +
                '<br>';
              res += str;
            }
            return res;
          },
        },
        z: index === 0 ? 1 : 2,
        data: [item],
      };
    });
  };

  useEffect(() => {
    const dataList = [
      {
        name: '个人',
        data: [
          studentWriteScoreInfo?.writeAverageScore as any,
          studentWriteScoreInfo?.languageAverageScore as any,
          studentWriteScoreInfo?.contentAverageScore as any,
          studentWriteScoreInfo?.structureAverageScore as any,
          studentWriteScoreInfo?.specificationAverageScore as any,
        ],
        itemStyleColor: '#00CBC1',
        areaStyleColor: '#D1F8F6',
      },
      {
        name: '班级平均',
        data: [
          writeScoreInfo?.writeAverageScore as any,
          writeScoreInfo?.languageAverageScore as any,
          writeScoreInfo?.contentAverageScore as any,
          writeScoreInfo?.structureAverageScore as any,
          writeScoreInfo?.specificationAverageScore as any,
        ],
        itemStyleColor: '#1D69FF',
        areaStyleColor: '#D1E0FA',
      },
    ];
    const series = [];
    for (let i in dataList) {
      series.push(...buildSeries(dataList, parseInt(i)));
    }
    console.log(series);

    setOption({
      grid: {
        left: '10%',
        top: '1000px',
        right: '10%',
        bottom: '10%',
        containLabel: true,
      },
      tooltip: {},
      radar: {
        center: ['50%', '65%'],
        radius: '55%',
        shape: 'circle',
        name: {
          textStyle: {
            color: '#747474',
          },
        },
        splitLine: {
          //每个圈的边框颜色
          lineStyle: {
            color: ['#F4F4F6', '#F4F4F6', '#F4F4F6', '#F4F4F6', '#F4F4F6', '#E9E9ED'], // 每个圈的边框颜色
          },
        },
        splitArea: {
          areaStyle: {
            color: ['#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff'], // 每个圆的背景颜色
          },
        },
        indicator,
      },
      series: series,
    });
  }, [chartData.studentWriteScoreInfo, chartData.writeScoreInfo]);

  const [option, setOption] = useState<any>({});
  useEffect(() => {
    if (!myChart || !option) return;
    myChart.setOption(option);
  }, [option]);

  useMount(() => {
    myChart = echarts.init(chartRef.current!);
    window.addEventListener('resize', () => {
      myChart && option && myChart.resize();
    });
  });
  return <div ref={chartRef} style={{ width: '100%', height: '100%' }}></div>;
});

export default writeChart;