Riku
2025-09-20 32eedf2857255cf29985ffc0cc73e75eccda39bf
src/utils/echart-util.js
@@ -1,123 +1,168 @@
// 递归的获取obj中的prop属性 解决有时需要取val.obj.prop的情况
function getPropValueLoop(obj, prop) {
  if (typeof prop !== 'string') {
    return obj;
  }
  const props = prop.split('.');
  let result = obj;
  props.forEach((item) => {
    result = result[item];
  });
  return result;
}
function getCount(array, element) {
  let count = 0;
  array.forEach((e) => {
    if (e == element) {
      count++;
    }
  });
  return count;
}
export default {
  /** 将chart图表转化为图片url
   * @param chart: chart图表的实例
   *  */
  chartToImageUrl(chart) {
    const dataURL = chart.getDataURL({
      pixelRatio: 5, // 提高图片质量
      backgroundColor: '#FFFFFF', // 设置背景颜色
      excludeComponents: ['toolbox'], // 排除工具箱组件
      type: 'png' // 输出图片类型为PNG
    });
    return dataURL;
  },
  // 展示 data 数组中对象的 prop 属性的饼图, title 是饼图的标题
  getPieChartByDataAndProp(data, prop, label) {
    let chartData = [];
    function hasThisName(name) {
      for (let index = 0; index < chartData.length; index++) {
        const element = chartData[index];
        if (element.name === name) {
          return true;
function pieChartOption() {
  return {
    color: [
      '#5470c6',
      '#91cc75',
      '#fac858',
      '#ee6666',
      '#73c0de',
      '#3ba272',
      '#fc8452',
      '#9a60b4',
      '#ea7ccc',
      '#514a9d',
      '#2ec7c9',
      '#b6a2de'
    ],
    title: {
      text: `饼图默认名称`,
      left: 'center' // 标题居中显示
    },
    // 添加工具栏配置,包含下载功能
    toolbox: {
      show: true,
      feature: {
        saveAsImage: {
          show: true,
          title: '下载图表',
          type: 'png',
          pixelRatio: 2 // 提高图片清晰度
        }
      }
      return false;
    }
    data.map((item) => {
      const name = getPropValueLoop(item, prop);
      if (hasThisName(name)) {
        chartData.map((item) => {
          if (item.name === name) {
            item.value++;
    },
    tooltip: {
      trigger: 'item', // 饼图使用item触发tooltip
      formatter: '{a} <br/>{b}: {c} ({d}%)' // 显示格式:名称: 数量 (百分比)
    },
    legend: {
      show: false,
      orient: 'vertical',
      left: 'right', // 图例居左垂直排列
      data: ['sample1', 'sample2', 'sample3'] // 图例数据为问题类型名称
    },
    series: [
      {
        name: 'sample',
        type: 'pie', // 图表类型改为饼图
        radius: '60%', // 饼图半径
        center: ['50%', '55%'], // 饼图中心位置
        data: [
          {
            name: 'sample1',
            value: 100
          },
          {
            name: 'sample2',
            value: 200
          },
          {
            name: 'sample3',
            value: 300
          }
        });
      } else {
        chartData.push({
          name: name,
          value: 1
        });
        ],
        label: {
          show: true,
          formatter: '{b}: {c} ({d}%)' // 扇区标签显示:名称: 数量 (百分比)
        }
      }
    });
    ]
  };
}
    return {
      title: {
        text: label,
        left: 'center'
      },
      tooltip: {
        trigger: 'item'
      },
      legend: {
        orient: 'vertical',
        left: 'left'
      },
      series: [
        {
          type: 'pie',
          radius: '50%',
          data: chartData,
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
function barChartOption() {
  return {
    title: {
      text: `柱状图默认名称`,
      left: 'center' // 标题居中显示
    },
    // 添加工具栏配置,包含下载功能
    toolbox: {
      show: true,
      feature: {
        saveAsImage: {
          show: true,
          title: '下载图表',
          type: 'png',
          pixelRatio: 2 // 提高图片清晰度
        }
      ]
    };
  },
  // 展示 data 数组中对象的 prop 属性的直方图, title 是直方图的标题
  getBarChartByDataAndProp(data, prop, title) {
    let series = data.map((item) => getPropValueLoop(item, prop));
    const option = {
      title: {
        text: title //设置标题
      }
    },
    tooltip: {
      trigger: 'axis', // 柱状图使用axis触发tooltip
      axisPointer: {
        type: 'shadow' // 显示阴影指示器
      },
      xAxis: {
        type: 'category',
        data: Array.from(new Set(series)),
        axisLabel: {
          rotate: 45, // 旋转标签,避免重叠
          // 或者
          interval: 0 // 显示所有标签,可能导致重叠,根据需求调整
      formatter: '{b}: {c}' // 显示格式:名称: 数量
    },
    legend: {
      show: true,
      orient: 'horizontal',
      bottom: '0%', // 图例底部水平排列
    },
    grid: {
      // left: '3%',
      // right: '4%',
      bottom: '10%',
      top: '15%',
      containLabel: true
    },
    xAxis: {
      name: '坐标轴',
      type: 'category',
      data: ['sample1', 'sample2', 'sample3'], // X轴数据
      axisTick: {
        alignWithLabel: true
      },
      axisLabel: {
        rotate: 45,
      }
    },
    yAxis: {
      type: 'value',
      name: '数量', // Y轴名称
      axisLine: {
        show: true
      },
      axisLabel: {
        formatter: '{value}'
      }
    },
    series: [
      {
        name: 'sample',
        type: 'bar', // 图表类型改为柱状图
        data: [100, 200, 300], // 数据值
        label: {
          show: true,
          position: 'top', // 标签显示在柱子顶部
          formatter: '{c}' // 标签格式:数量
        }
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: Array.from(new Set(series)).map((item) =>
            getCount(series, item)
          ),
          type: 'bar',
          smooth: true
        }
      ]
    };
    return option;
  }
};
      }
    ]
  };
}
// 通过 ECharts API 下载图片的函数
function downloadChartImage(chart, fileName) {
  if (!chart) return; // 确保图表已初始化
  // 获取图表图片数据(支持 png/jpeg 格式,pixelRatio 控制清晰度)
  const dataURL = chart.getDataURL({
    type: 'png', // 图片格式
    pixelRatio: 2, // 像素比,值越大图片越清晰
    backgroundColor: '#fff', // 背景色(默认透明)
    excludeComponents: ['toolbox']
  });
  // 创建下载链接
  const link = document.createElement('a');
  link.href = dataURL;
  // 设置下载文件名(可根据实际需求调整)
  link.download = `${fileName}.png`;
  // 添加到文档并触发下载
  document.body.appendChild(link);
  link.click();
  // 清理链接元素
  document.body.removeChild(link);
}
export { pieChartOption, barChartOption, downloadChartImage };