文档地址: https://v-charts.js.org/#/

在使用 echarts 生成图表时,经常需要做繁琐的数据类型转化、修改复杂的配置项,v-charts 的出现正是为了解决这个痛点。基于 Vue2.0 和 echarts 封装的 v-charts 图表组件,只需要统一提供一种对前后端都友好的数据格式设置简单的配置项,便可轻松生成常见的图表。

安按照文档引入之后,运行项目,如果报错

This dependency was not found:
* echarts/lib/visual/dataColor in ./node_modules/echarts-liquidfill/src/liquidFill.js
To install it, you can run: npm install —save echarts/lib/visual/dataColor

降级echarts到v4.9.0即可

npm i v-charts echarts@4.9.0 -S

图表 公有属性

所有图表都具有的属性,例如 width, events 等。

:data 设置图表的数据

:setting 图表自身属性

用于设置图表自身属性,例如用于设置数据类型的 yAxisType, 是否展示为面积图的 area等,因为每种图表的自有属性不完全相同,将在具体图表中详细介绍setting的使用。

  1. <ve-line :data="lineChartData" :settings="lineChartSettings"></ve-line>
  2. data() {
  3. this.lineChartSettings = {
  4. stack: { 用户: ["访问用户", "下单用户"] },
  5. area: true, // 折线图 -- 填充整个面积的色块
  6. };
  7. return {
  8. lineChartData: {
  9. columns: ["日期", "访问用户", "下单用户", "下单率"],
  10. rows: [
  11. { 日期: "1/1", 访问用户: 1393, 下单用户: 1093, 下单率: 0.32 },
  12. { 日期: "1/2", 访问用户: 3530, 下单用户: 3230, 下单率: 0.26 },
  13. { 日期: "1/3", 访问用户: 2923, 下单用户: 2623, 下单率: 0.76 },
  14. { 日期: "1/4", 访问用户: 1723, 下单用户: 1423, 下单率: 0.49 },
  15. { 日期: "1/5", 访问用户: 3792, 下单用户: 3492, 下单率: 0.323 },
  16. { 日期: "1/6", 访问用户: 4593, 下单用户: 4293, 下单率: 0.78 },
  17. ],
  18. }
  19. };
  20. }

image.png

:extend

为了能够更方便的设置属性配置项等,可以通过extend属性实现对已配置好的内部属性进行单独的设置

:loading 图表加载状态

  1. <ve-line
  2. :data="chartData"
  3. :loading="loading">
  4. </ve-line>
  5. import 'v-charts/lib/style.css'
  6. loading: true

:data-zoom 设置区域缩放

在使用 dataZoom 组件时,数据发生改变会引起 dataZoom 的重置,在组件上设置:not-set-unchange="['dataZoom']"即可解决这个问题。

:colors 修改颜色列表

  1. <template>
  2. <ve-line
  3. :data="chartData"
  4. :colors="colors">
  5. </ve-line>
  6. </template>
  7. <script>
  8. export default {
  9. data () {
  10. this.colors = ['#c23531','#2f4554', '#61a0a8',
  11. '#d48265', '#91c7ae','#749f83',
  12. '#ca8622', '#bda29a','#6e7074',
  13. '#546570', '#c4ccd3']
  14. return {
  15. chartData: {
  16. columns: ['日期', '成本', '利润'],
  17. rows: [
  18. { '日期': '1月1日', '成本': 15, '利润': 12 },
  19. { '日期': '1月2日', '成本': 12, '利润': 25 },
  20. { '日期': '1月3日', '成本': 21, '利润': 10 },
  21. { '日期': '1月4日', '成本': 41, '利润': 32 },
  22. { '日期': '1月5日', '成本': 31, '利润': 30 },
  23. { '日期': '1月6日', '成本': 71, '利润': 55 }
  24. ]
  25. }
  26. }
  27. }
  28. }
  29. </script>

Demo

柱形图

