ECharts:一个基于 JavaScript 的开源可视化图表库。

目录

效果

  一、介绍

 1、官方文档:Apache ECharts

2、官方示例

二、准备工作

1、安装依赖包

 2、示例版本 

三、使用步骤

1、在单页面引入 ' echarts '

2、指定容器并设置容器宽高

3、数据处理(关键点)

        1)y轴左侧自定义富文本样式

        2)y轴右侧显示数值

        3)柱体渐变色

        4)自定义symbol

四、完整示例

  欢迎关注VX公众号:前端小知识营地


效果

  一、介绍

 1、官方文档:Apache ECharts

Apache EChartsApache ECharts,一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。https://echarts.apache.org/zh/index.html

2、官方示例

​​​

二、准备工作

1、安装依赖包

npm install echarts --save

 2、示例版本 

"echarts": "^5.4.3",

三、使用步骤

1、在单页面引入 ' echarts '

import * as echarts from "echarts";

注:上面的代码会引入 ECharts 中所有的图表和组件,如果你不想引入所有组件,也可以使用 ECharts 提供的按需引入的接口来打包必须的组件。详见官方文档:在项目中引入 ECharts - 入门篇 - Handbook - Apache ECharts

2、指定容器并设置容器宽高

<template>
  <div id="barDiagramMain"></div>
</template>

<script lang="ts" setup>
  import * as echarts from "echarts";

  initChart() {
    let chartDom = document.getElementById("barDiagramMain");
    let myChart = echarts.init(chartDom);
    let option;

    ...详见完整示例   
  };
</script>

<style lang="scss" scoped>
#barDiagramMain{
  width: 400px;
  height: 300px;
}
</style>

3、数据处理(关键点)

        1)y轴左侧自定义富文本样式
yAxis: [
  // 左侧标签
  {
    type: 'category',
    inverse: true,
    axisLabel: {
      show: true,
      position: 'top',
      margin: layoutParams.labelYOffset, // 标签Y轴偏移量
      color: '#fff',
      fontSize: layoutParams.fontSize,
      verticalAlign: 'bottom',
      align: 'left',
      lineHeight: layoutParams.barHeight, // 行高匹配柱体高度
      rich: {
        rank: {
          fontWeight: 'bold',
          width: 25,
          fontSize: layoutParams.fontSize
        },
        name: {
          padding: [0, 0, 0, 10],
          fontSize: layoutParams.fontSize
        },
        // NO.1的处理
        rankHighlight: {
          fontWeight: 'bold',
          width: 25,
          fontSize: layoutParams.fontSize,
          color: '#FBE361'
        },
        // NO.1的处理
        nameHighlight: {
          padding: [0, 0, 0, 10],
          fontSize: layoutParams.fontSize,
          color: '#FBE361'
        }
      },
      formatter: function (value: string) {
        const index = deviceData.findIndex(item => item.name === value);
        const rank = index + 1;
        // 索引为0时使用高亮样式,其余用默认样式
        return index === 0 
          ? `{rankHighlight|No.${rank}}  {nameHighlight|${value}}` 
          : `{rank|No.${rank}}  {name|${value}}`;
      }
    },
    ...详见完整示例
  }
]

注:

        2)y轴右侧显示数值
yAxis: [
  ...详见完整示例
  // 右侧数值轴
  {
    type: 'category',
    inverse: true,
    axisTick: 'none',
    axisLine: 'none',
    axisLabel: {
      show: true,
      position: 'top',
      // 偏移量以适配柱体高度
      margin: -layoutParams.barHeight + 22,
      color: '#fff',
      fontSize: layoutParams.fontSize,
      verticalAlign: 'bottom',
      align: 'right',
      lineHeight: layoutParams.barHeight,
      formatter: function (value: number) {
        return `${value}次`;
      }
    },
    data: deviceData.map(item => item.value)
  }
],
        3)柱体渐变色
series: [
  {
    name: '迟到次数',
    type: 'bar',
    barWidth: layoutParams.barWidth,
    barHeight: layoutParams.barHeight, // 使用柱体高度
    barCategoryGap: layoutParams.barGap, // 使用柱体间隔
    zlevel: 2,
    showBackground: true,
    backgroundStyle: {
      color: '#04444D50'
    },
    itemStyle: {
      borderRadius: [3, 3, 3, 3],
      color: (params: any) => getBarGradientColor(params.dataIndex)
    },
    label: {
      show: false
    },
    data: deviceData.map(item => item.value)
  },
  ...详见完整示例
]
        4)自定义symbol
series: [
  ...详见完整示例
  {
    type: 'pictorialBar',
    symbol: (params: any) => params.dataIndex === 0 
      ? `image://${noOne}` 
      : `image://${noNormal}`,
    symbolSize: [12, 20],
    symbolOffset: [3, 0],
    symbolPosition: 'end',
    z: 12,
    zlevel: 12,
    itemStyle: {
      color: '#fff'
    },
    data: deviceData.map(item => item.value)
  }
]

注:https://echarts.apache.org/zh/option.html#series-pictorialBar.symbol

四、完整示例

<template>
  <div id="barDiagramMain"></div>
</template>

