0


vue3 | 数据可视化实战echarts图表柱状图和饼图的联动

💰前言

个人主页:KinHKin(五年前端)的博客_CSDN博客-vue,css,中秋活动领域博主

在线演示: KinHKin

刚结束了一个vue3项目的前端改造,从一个页面改造成路由系统切换的功能,产品美名曰:UI改版。我们都知道产品的好坏,取决于产品的设计,设计的变动,不一定是业务方的变动,但是一定是产品的需求变动,有时候大费周折在原来的基础上需要重新设计前端布局,组件的传值,条件的判断,主题色的修改,如果想要在自己的受控范围内,这就需要得益于前期的组件抽象,样式变量,这样能达到改一处代码,全局都受益的结果。对于参数的传递,我推荐使用vue3的最新版pania状态管理工具,使用方便,逻辑简单,复用性高。这里需要举个简单的例子:

先来看效果图:

👍🏻实现过程

主要echarts的柱状图和饼图配合点击事件进行数据传值,饼图数据渲染。

📊 柱状图思路

  1. 全局引入echarts
  2. 模拟柱状图数据
  3. 定义关键三个函数:drawPieCharts,BarClick,defaultClick
  4. 初始化数据

整体函数预览:

1.初始化数据

获取dom元素,echarts初始化图表,drawPieCharts来画柱状图,BarClick来初始化柱状图的点击事件。

  1. // 初始化
  2. onMounted(() => {
  3. const chartDom = document.getElementById("pieCharts");
  4. myChart = echarts.init(chartDom);
  5. drawBarCharts(list.value);
  6. BarClick();
  7. });

2.画柱状图

这里面就是普通的echarts画柱状图的方法,需要注意的是visualMap画区域颜色,markLine来默认画出第一条线

  1. // 画柱状图
  2. const drawBarCharts = (list: any[]) => {
  3. // drawPieChart("skip", "");
  4. if (option) {
  5. myChart.dispose(); //释放图表
  6. }
  7. // 折线图 默认配置
  8. option = {
  9. grid: {
  10. top: 40,
  11. },
  12. yAxis: {
  13. type: "category",
  14. axisTick: {
  15. show: false,
  16. },
  17. data: list.map((i) => i.name).reverse(),
  18. },
  19. xAxis: {
  20. type: "value",
  21. },
  22. visualMap: {
  23. type: "piecewise",
  24. show: false,
  25. dimension: 1,
  26. seriesIndex: 1,
  27. pieces: [
  28. {
  29. gt: 4,
  30. lt: 5,
  31. color: "#FFD6D4",
  32. },
  33. ],
  34. },
  35. series: [
  36. {
  37. name: "",
  38. data: list.map((i) => i.total).reverse(),
  39. type: "bar",
  40. barWidth: "50%",
  41. color: "#0072ED",
  42. zlevel: 2,
  43. },
  44. {
  45. name: "line",
  46. type: "line",
  47. areaStyle: {
  48. // color: '#D6F1FF'
  49. },
  50. lineStyle: {
  51. color: "#E2F0FF",
  52. },
  53. data: list.map((i) => i.total).reverse(),
  54. zlevel: 1,
  55. symbol: "none",
  56. markLine: {
  57. silent: true,
  58. data: [
  59. [
  60. {
  61. lineStyle: { color: "#1890FF", type: "dashed", width: 2 },
  62. x: "10%",
  63. y: "22%",
  64. },
  65. {
  66. label: {
  67. color: "#1890FF",
  68. padding: [0, 15, 0, 0], // 重点在这里,这个地方就是定位
  69. position: "insideEndTop",
  70. formatter: `${list[1].name + " " + list[1].total}`, // 默认第二个
  71. },
  72. lineStyle: { color: "#1890FF", type: "dashed", width: 2 },
  73. x: "98%",
  74. y: "22%",
  75. },
  76. ],
  77. ],
  78. },
  79. },
  80. ],
  81. };
  82. // 折线图 点击事件
  83. option && myChart.setOption(option);
  84. };

3.初始化柱状图点击事件BarClick

使用实例化的myChart 和 getZr方法 作用于line上面来调用defaultClick事件

  1. // 初始化柱状图点击事件
  2. const BarClick = () => {
  3. // 折线图 点击事件
  4. myChart.getZr().on("click", "series.line", (params) => {
  5. defaultClick(params, option, myChart, visualMapPieces, list.value);
  6. console.log(params, "params");
  7. barChangeList();
  8. });
  9. };

4.defaultClick事件

用于重绘区域颜色和线上数据,改变bie的数据,根据Y轴的值 预估区间,来获取对应的数组的index。