image.png

  1. template>
  2. <div>
  3. <div class="card-panel">
  4. <h3>报价台量</h3>
  5. <ve-histogram
  6. class="myve"
  7. :data="chartData"
  8. :settings="vchartsConfig.setting"
  9. :extend="vchartsConfig.extend"
  10. ></ve-histogram>
  11. </div>
  12. </div>
  13. </template>
  14. <script>
  15. export default {
  16. name: "AreaChart",
  17. data() {
  18. return {
  19. // v-charts配置参数
  20. vchartsConfig: {
  21. setting: {
  22. // 别称
  23. labelMap: {
  24. area: "地区",
  25. count: "报价台量",
  26. },
  27. },
  28. extend: {
  29. // 左上角图表标题
  30. title: {
  31. show: true,
  32. text: "",
  33. subtext: "各城市台量",
  34. // textAlign:'center',
  35. },
  36. // 图表上方的维度标题及按钮
  37. legend: {
  38. show: true,
  39. },
  40. // backgroundColor:'red',//整个组件的背景颜色
  41. //X轴线
  42. xAxis: {
  43. // name: "地区",
  44. type: "category",
  45. show: true,
  46. // 坐标轴轴线
  47. axisLine: {
  48. show: false,
  49. },
  50. // 坐标轴刻度
  51. axisTick: {
  52. show: false,
  53. },
  54. // 坐标轴每项的文字
  55. axisLabel: {
  56. showMaxLabel: true,
  57. showMinLabel: true,
  58. color: "#3a3a3a",
  59. rotate: 0, //刻度文字旋转,防止文字过多不显示
  60. margin: 18, //文字离x轴的距离
  61. boundaryGap: true,
  62. // backgroundColor:'#0f0',
  63. formatter: (v) => {
  64. // console.log('x--v',v)
  65. if (v.length > 5) {
  66. return v.substring(0, 5) + "...";
  67. }
  68. return v;
  69. },
  70. },
  71. // X轴下面的刻度小竖线
  72. axisTick: {
  73. show: false,
  74. alignWithLabel: true, //axisLabel.boundaryGap=true时有效
  75. interval: 0,
  76. length: 4, //长度
  77. },
  78. // x轴对应的竖线
  79. splitLine: {
  80. show: false,
  81. interval: 0,
  82. lineStyle: {
  83. color: "red",
  84. backgroundColor: "red",
  85. },
  86. },
  87. },
  88. yAxis: {
  89. show: true,
  90. offset: 0,
  91. // 坐标轴轴线
  92. axisLine: {
  93. show: false,
  94. },
  95. // x轴对应的竖线
  96. splitLine: {
  97. show: false,
  98. },
  99. // 坐标轴刻度
  100. axisTick: {
  101. show: false,
  102. },
  103. boundaryGap: false,
  104. axisLabel: {
  105. color: "#3a3a3a",
  106. },
  107. },
  108. // 滚动缩放组件参数
  109. // dataZoom: [
  110. // {
  111. // type: "inside",
  112. // show: true,
  113. // xAxisIndex: [0],
  114. // startValue: 0,
  115. // endValue: 4,
  116. // zoomLock: true, //阻止区域缩放
  117. // },
  118. // ],
  119. // dataZoom: [
  120. // {
  121. // type: "slider",
  122. // startValue: 0,
  123. // endValue: 5, //只显示5个数据
  124. // },
  125. // ],
  126. // 柱形区域
  127. grid: {
  128. show: true,
  129. backgroundColor: "#FFF6F3",
  130. borderColor: "#FFF6F3",
  131. // containLabel:false,
  132. },
  133. // 每个柱子
  134. series(v) {
  135. // console.log("v", v);
  136. // 设置柱子的样式
  137. v.forEach((i) => {
  138. console.log("series", i);
  139. i.barWidth = 20;
  140. i.itemStyle = {
  141. barBorderRadius: [10, 10, 10, 10],
  142. color: "#FF6633",
  143. borderWidth: 0,
  144. };
  145. i.label = {
  146. color: "#666",
  147. show: true,
  148. position: "top", //top inner insideBottom insideRight
  149. // backgroundColor:'yellow',
  150. };
  151. });
  152. return v;
  153. },
  154. },
  155. },
  156. // v-chats列表数据
  157. chartData: {
  158. columns: ["area", "count"],
  159. rows: [
  160. { area: "南宁市", count: 20 },
  161. { area: "柳州市", count: 30 },
  162. { area: "防城港市", count: 12 },
  163. { area: "南市", count: 20 },
  164. { area: "柳市", count: 30 },
  165. { area: "防港市", count: 12 },
  166. { area: "市", count: 20 },
  167. { area: "柳", count: 30 },
  168. { area: "防城市", count: 12 },
  169. { area: "3333333", count: 42 },
  170. ],
  171. },
  172. };
  173. },
  174. created() {},
  175. methods: {},
  176. };
  177. </script>

柱形折线混合图

主要是 label 的设置。设置双 y 轴后 ,折线的 label 也需要设置为百分比

