ECharts 快速使用

最终效果

在这里插入图片描述

使用介绍

echarts图表的绘制,大体分为三步:

  1. 根据 DOM实例,通过 echarts.init方法,生成 echarts实例
  2. 构建 options配置对象,整个echarts的样式,皆有该对象决定
  3. 最后通过实例.setOption方法,设置配置对象配置对象是echarts中最复杂的部分,也就是核心。
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
  // 基于准备好的dom,初始化echarts实例
  const myChart = echarts.init(document.getElementById('main'));

  // 指定图表的配置项和数据
  const option = {
    title: {
      text: 'ECharts 入门示例'
    },
    tooltip: {},
    legend: {
      data: ['销量']
    },
    xAxis: {
      data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
    },
    yAxis: {},
    series: [
      {
        name: '销量',
        type: 'bar',
        data: [5, 20, 36, 10, 10, 20]
      }
    ]
  };

  // 使用刚指定的配置项和数据显示图表。
  myChart.setOption(option);
</script>

那么最难的 option 配置对象怎么看呢?这里我们可以跟着官方示例学习:echarts 示例,通过不断修改示例达到我们预期的效果。

还有一个难点,就是如果我们的配置写的不完全或者写的不对,是不能够看到部分效果的,也就是说,要么就是一张完整的图表,要么就是一张空白。

经过上述种种难点,我总结出一个使用 echarts 的好办法,结合 ChatGPT。

我们先向他描述图表的大致形状,然后让它先生成一个能够运行的图表,之后我们不断细化需求,进行更改。

比如:

我:我要使用 echarts 绘制一些图表,但是不知道相关代码配置怎么写,
我需要你按照我接下来的要求给出代码。
ChatGPT:xxx
我:我想绘制一张横向的柱形图,比如柱形图第一行 
坐标为华北,数据为20;第二行 坐标为 西北,数据为30 ;
代码应该怎么写?
ChatGPT:xxx
我:我不想要横坐标。
ChatGPT:xxx

最终生成:

在这里插入图片描述

总之就是这样,逐渐细化需求,直到完成我们的要求为止。

具体示例

这里可以先试用 tailwindcss 进行初始布局搭建。

tailwindcss 结合框架使用跟着文档就就可以。

基本布局

下面均使用 mock 数据。

index

function Index(props) {
  return (
    <div
      style={{
        backgroundImage: `url(${bgImage})`,
        backgroundSize: 'cover',
        backgroundRepeat: 'no-repeat',
        width: '100%',
        height: '94vh',
        color: 'white',
        display: 'flex',
        overflow: 'hidden',
        padding: '5px',
      }}
    >
      {/*左*/}
      <div className="flex-1 mr-2 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
        {/*    横向柱状图*/}
        <HorizontalBar className="h-1/3 box-border pb-4" />
        {/*    雷达图*/}
        <RadarBar className="h-1/3 box-border pb-4" />
        {/*    关系图*/}
        <Relation className="h-1/3" />
      </div>
      {/*中*/}
      <div className="w-1/2 mr-2 flex flex-col">
        {/*    数据总览图*/}
        <TotalData classNmae="bg-opacity-50 bg-slate-800 p-3 " />
        {/*    地图可视化*/}
        <MapChart classNmae="bg-opacity-50 bg-slate-800 p-3 mt-2 flex-1" />
      </div>
      {/*右*/}
      <div className="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
        {/*    竖向柱状图*/}
        <VerticalBar className="h-1/3 box-border pb-4" />
        {/*    环形图*/}
        <RingBar className="h-1/3 box-border pb-4" />
        {/*    文档云图*/}
        <WordCloud className="h-1/3 " />
      </div>
    </div>
  );
}

HorizontalBar