注意:这里面是估算,不是精确数据。

  1. // 点击事件重置柱状图的颜色区域
  2. function defaultClick(
  3. params: { target: any; offsetY: number; offsetX: any },
  4. option: echarts.EChartsOption,
  5. myChart: {
  6. setOption: (arg0: {
  7. visualMap: {
  8. type: string;
  9. show: boolean;
  10. dimension: number;
  11. seriesIndex: number;
  12. pieces: any;
  13. };
  14. series: any;
  15. }) => void;
  16. },
  17. visualMapPieces: any[],
  18. list: Ref<{ name: string; total: string }[]> | { total: any }[]
  19. ) {
  20. // 折线图 点击事件
  21. console.log(params, "params");
  22. if (!params.target) {
  23. return;
  24. }
  25. let areaIndex = 0; // 值域:[0, 4]的正整数
  26. // 根据Y轴的值 预估区间
  27. if (params.offsetY >= 78 && params.offsetY < 125) {
  28. areaIndex = 4;
  29. } else if (params.offsetY >= 125 && params.offsetY < 148) {
  30. areaIndex = 3;
  31. } else if (params.offsetY >= 148 && params.offsetY < 197) {
  32. areaIndex = 2;
  33. } else if (params.offsetY >= 197 && params.offsetY < 270) {
  34. areaIndex = 1;
  35. } else if (params.offsetY >= 270 && params.offsetY < 296) {
  36. areaIndex = 0;
  37. } else {
  38. areaIndex = null;
  39. }
  40. if (areaIndex === null) return; // 控制第四个区域不能点击
  41. myChart.setOption({
  42. visualMap: {
  43. type: "piecewise",
  44. show: false,
  45. dimension: 1,
  46. seriesIndex: 1,
  47. pieces: visualMapPieces.map((item, index) => {
  48. // 根据点击区域,修改折线图区域的颜色
  49. return index === areaIndex
  50. ? {
  51. agt: index,
  52. lt: index + 1,
  53. color: "#FFD6D4",
  54. }
  55. : { ...item };
  56. }),
  57. },
  58. series: option.series.map((item, index) => {
  59. // 根据点击区域 画指示线
  60. return item.name === "line"
  61. ? {
  62. ...item,
  63. markLine: {
  64. silent: true,
  65. lineStyle: {
  66. type: "dashed",
  67. color: "#1890FF",
  68. },
  69. data: [
  70. [
  71. {
  72. lineStyle: { color: "#1890FF", type: "dashed", width: 1 },
  73. x: params.offsetX,
  74. y: params.offsetY,
  75. },
  76. {
  77. label: {
  78. color: "#1890FF",
  79. padding: [0, 15, 0, 0], // 重点在这里,这个地方就是定位
  80. position: "insideEndTop",
  81. formatter: `${
  82. list[areaIndex - 1 < 0 ? 0 : areaIndex - 1].name
  83. }${list[areaIndex - 1 < 0 ? 0 : areaIndex - 1].total}`,
  84. },
  85. lineStyle: { color: "#1890FF", type: "dashed", width: 1 },
  86. x: "98%",
  87. y: params.offsetY,
  88. },
  89. ],
  90. ],
  91. },
  92. }
  93. : { ...item };
  94. }),
  95. });
  96. }

🆚饼图思路

饼图思路很简单,接受一个props.list 用于数据驱动,需要注意的是饼图要绑定一个key,用于变化数据时候更新。还有在销毁组件里面重新实例化echarts图表对象。

if (option) {
myChart.dispose(); //释放图表
myChart = null;
let chartDom = document.getElementById("barCharts");
myChart = echarts.init(chartDom);
}

代码如下:

  1. <!--功能说明: KinHKin 饼图-->
  2. <template>
  3. <div class="route-watch-bar" id="barCharts" :key="keyOnly"></div>
  4. </template>
  5. <script setup lang="ts">
  6. import { onMounted, ref } from "vue";
  7. import * as echarts from "echarts";
  8. import { watch } from "vue";
  9. type EChartsOption = echarts.EChartsOption;
  10. const keyOnly = new Date().getTime();
  11. let myChart = null;
  12. let option: EChartsOption;
  13. const props = defineProps({
  14. list: Array,
  15. });
  16. const drawBarCharts = () => {
  17. if (option) {
  18. myChart.dispose(); //释放图表
  19. myChart = null;
  20. let chartDom = document.getElementById("barCharts");
  21. myChart = echarts.init(chartDom);
  22. }
  23. option = {
  24. color: ["#0050B3", "#339DFF", "#36CFC9", "#2BAD2B", "#37C1F0", "#096DD9"],
  25. grid: {
  26. top: "50%",
  27. right: "90%",
  28. left: "40%",
  29. },
  30. tooltip: {
  31. trigger: "item",
  32. formatter: "{b} <br/>{d}%",
  33. },
  34. series: [
  35. {
  36. name: "",
  37. type: "pie",
  38. radius: "74%",
  39. roseType: "area",
  40. data: props.list,
  41. label: {
  42. alignTo: "edge",
  43. formatter: "{name|{b}}\n\n{value|{d} %}",
  44. minMargin: 5,
  45. edgeDistance: 10,
  46. lineHeight: 15,
  47. rich: {
  48. name: {
  49. fontSize: 14,
  50. color: "#666",
  51. },
  52. value: {
  53. fontSize: 16,
  54. color: "#1890FF",
  55. },
  56. },
  57. },
  58. emphasis: {
  59. itemStyle: {
  60. shadowBlur: 10,
  61. shadowOffsetX: 0,
  62. shadowColor: "rgba(0, 0, 0, 0.5)",
  63. },
  64. },
  65. },
  66. ],
  67. };
  68. option && myChart.setOption(option);
  69. };
  70. const init = () => {
  71. let chartDom = document.getElementById("barCharts");
  72. myChart = echarts.init(chartDom);
  73. drawBarCharts();
  74. };
  75. onMounted(() => {
  76. init();
  77. });
  78. watch(
  79. () => props.list,
  80. () => {
  81. init();
  82. },
  83. {
  84. deep: true,
  85. }
  86. );
  87. </script>
  88. <style lang="less" scoped>
  89. .route-watch-bar {
  90. width: 100%;
  91. height: 400px;
  92. }
  93. </style>

❤️总结

echarts图表在大数据可视化中间非常实用,图表之间联动效果更具直观性,同时需要掌握echarts的配置,属性,熟练应用功能,要具备抽象思维,封装组件思维,数据驱动页面思维,把基础的功能组件做好,后续的维护和扩展性才会更加方便,码字不易,希望多多支持哈~❤️❤️❤️


本文转载自: https://blog.csdn.net/weixin_42974827/article/details/126975580
版权归原作者 KinHKin(五年前端) 所有, 如有侵权,请联系我们删除。

“vue3 | 数据可视化实战echarts图表柱状图和饼图的联动”的评论:

还没有评论