<script lang="ts" setup name="barDiagram">
import * as echarts from "echarts";
import { ref, onMounted, nextTick } from "vue";
import noOne from '../../../assets/noOne.png';
import noNormalfrom '../../../assets/noNormal.png';

const layoutParams = {
  barWidth: 8, // 柱体宽度
  barHeight: 22, // 柱体高度
  barGap: '15%', // 柱体间隔比例
  fontSize: 14, // 字体大小
  topOffset: 0, // 图表顶部边距
  labelYOffset: -2, // 标签Y轴偏移量
  iconYOffset: -35 // 图标Y轴偏移量
};

// 渐变色函数
const getBarGradientColor = (index: number) => {
  const colors = [
    { start: '#0D1F32', end: '#FBE361' },
    { start: '#052343', end: '#1899FD' },
    { start: '#052343', end: '#1899FD' },
    { start: '#052343', end: '#1899FD' },
    { start: '#052343', end: '#1899FD' },
  ];

  const colorConfig = colors[Math.min(index, colors.length - 1)];
  return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
    { offset: 0, color: colorConfig.start },
    { offset: 1, color: colorConfig.end }
  ]);
};

const deviceData = [
  { name:'三组', value: 180 },
  { name:'一组', value:150 },
  { name:'四组', value:120 },
  { name:'二组', value:98 },
  { name:"五组", value:68 }
]

const initChart = () => {
  let chartDom = document.getElementById("barDiagramMain");
  let myChart = echarts.init(chartDom);
  let option;

  const maxValue = Math.max(...deviceData.map((item) => item.value), 0);
  
  option = {
    backgroundColor: 'transparent',
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c}次'
    },
    grid: {
      left: -50,
      top: layoutParams.topOffset,
      bottom: -30,
      right: 0,
      containLabel: true
    },
    xAxis: {
      type: 'value',
      show: false,
      max: maxValue * 1.25
    },
    yAxis: [
      // 左侧标签
      {
        type: 'category',
        inverse: true,
        axisLabel: {
          show: true,
          position: 'top',
          margin: layoutParams.labelYOffset, // 标签Y轴偏移量
          color: '#fff',
          fontSize: layoutParams.fontSize,
          verticalAlign: 'bottom',
          align: 'left',
          lineHeight: layoutParams.barHeight, // 行高匹配柱体高度
          rich: {
            rank: {
              fontWeight: 'bold',
              width: 25,
              fontSize: layoutParams.fontSize
            },
            name: {
              padding: [0, 0, 0, 10],
              fontSize: layoutParams.fontSize
            },
            // NO.1的处理
            rankHighlight: {
              fontWeight: 'bold',
              width: 25,
              fontSize: layoutParams.fontSize,
              color: '#FBE361'
            },
            // NO.1的处理
            nameHighlight: {
              padding: [0, 0, 0, 10],
              fontSize: layoutParams.fontSize,
              color: '#FBE361'
            }
          },
          formatter: function (value: string) {
            const index = deviceData.findIndex(item => item.name === value);
            const rank = index + 1;
            // 索引为0时使用高亮样式,其余用默认样式
            return index === 0 
              ? `{rankHighlight|No.${rank}}  {nameHighlight|${value}}` 
              : `{rank|No.${rank}}  {name|${value}}`;
          }
        },
        splitLine: {
          show: false
        },
        axisTick: {
          show: false
        },
        axisLine: {
          show: false
        },
        data: deviceData.map(item => item.name)
      },
      // 右侧数值轴
      {
        type: 'category',
        inverse: true,
        axisTick: 'none',
        axisLine: 'none',
        axisLabel: {
          show: true,
          position: 'top',
          // 偏移量以适配柱体高度
          margin: -layoutParams.barHeight + 22,
          color: '#fff',
          fontSize: layoutParams.fontSize,
          verticalAlign: 'bottom',
          align: 'right',
          lineHeight: layoutParams.barHeight,
          formatter: function (value: number) {
            return `${value}次`;
          }
        },
        data: deviceData.map(item => item.value)
      }
    ],
    series: [
      {
        name: '迟到次数',
        type: 'bar',
        barWidth: layoutParams.barWidth,
        barHeight: layoutParams.barHeight, // 使用柱体高度
        barCategoryGap: layoutParams.barGap, // 使用柱体间隔
        zlevel: 2,
        showBackground: true,
        backgroundStyle: {
          color: '#04444D50'
        },
        itemStyle: {
          borderRadius: [3, 3, 3, 3],
          color: (params: any) => getBarGradientColor(params.dataIndex)
        },
        label: {
          show: false
        },
        data: deviceData.map(item => item.value)
      },
      {
        type: 'pictorialBar',
        symbol: (params: any) => params === maxValue 
          ? `image://${noOne}` 
          : `image://${noNormal}`,
        symbolSize: [12, 20],
        symbolOffset: [3, 0],
        symbolPosition: 'end',
        z: 12,
        zlevel: 12,
        itemStyle: {
          color: '#fff'
        },
        data: deviceData.map(item => item.value)
      }
    ]
  }

  option && myChart.setOption(option);
}

onMounted(async() => {
  await nextTick()
  initChart()
})

</script>

<style lang="scss" scoped>
#barDiagramMain {
  width: 400px;
  height: 300px;
  background-color: #081326;
}
</style>

  欢迎关注VX公众号:前端小知识营地

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