image.png

  1. <template>
  2. <div class="card-panel">
  3. <h3>每月发货台量及完成率</h3>
  4. <ve-histogram
  5. :data="chartData"
  6. :settings="chartSettings"
  7. :extend="chartExtend"
  8. ></ve-histogram>
  9. </div>
  10. </template>
  11. <script>
  12. import { sendChart } from "@/api/install/chart";
  13. export default {
  14. data() {
  15. this.chartSettings = {
  16. showLine: ["percent"], //展示为折线图的指标
  17. axisSite: { right: ["percent"] }, //指标所在的轴 默认不在right轴的指标都在left轴
  18. yAxisType: ["KMB", "percent"], //左右坐标轴数据类型; KMB, normal, percent
  19. yAxisName: ["台量", "完成率"], //左右坐标轴标题
  20. labelMap: { count: "发货台量", percent: "完成率" }, //设置指标的别名,同时作用于提示框和图例
  21. };
  22. this.chartExtend = {
  23. // 图表上方的维度标题及按钮
  24. legend: {
  25. show: true,
  26. left: "center",
  27. bottom: "bottom",
  28. },
  29. // 柱形区域
  30. grid: {
  31. show: true,
  32. backgroundColor: "#FFF6F3",
  33. borderColor: "#FFF6F3",
  34. },
  35. // 每个柱子
  36. series(v) {
  37. // 设置发货台量 柱形图样式
  38. v[0].barWidth = 30;
  39. v[0].itemStyle = {
  40. barBorderRadius: [15, 15, 15, 15],
  41. color: "#727CF5",
  42. };
  43. v[0].label = {
  44. color: "#3a3a3a",
  45. show: true,
  46. position: "top", //top inner inside insideBottom insideRight
  47. };
  48. // 设置完成率 折线的样式
  49. v[1].itemStyle = {
  50. color: "#f58634",
  51. };
  52. // 设置折线的 label
  53. v[1].label = {
  54. color: "#3a3a3a",
  55. show: true,
  56. position: "top",
  57. // formatter: "{c}%", 这样设置只是在数据后加上了百分符,但没有小数部分没有没有转化为百分数
  58. formatter: function(param){
  59. console.log(param)
  60. return param.value * 100 + '%'
  61. },
  62. };
  63. return v;
  64. },
  65. yAxis: {
  66. show: true,
  67. offset: 0,
  68. // y轴对应的横线
  69. splitLine: {
  70. show: false,
  71. },
  72. //这样设置的话 双 y 轴都是百分比了
  73. // axisLabel: {
  74. // show: true,
  75. // interval: "auto",
  76. // formatter: "{value}%",
  77. // },
  78. },
  79. // 自定义鼠标悬浮框toolTip
  80. // tooltip: {
  81. // // formatter: '{b0}<br />{a0}: {c0}<br />{a1}: {c1}%', //直接这样没有前面的颜色图例
  82. // trigger: "axis",
  83. // formatter: function (params) {
  84. // let html = params[0].name + "<br>";
  85. // for (let i = 0; i < params.length; i++) {
  86. // html +=
  87. // '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' +
  88. // params[i].color +
  89. // ';"></span>';
  90. // if (params[i].seriesName == "完成率") {
  91. // html += params[i].seriesName + ": " + params[i].value + "%<br>";
  92. // } else {
  93. // html += params[i].seriesName + ": " + params[i].value + "<br>";
  94. // }
  95. // }
  96. // return html;
  97. // },
  98. // },
  99. };
  100. return {
  101. chartData: {
  102. columns: ["month", "count", "percent"],
  103. rows: [
  104. { month: "1月", count: 393, percent: 0.32 },
  105. { month: "2月", count: 530, percent: 1.32 },
  106. { month: "3月", count: 923, percent: 2.32 },
  107. { month: "4月", count: 723, percent: 3.2 },
  108. { month: "5月", count: 792, percent: 1.2 },
  109. { month: "6月", count: 593, percent: 2.2 },
  110. { month: "7月", count: 393, percent: 1.32 },
  111. { month: "8月", count: 530, percent: 2.32 },
  112. { month: "9月", count: 923, percent: 0.32 },
  113. { month: "10月", count: 723, percent: 3.32 },
  114. { month: "11月", count: 792, percent: 1.32 },
  115. { month: "12月", count: 593, percent: 2.32 },
  116. ],
  117. },
  118. };
  119. },
  120. mounted() {
  121. sendChart().then((res) => {
  122. console.log("🚀 ~ file: SendChart.vue ~ line 99 ~ sendChart ~ res", res);
  123. });
  124. },
  125. };
  126. </script>