import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function HorizontalBar(props) {
  const data = {
    regions: [
      { id: 1, name: '华北', value: 63 },
      { id: 2, name: '华南', value: 86 },
      { id: 3, name: '华东', value: 85 },
      { id: 4, name: '西南', value: 63 },
      { id: 5, name: '西北', value: 54 },
      { id: 6, name: '东北', value: 79 },
    ],
  };
  // 1. 初始化 echarts 实例
  let myChart = null;
  const target = useRef(null);
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  // 2. 构建 options 配置对象
  const renderChart = () => {
    const options = {
      // x 轴展示数据
      xAxis: {
        // 不显示 x 轴
        show: false,
        // x 轴类型为数据进行展示
        type: 'value',
        // 设置 x 轴最大值
        max: function (value) {
          // 将 x 轴个数据中的的最大值 * 1.2 作为 x 轴的最大值
          return parseInt(value.max * 1.2);
        },
      },
      // y 轴展示数据
      yAxis: {
        // y 轴为类型数据展示
        type: 'category',
        // data 为所需展示的数据
        data: data.regions.map((item) => item.name), // 映射数据
        // 反向展示数据 默认情况从下到上展示数据
        inverse: true,
        // 不展示轴线
        axisLine: {
          show: false,
        },
        // 不展示刻度
        axisTick: {
          show: false,
        },
        axisLabel: {
          color: '#9eb1c8',
        },
      },
      // 图表位置 上下左右
      grid: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0,
        // 包含标签
        containLabel: true,
      },
      // 核心配置
      series: [
        {
          // 柱形图
          type: 'bar',
          // 展示数据
          data: data.regions.map((item) => ({
            name: item.name,
            value: item.value,
          })),
          showBackground: true,
          backgroundStyle: {
            color: 'rgba(180,180,180,0.2)',
          },
          // x 数据项样式
          itemStyle: {
            color: '#479AD3',
            barBorderRadius: 5,
            shadowColor: 'rgba(0,0,0,0.3)',
            // 阴影模糊
            shadowBlur: 5,
          },
          barWidth: 12,
          // x 上的字体标签
          label: {
            show: true,
            position: 'right',
            textStyle: {
              color: '#fff',
            },
          },
        },
      ],
    };
    // 3. 根据数据构建 options 配置对象 myCharts.setOption(options)
    myChart.setOption(options);
  };

  return (
    <div className={props.className}>
      <div>学生来源信息</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default HorizontalBar;

MapChart

import mapJson from '@/assets/screen/MapData/china.json';
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function MapChart(props) {
  const data = {
    mapData: {
      categoryData: {
        2020: [
          { name: '北京', value: 42 },
          { name: '天津', value: 24 },
          { name: '上海', value: 53 },
          { name: '重庆', value: 64 },
          { name: '河北', value: 87 },
          { name: '河南', value: 52 },
          { name: '云南', value: 14 },
          { name: '辽宁', value: 35 },
          { name: '黑龙江', value: 85 },
          { name: '湖南', value: 95 },
          { name: '安徽', value: 41 },
          { name: '山东', value: 45 },
          { name: '新疆', value: 56 },
          { name: '江苏', value: 43 },
          { name: '浙江', value: 56 },
          { name: '江西', value: 63 },
          { name: '湖北', value: 41 },
          { name: '广西', value: 23 },
          { name: '甘肃', value: 56 },
          { name: '山西', value: 62 },
          { name: '内蒙古', value: 64 },
          { name: '陕西', value: 54 },
          { name: '吉林', value: 34 },
          { name: '福建', value: 16 },
          { name: '贵州', value: 71 },
          { name: '广东', value: 32 },
          { name: '青海', value: 56 },
          { name: '西藏', value: 52 },
          { name: '四川', value: 63 },
          { name: '宁夏', value: 74 },
          { name: '海南', value: 51 },
        ],
        2021: [
          { name: '北京', value: 76 },
          { name: '天津', value: 54 },
          { name: '上海', value: 23 },
          { name: '重庆', value: 64 },
          { name: '河北', value: 54 },
          { name: '河南', value: 52 },
          { name: '云南', value: 34 },
          { name: '辽宁', value: 35 },
          { name: '黑龙江', value: 65 },
          { name: '湖南', value: 95 },
          { name: '安徽', value: 34 },
          { name: '山东', value: 34 },
          { name: '新疆', value: 56 },
          { name: '江苏', value: 76 },
          { name: '浙江', value: 23 },
          { name: '江西', value: 65 },
          { name: '湖北', value: 41 },
          { name: '广西', value: 34 },
          { name: '甘肃', value: 43 },
          { name: '山西', value: 65 },
          { name: '内蒙古', value: 64 },
          { name: '陕西', value: 54 },
          { name: '吉林', value: 98 },
          { name: '福建', value: 76 },
          { name: '贵州', value: 71 },
          { name: '广东', value: 65 },
          { name: '青海', value: 56 },
          { name: '西藏', value: 43 },
          { name: '四川', value: 63 },
          { name: '宁夏', value: 54 },
          { name: '海南', value: 51 },
        ],
        2022: [
          { name: '北京', value: 23 },
          { name: '天津', value: 24 },
          { name: '上海', value: 43 },
          { name: '重庆', value: 64 },
          { name: '河北', value: 65 },
          { name: '河南', value: 52 },
          { name: '云南', value: 14 },
          { name: '辽宁', value: 35 },
          { name: '黑龙江', value: 98 },
          { name: '湖南', value: 95 },
          { name: '安徽', value: 65 },
          { name: '山东', value: 45 },
          { name: '新疆', value: 56 },
          { name: '江苏', value: 87 },
          { name: '浙江', value: 65 },
          { name: '江西', value: 63 },
          { name: '湖北', value: 54 },
          { name: '广西', value: 45 },
          { name: '甘肃', value: 56 },
          { name: '山西', value: 62 },
          { name: '内蒙古', value: 64 },
          { name: '陕西', value: 54 },
          { name: '吉林', value: 23 },
          { name: '福建', value: 16 },
          { name: '贵州', value: 54 },
          { name: '广东', value: 32 },
          { name: '青海', value: 21 },
          { name: '西藏', value: 52 },
          { name: '四川', value: 43 },
          { name: '宁夏', value: 32 },
          { name: '海南', value: 51 },
        ],
        2023: [
          { name: '北京', value: 65 },
          { name: '天津', value: 54 },
          { name: '上海', value: 53 },
          { name: '重庆', value: 64 },
          { name: '河北', value: 23 },
          { name: '河南', value: 52 },
          { name: '云南', value: 43 },
          { name: '辽宁', value: 35 },
          { name: '黑龙江', value: 85 },
          { name: '湖南', value: 95 },
          { name: '安徽', value: 34 },
          { name: '山东', value: 45 },
          { name: '新疆', value: 56 },
          { name: '江苏', value: 42 },
          { name: '浙江', value: 56 },
          { name: '江西', value: 63 },
          { name: '湖北', value: 41 },
          { name: '广西', value: 23 },
          { name: '甘肃', value: 23 },
          { name: '山西', value: 62 },
          { name: '内蒙古', value: 64 },
          { name: '陕西', value: 54 },
          { name: '吉林', value: 34 },
          { name: '福建', value: 43 },
          { name: '贵州', value: 65 },
          { name: '广东', value: 32 },
          { name: '青海', value: 56 },
          { name: '西藏', value: 52 },
          { name: '四川', value: 76 },
          { name: '宁夏', value: 43 },
          { name: '海南', value: 51 },
        ],
        2024: [
          { name: '北京', value: 31 },
          { name: '天津', value: 54 },
          { name: '上海', value: 53 },
          { name: '重庆', value: 64 },
          { name: '河北', value: 33 },
          { name: '河南', value: 52 },
          { name: '云南', value: 54 },
          { name: '辽宁', value: 42 },
          { name: '黑龙江', value: 85 },
          { name: '湖南', value: 95 },
          { name: '安徽', value: 41 },
          { name: '山东', value: 45 },
          { name: '新疆', value: 56 },
          { name: '江苏', value: 53 },
          { name: '浙江', value: 56 },
          { name: '江西', value: 43 },
          { name: '湖北', value: 64 },
          { name: '广西', value: 23 },
          { name: '甘肃', value: 56 },
          { name: '山西', value: 65 },
          { name: '内蒙古', value: 64 },
          { name: '陕西', value: 54 },
          { name: '吉林', value: 34 },
          { name: '福建', value: 54 },
          { name: '贵州', value: 71 },
          { name: '广东', value: 13 },
          { name: '青海', value: 56 },
          { name: '西藏', value: 52 },
          { name: '四川', value: 23 },
          { name: '宁夏', value: 74 },
          { name: '海南', value: 51 },
        ],
      },
      colors: [
        '#1DE9B6',
        '#F46E36',
        '#04B9FF',
        '#5DBd32',
        '#FFC809',
        '#FB05D5',
        '#BDA29A',
        '#6E7074',
        '#546570',
        '#C4CCD3',
      ],
      topData: {
        2020: [
          {
            name: '天津',
            value: [117.4219, 39.4189, 84.1],
          },
          {
            name: '河北',
            value: [114.4995, 38.1006, 85.8],
          },
          {
            name: '河南',
            value: [113.4668, 34.6234, 83.6],
          },
          {
            name: '北京',
            value: [116.4551, 40.2539, 83.2],
          },
          {
            name: '山东',
            value: [117.1582, 36.8701, 82.5],
          },
          {
            name: '安徽',
            value: [117.29, 32.0581, 81.7],
          },
          {
            name: '湖北',
            value: [114.3896, 30.6628, 81.4],
          },
          {
            name: '江苏',
            value: [118.8062, 31.9208, 81.1],
          },
          {
            name: '新疆',
            value: [87.9236, 43.5883, 80.4],
          },
          {
            name: '湖南',
            value: [113.0823, 28.2568, 80.1],
          },
        ],
        2021: [
          {
            name: '天津',
            value: [117.4219, 39.4189, 84.1],
          },
          {
            name: '河北',
            value: [114.4995, 38.1006, 85.8],
          },
          {
            name: '河南',
            value: [113.4668, 34.6234, 83.6],
          },
          {
            name: '北京',
            value: [116.4551, 40.2539, 83.2],
          },
          {
            name: '山东',
            value: [117.1582, 36.8701, 82.5],
          },
          {
            name: '安徽',
            value: [117.29, 32.0581, 81.7],
          },
          {
            name: '湖北',
            value: [114.3896, 30.6628, 81.4],
          },
          {
            name: '江苏',
            value: [118.8062, 31.9208, 81.1],
          },
          {
            name: '新疆',
            value: [87.9236, 43.5883, 80.4],
          },
          {
            name: '湖南',
            value: [113.0823, 28.2568, 80.1],
          },
        ],
        2022: [
          {
            name: '天津',
            value: [117.4219, 39.4189, 84.1],
          },
          {
            name: '河北',
            value: [114.4995, 38.1006, 85.8],
          },
          {
            name: '河南',
            value: [113.4668, 34.6234, 83.6],
          },
          {
            name: '北京',
            value: [116.4551, 40.2539, 83.2],
          },
          {
            name: '山东',
            value: [117.1582, 36.8701, 82.5],
          },
          {
            name: '安徽',
            value: [117.29, 32.0581, 81.7],
          },
          {
            name: '湖北',
            value: [114.3896, 30.6628, 81.4],
          },
          {
            name: '江苏',
            value: [118.8062, 31.9208, 81.1],
          },
          {
            name: '新疆',
            value: [87.9236, 43.5883, 80.4],
          },
          {
            name: '湖南',
            value: [113.0823, 28.2568, 80.1],
          },
        ],
        2023: [
          {
            name: '天津',
            value: [117.4219, 39.4189, 84.1],
          },
          {
            name: '河北',
            value: [114.4995, 38.1006, 85.8],
          },
          {
            name: '河南',
            value: [113.4668, 34.6234, 83.6],
          },
          {
            name: '北京',
            value: [116.4551, 40.2539, 83.2],
          },
          {
            name: '山东',
            value: [117.1582, 36.8701, 82.5],
          },
          {
            name: '安徽',
            value: [117.29, 32.0581, 81.7],
          },
          {
            name: '湖北',
            value: [114.3896, 30.6628, 81.4],
          },
          {
            name: '江苏',
            value: [118.8062, 31.9208, 81.1],
          },
          {
            name: '新疆',
            value: [87.9236, 43.5883, 80.4],
          },
          {
            name: '湖南',
            value: [113.0823, 28.2568, 80.1],
          },
        ],
        2024: [
          {
            name: '天津',
            value: [117.4219, 39.4189, 84.1],
          },
          {
            name: '河北',
            value: [114.4995, 38.1006, 85.8],
          },
          {
            name: '河南',
            value: [113.4668, 34.6234, 83.6],
          },
          {
            name: '北京',
            value: [116.4551, 40.2539, 83.2],
          },
          {
            name: '山东',
            value: [117.1582, 36.8701, 82.5],
          },
          {
            name: '安徽',
            value: [117.29, 32.0581, 81.7],
          },
          {
            name: '湖北',
            value: [114.3896, 30.6628, 81.4],
          },
          {
            name: '江苏',
            value: [118.8062, 31.9208, 81.1],
          },
          {
            name: '新疆',
            value: [87.9236, 43.5883, 80.4],
          },
          {
            name: '湖南',
            value: [113.0823, 28.2568, 80.1],
          },
        ],
      },
      voltageLevel: ['2020', '2021', '2022', '2023', '2024'],
    },
  };
  const target = useRef(null);
  let myChart = null;

  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  const renderChart = () => {
    // echarts 渲染
    echarts.registerMap('china', mapJson);

    let options = {
      // 时间线,提供了在多个 ECharts option 间进行切换
      timeline: {
        // 数据
        data: data.mapData.voltageLevel,
        // 类目轴
        axisType: 'category',
        // 自动切换
        autoPlay: true,
        // 间隔时间
        playInterval: 3000,
        // 位置
        left: '10%',
        right: '10%',
        bottom: '0%',
        width: '80%',
        // 轴的文本标签
        label: {
          // 默认状态
          normal: {
            textStyle: {
              color: '#ddd',
            },
          },
          // 高亮状态
          emphasis: {
            textStyle: {
              color: '#fff',
            },
          },
        },
        // 文字大小
        symbolSize: 10,
        // 线的样式
        lineStyle: {
          color: '#555',
        },
        // 选中点的样式
        checkpointStyle: {
          borderColor: '#888',
          borderWidth: 2,
        },
        // 控件样式
        controlStyle: {
          // 上一步按钮
          showNextBtn: true,
          // 下一步按钮
          showPrevBtn: true,
          // 默认样式
          normal: {
            color: '#666',
            borderColor: '#666',
          },
          // 高亮样式
          emphasis: {
            color: '#aaa',
            borderColor: '#aaa',
          },
        },
      },
      // 柱形图右侧展示
      baseOption: {
        grid: {
          right: '2%',
          top: '15%',
          bottom: '10%',
          width: '20%',
        },

        // 中国地图
        geo: {
          // 展示
          show: true,
          // 中国地图
          map: 'china',
          // 开启缩放
          roam: true,
          // 初始缩放
          zoom: 0.8,
          // 中心点
          center: [113.83531246, 34.0267395887],
          // 默认状态的省份样式
          itemStyle: {
            normal: {
              // 边框色值
              borderColor: 'rgba(147, 235, 248, 1)',
              // 边框宽度
              borderWidth: 1,
              // 区域颜色
              areaColor: {
                // 经向色值
                type: 'radial',
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  // 0% 处的颜色
                  {
                    offset: 0,
                    color: 'rgba(147, 235, 248, 0)',
                  },
                  // 100% 处的颜色
                  {
                    offset: 1,
                    color: 'rgba(147, 235, 248, .2)',
                  },
                ],
                // 缺省为 false
                globalCoord: false,
              },
            },
            // 鼠标移入的色值
            emphasis: {
              areaColor: '#389BB7',
              borderWidth: 0,
            },
          },
        },
      },
      // 绑定时间轴的多个图表
      options: [],
    };

    // 为每一年度的图表添加数据
    data.mapData.voltageLevel.forEach((item, index) => {
      options.options.push({
        // 背景色
        backgroundColor: '#142037',
        title: [
          // 主标题,对应地图
          {
            text: '2020-2024 年度使用人数统计',
            left: '0%',
            top: '0',
            textStyle: {
              color: '#ccc',
              fontSize: 30,
            },
          },
          // 副标题,对应柱形图
          {
            id: 'statistic',
            text: item + '年数据统计情况',
            right: '0%',
            top: '4%',
            textStyle: {
              color: '#ccc',
              fontSize: 20,
            },
          },
        ],
        // X 轴配置
        xAxis: {
          // 数据轴
          type: 'value',
          // 脱离 0 值比例
          scale: true,
          // 位置
          position: 'top',
          // 不显示分割线
          splitLine: {
            show: false,
          },
          // 不显示轴线
          axisLine: {
            show: false,
          },
          // 不显示刻度尺
          axisTick: {
            show: false,
          },
          // 类别文字
          axisLabel: {
            margin: 2,
            textStyle: {
              color: '#aaa',
            },
          },
        },
        // Y 轴
        yAxis: {
          // 选项轴
          type: 'category',
          // 轴线
          axisLine: {
            show: true,
            lineStyle: {
              color: '#ddd',
            },
          },
          // 轴刻度
          axisTick: {
            show: false,
            lineStyle: {
              color: '#ddd',
            },
          },
          // 轴标签
          axisLabel: {
            interval: 0,
            textStyle: {
              color: '#ddd',
            },
          },
          // 根据年份,获取对应数据
          data: data.mapData.categoryData[item].map((item) => item.name),
        },
        // 核心配置
        series: [
          // 柱形图
          {
            zlevel: 1.5,
            // 柱形图
            type: 'bar',
            // 每个柱子的色值
            itemStyle: {
              normal: {
                color: data.mapData.colors[index],
              },
            },
            // 根据年份,获取对应数据
            data: data.mapData.categoryData[item].map((item) => item.value),
          },
          // 散点图
          {
            // 散点(气泡)图
            type: 'effectScatter',
            // 使用地理坐标系
            coordinateSystem: 'geo',
            // 数据
            data: data.mapData.topData[item],
            // 标记大小
            symbolSize: function (val) {
              return val[2] / 4;
            },
            // 绘制完成后显示特效
            showEffectOn: 'render',
            // 展示涟漪特效
            rippleEffect: {
              brushType: 'stroke',
            },
            // 文字
            label: {
              normal: {
                formatter: '{b}',
                position: 'right',
                show: true,
              },
            },
            // 每一项的配置
            itemStyle: {
              normal: {
                color: data.mapData.colors[index],
                // 阴影配置
                shadowBlur: 5,
                shadowColor: data.mapData.colors[index],
              },
            },
            zlevel: 1,
          },
        ],
      });
    });

    myChart.setOption(options);
  };
  return <div ref={target} className={props.classNmae}></div>;
}

export default MapChart;

RadarBar

import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function RadarBar(props) {
  const data = {
    regions: [
      { id: 1, name: '华北', value: 63 },
      { id: 2, name: '华南', value: 86 },
      { id: 3, name: '华东', value: 85 },
      { id: 4, name: '西南', value: 63 },
      { id: 5, name: '西北', value: 54 },
      { id: 6, name: '东北', value: 79 },
    ],
  };
  const target = useRef(null);
  let myChart = null;
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  const renderChart = () => {
    const options = {
      // 雷达图的坐标系位置
      radar: {
        name: {
          textStyle: {
            color: '#05D5FF',
            fontSize: 14,
          },
        },
        shape: 'polygon', // 雷达图绘制类型,支持 'polygon' 和 'circle'
        center: ['50%', '50%'],
        radius: '80%', // 雷达图半径
        startAngle: 120,
        // 轴线
        axisLine: {
          lineStyle: {
            color: 'rgba(5,213,255,.8)',
          },
        },
        // 分割线(网格线)
        splitLine: {
          show: true,
          lineStyle: {
            width: 1,
            color: 'rgba(5,213,255,.8)', // 分割线颜色
          },
        },
        // 指示器(文字指示)
        indicator: data.regions.map((item) => {
          return {
            name: item.name,
            max: 100,
          };
        }),
        splitArea: {
          show: false,
        },
      },
      // 坐标极点
      polar: {
        center: ['50%', '50%'],
        radius: '0%',
      },
      // 坐标角度
      angleAxis: {
        min: 0,
        // 分割间隔
        interval: 5,
        clockwise: false, // 刻度增长是否按照顺时针 默认顺时针
      },
      // 径向轴
      radiusAxis: {
        min: 0,
        interval: 20,
        splitLine: {
          show: true,
        },
      },
      // 核心配置 只有一个对象直接可以写对象 多个对象使用数组包裹
      series: {
        type: 'radar',
        symbol: 'circle', // 标记图形类型
        symbolSize: 10, // 标记拐角大小
        itemStyle: {
          normal: {
            color: '#05D5FF',
          },
        },
        // 填充 style
        areaStyle: {
          normal: {
            color: '#05D5FF',
            opacity: 0.5,
          },
        },
        lineStyle: {
          width: 2,
          color: '#05D5FF',
        },
        label: {
          normal: {
            show: true,
            color: '#fff',
          },
        },
        data: [
          {
            value: data.regions.map((item) => item.value),
          },
        ],
      },
    };
    myChart.setOption(options);
  };
  return (
    <div className={props.className}>
      <div>监控云端方位报警风险</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default RadarBar;

Relation

import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function Relation(props) {
  const data = {
    relations: [
      {
        id: 1,
        name: '软件工程II',
        source: '软件工程II',
        speed: 66,
        target: '软件工程I',
        value: [0, 300],
      },
      {
        id: 2,
        name: '软件概述',
        source: '软件工程I',
        speed: 78,
        target: '软件概述',
        value: [100, 300],
      },
      {
        id: 3,
        name: '软件内容',
        source: '软件工程I',
        speed: 92,
        target: '软件内容',
        value: [100, 100],
      },
      {
        id: 4,
        name: '软件导论',
        source: '软件导论',
        speed: 33,
        target: '软件工程I',
        value: [0, 100],
      },
      { id: 0, name: '软件工程I', speed: 117, value: [50, 200] },
    ],
  };
  const target = useRef(null);
  let myChart = null;
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  const renderChart = () => {
    const options = {
      // X 轴不需要展示
      xAxis: {
        show: false,
        type: 'value',
      },
      // Y 轴不需要展示
      yAxis: {
        show: false,
        type: 'value',
      },
      // 核心数据配置
      series: [
        {
          // 用于展现节点以及节点之间的关系数据
          type: 'graph',
          // 不采用任何布局
          layout: 'none',
          // 使用二维的直角坐标系
          coordinateSystem: 'cartesian2d',
          // 节点标记的大小
          symbolSize: 26,
          // z-index
          z: 3,
          // 边界标签(线条文字)
          edgeLabel: {
            normal: {
              show: true,
              color: '#fff',
              textStyle: {
                fontSize: 14,
              },
              formatter: function (params) {
                let txt = '';
                if (params.data.speed !== undefined) {
                  txt = params.data.speed;
                }
                return txt;
              },
            },
          },
          // 圆饼下文字
          label: {
            normal: {
              show: true,
              position: 'bottom',
              color: '#5e5e5e',
            },
          },
          // 边两端的标记类型
          edgeSymbol: ['none', 'arrow'],
          // 边两端的标记大小
          edgeSymbolSize: 8,
          // 圆数据
          data: data.relations.map((item) => {
            // id 为 0 ,表示数据中心,数据中心单独设置
            if (item.id !== 0) {
              return {
                name: item.name,
                category: 0,
                active: true,
                speed: `${item.speed}kb/s`,
                // 位置
                value: item.value,
              };
            } else {
              return {
                name: item.name,
                // 位置
                value: item.value,
                // 数据中心圆的大小
                symbolSize: 100,
                // 圆的样式
                itemStyle: {
                  normal: {
                    // 渐变色
                    color: {
                      colorStops: [
                        { offset: 0, color: '#157eff' },
                        { offset: 1, color: '#35c2ff' },
                      ],
                    },
                  },
                },
                // 字体
                label: { normal: { fontSize: '14' } },
              };
            }
          }),
          // 线
          links: data.relations.map((item, index) => ({
            // 方向
            source: item.source,
            target: item.target,
            // 线上的文字
            speed: `${item.speed}%`,
            // 线的样式
            lineStyle: { normal: { color: '#12b5d0', curveness: 0.2 } },
            // 文字位置
            label: {
              show: true,
              position: 'middle',
              offset: [10, 0],
            },
          })),
        },
        {
          // 用于带有起点和终点信息的线数据的绘制
          type: 'lines',
          // 使用二维的直角坐标系
          coordinateSystem: 'cartesian2d',
          // z-index
          z: 1,
          // 线特效的配置
          effect: {
            show: true,
            smooth: false,
            trailLength: 0,
            symbol: 'arrow',
            color: 'rgba(55,155,255,0.5)',
            symbolSize: 12,
          },
          // 线的样式
          lineStyle: {
            normal: {
              curveness: 0.2,
            },
          },
          // 线的数据级,前后线需要重合。数据固定
          data: [
            [{ coord: [0, 300] }, { coord: [50, 200] }],
            [{ coord: [0, 100] }, { coord: [50, 200] }],
            [{ coord: [50, 200] }, { coord: [100, 100] }],
            [{ coord: [50, 200] }, { coord: [100, 300] }],
          ],
        },
      ],
    };
    myChart.setOption(options);
  };
  return (
    <div className={props.className}>
      <div>知识溯源概念模型</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default Relation;

RingBar

import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function RingBar(props) {
  const data = {
    courses: [
      { id: 1, name: '软件工程概论', value: 1363 },
      { id: 2, name: 'Java程序设计', value: 1086 },
      { id: 3, name: '计算机网络', value: 666 },
      { id: 4, name: '操作系统', value: 999 },
      { id: 5, name: '数据结构与算法', value: 765 },
    ],
  };
  const target = useRef(null);
  let myChart = null;
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  /**
   * 双环形图绘制原理:
   * 1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠
   * 2. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图
   * 3. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染
   */
  const getSeriesData = () => {
    const series = [];

    data.courses.forEach((item, index) => {
      // 上层环形绘制
      series.push({
        name: item.name,
        // 使用饼图绘制,减少饼图宽度即为环形图
        type: 'pie',
        // 逆时针排布
        clockWise: false,
        // 不展示鼠标移入动画
        hoverAnimation: false,
        // 半径位置,需要依次递减,否则会重复在一处进行展示
        radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
        // 中心点
        center: ['55%', '55%'],
        // 不展示 label
        label: { show: false },
        // 数据配置
        data: [
          // 设置数据与名称
          { value: item.value, name: item.name },
          // 最大数据,展示比例
          {
            value: 1000,
            name: '',
            itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
            tooltip: { show: false },
            hoverAnimation: false,
          },
        ],
      });

      // 底层图
      series.push({
        name: item.name,
        type: 'pie',
        // 图形不响应事件
        silent: true,
        // z-index: 置于底层
        z: 1,
        // 逆时针排布
        clockWise: false,
        // 不展示鼠标移入动画
        hoverAnimation: false,
        // 半径位置,需要依次递减,否则会重复在一处进行展示
        radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
        // 中心点
        center: ['55%', '55%'],
        // 不展示 label
        label: { show: false },
        // 数据
        data: [
          // 绘制底线 75%
          {
            value: 7.5,
            itemStyle: { color: 'rgb(3, 31, 62)', borderWidth: 0 },
            tooltip: { show: false },
            hoverAnimation: false,
          },
          // 绘制底线 25% 透明区域
          {
            value: 2.5,
            name: '',
            itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
            tooltip: { show: false },
            hoverAnimation: false,
          },
        ],
      });
    });

    return series;
  };
  const renderChart = () => {
    const options = {
      // 图例配置
      legend: {
        show: true,
        // 图例色块
        icon: 'circle',
        // 位置
        top: '14%',
        left: '60%',
        // 图例展示数据
        data: data.courses.map((item) => item.name),
        // 总宽度(一列)
        width: -5,
        // 每个色块的宽
        itemWidth: 10,
        // 每个色块的高度
        itemHeight: 10,
        // item 间距
        itemGap: 6,
        // 展示内容
        formatter: function (name) {
          return '{title|' + name + '}';
        },
        // 字体配置
        textStyle: {
          rich: {
            title: {
              fontSize: 12,
              lineHeight: 5,
              color: 'rgba(255,255,255,0.8)',
            },
          },
        },
      },
      // 提示层(鼠标移上去的提示信息)
      tooltip: {
        show: true,
        trigger: 'item',
        formatter: '{a}<br>{b}:{c}({d}%)',
      },
      // Y 轴展示选项
      yAxis: [
        {
          type: 'category',
          // 反向展示
          inverse: true,
          // 不展示轴线
          axisLine: {
            show: false,
          },
          // 不展示刻度
          axisTick: {
            show: false,
          },
        },
      ],
      // X 轴不展示(没有 x 轴)
      xAxis: [
        {
          show: false,
        },
      ],
      // 每两个标记一条线 相当于 10 个饼图
      series: getSeriesData(),
    };
    myChart.setOption(options);
  };
  return (
    <div className={props.className}>
      <div>课程掌握熟练度处理</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default RingBar;

TotalData

// import * as echarts from 'echarts';
import '@/assets/screen/fonts/css/style.css';
import { CountUp } from 'countup.js';
import { useEffect, useRef } from 'react';

function TotalData(props) {
  const data = {
    totalData: {
      db: '65446',
      hb: '87788',
      hd: '76456',
      total: '6784739',
      xb: '75753',
      xn: '74564',
      zn: '42135',
    },
  };
  const totalCountTarget = useRef(null);
  const city1 = useRef(null);
  const city2 = useRef(null);
  const city3 = useRef(null);
  const city4 = useRef(null);
  const city5 = useRef(null);
  const city6 = useRef(null);

  useEffect(() => {
    new CountUp(totalCountTarget.current, data.totalData.total).start();
    new CountUp(city1.current, data.totalData.hb).start();
    new CountUp(city2.current, data.totalData.db).start();
    new CountUp(city3.current, data.totalData.hd).start();
    new CountUp(city4.current, data.totalData.zn).start();
    new CountUp(city5.current, data.totalData.xn).start();
    new CountUp(city6.current, data.totalData.xb).start();
  }, []);

  return (
    <div className={props.className}>
      <div className="p-6">
        <div className="text-slate-300 text-center">
          数据总量:
          <span
            ref={totalCountTarget}
            className="text-7xl ml-2 mr-2 font-bold font-[Electronic] text-gradient"
          >
            679,473,929
          </span>
          条记录
        </div>
        <div className="mt-3 flex flex-wrap">
          <div className="w-1/3 text-center text-slate-400 text-sm">
            抬头:
            <span
              ref={city1}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
          <div className="w-1/3 text-center text-slate-400 text-sm">
            睡觉:
            <span
              ref={city2}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
          <div className="w-1/3 text-center text-slate-400 text-sm">
            举手:
            <span
              ref={city3}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
          <div className="w-1/3 text-center text-slate-400 text-sm">
            低头:
            <span
              ref={city4}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
          <div className="w-1/3 text-center text-slate-400 text-sm">
            站立:
            <span
              ref={city5}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
          <div className="w-1/3 text-center text-slate-400 text-sm">
            坐直:
            <span
              ref={city6}
              className="text-[#5DC5EF] text-3xl font-[Electronic]"
            >
              8,778,988
            </span>
          </div>
        </div>
      </div>
    </div>
  );
}

export default TotalData;

VerticalBar

import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

function VerticalBar(props) {
  const data = {
    servers: [
      { id: 1, name: '很好', value: 33 },
      { id: 2, name: '较好', value: 20 },
      { id: 3, name: '略好', value: 13 },
      { id: 4, name: '略差', value: 17 },
      { id: 5, name: '较差', value: 14 },
      { id: 6, name: '很差', value: 3 },
    ],
  };
  const target = useRef(null);
  let myChart = null;
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  const renderChart = () => {
    const options = {
      // X 轴展示选项
      xAxis: {
        type: 'category',
        // 根据根据服务端数据筛选
        data: data.servers.map((item) => item.name),
        // 文字色值
        axisLabel: {
          color: '#9EB1C8',
        },
      },
      // Y 轴展示数据
      yAxis: {
        // 数据展示
        type: 'value',
        // 不显示轴
        show: false,
        // 最大值(防止触顶)
        max: function (value) {
          // 取整
          return parseInt(value.max * 1.2);
        },
      },
      // echarts 网格绘制的位置,对应 上、右、下、左
      grid: {
        top: 16,
        right: 0,
        bottom: 26,
        left: -26,
        // 计算边距时,包含标签
        containLabel: true,
      },
      // 柱形图核心配置
      series: [
        {
          // 柱形图
          type: 'bar',
          // 数据筛选
          data: data.servers.map((item) => ({
            name: item.name,
            value: item.value,
          })),
          // 每个轴的样式
          itemStyle: {
            color: '#479AD3', // 设置柱子的颜色
            barBorderRadius: 5, // 设置柱子的圆角
            shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色
            shadowBlur: 5, // 设置柱子的阴影模糊大小
          },
          // 柱子宽度
          barWidth: 12,
          // 文本
          label: {
            show: true,
            // 设置标签位置为右侧
            position: 'top',
            textStyle: {
              // 设置标签文本颜色
              color: '#fff',
            },
            // 格式化展示数值
            formatter: '{c}%',
          },
        },
      ],
    };

    myChart.setOption(options);
  };
  return (
    <div className={props.className}>
      <div>听课抬头率分布占比</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default VerticalBar;

WordCloud

import * as echarts from 'echarts';
import 'echarts-wordcloud';
import { useEffect, useRef } from 'react';

function WordCloud(props) {
  const data = {
    wordData: [
      { value: 24, name: '链表' },
      { value: 18, name: '队列' },
      { value: 16, name: '树' },
      { value: 12, name: 'Java' },
      { value: 10, name: 'JavaScript' },
      { value: 8, name: 'C++' },
      { value: 6, name: '设计模式' },
      { value: 45, name: '算法' },
      { value: 4, name: '数据结构' },
      { value: 2, name: '操作系统' },
      { value: 1, name: '计算机网络' },
      { value: 43, name: '前端' },
      { value: 3, name: '后端' },
      { value: 5, name: '数据库' },
      { value: 7, name: 'HTML' },
      { value: 9, name: 'CSS' },
      { value: 11, name: 'Vue' },
      { value: 13, name: 'React' },
      { value: 15, name: 'Webpack' },
      { value: 17, name: 'Node.js' },
    ],
  };
  const target = useRef(null);
  let myChart = null;
  useEffect(() => {
    myChart = echarts.init(target.current);
    renderChart();
  }, []);
  /**
   * 生成随机色值
   */
  const randomRGB = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
  };
  const renderChart = () => {
    const options = {
      series: [
        {
          // 类型
          type: 'wordCloud',
          // 形状
          shape: 'circle',
          width: '100%',
          height: '100%',
          // 数据映射文本的大小范围
          sizeRange: [12, 52],
          // 文字旋转范围
          rotationRange: [0, 0],
          // 单词之间的间距
          gridSize: 5,
          // 渲染动画
          layoutAnimation: true,
          // 字体
          textStyle: {
            // 随机色值
            color: randomRGB,
          },
          // 高亮字体
          emphasis: {
            textStyle: {
              fontWeight: 'bold',
              color: '#000',
            },
          },
          // 数据
          data: data.wordData,
        },
      ],
    };
    myChart.setOption(options);
  };
  return (
    <div className={props.className}>
      <div>关键词条</div>
      <div ref={target} className="w-full h-full"></div>
    </div>
  );
}

export default WordCloud;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秀秀_heo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值