当前位置:   article > 正文

vue+echarts项目四:地区销量趋势(堆叠折线图)_echarts趋势图

echarts趋势图

 最终效果如图

组件结构设计

外部 Trendpage.vue

  1. <!--针对于/trendpage 这条路径显示 测试显示组件-->
  2. <template>
  3. <div class="comP1">
  4. <Trend></Trend>
  5. </div>
  6. </template>
  7. <script>
  8. import Trend from "@/components/Trend";
  9. export default {
  10. name: "TrendPage",
  11. components:{Trend}
  12. }
  13. </script>
  14. <style scoped>
  15. </style>

内部Trend.vue 

  1. <!-- 显示地区销量趋势的折线图表 -->
  2. <template>
  3. <div class="comP2" ref="trend_1"></div>
  4. </template>
  5. <script>
  6. export default {
  7. data () {
  8. return {}
  9. },
  10. methods: {}
  11. }
  12. </script>
  13. <style lang="less" scoped>
  14. </style>

 初始化图表+数据的获取+更新图表

设置好这些函数 在mounted生命周期内调用

  1. mounted() {
  2. // 渲染DOM元素之后 初始化图表实例 请求数据 监听页面尺寸变化
  3. this.initChart()
  4. this.getData() // 请求数据
  5. // 监听图表尺寸发生变化时的 处理函数 自适应尺寸
  6. window.addEventListener('resize',this.screenAdapter)
  7. this.screenAdapter()
  8. },

找到盒子初始化图表、这里只是简单设置的直角坐标系 

  1. initChart(){
  2. this.chartInstance = this.$echarts.init(this.$refs.trend_1,this.theme)
  3. const initOption = {
  4. grid:{
  5. left:'3%',
  6. top:'35%',
  7. right:'4%',
  8. bottom:'1%',
  9. containLabel:true
  10. },
  11. tooltip:{ // 鼠标悬浮时的提示框
  12. trigger:'axis'
  13. },
  14. legend:{
  15. left: 20,
  16. top: '15%',
  17. icon:'circle'
  18. },
  19. xAxis: {
  20. type:'category',
  21. boundaryGap:false // 紧贴两侧边缘
  22. },
  23. yAxis:{
  24. type:'value'
  25. }
  26. }
  27. this.chartInstance.setOption(initOption)
  28. },

发送请求、获取数据 

  1. getData(){
  2. const {data:res} = await this.$http.get('trend')
  3. this.allData = res
  4. this.updateChart()
  5. },

请求过来的数据:

  1. {
  2. "map": {
  3. "title": "地区销量趋势",
  4. "base": 310,
  5. "unit": "万",
  6. "data": [{
  7. "name": "上海",
  8. "data": ["155.13","154.65","171.46","164.38","237.23","300.65","240.29","232.07","193.31","136.70","48.64","90.20"]
  9. }, {
  10. "name": "北京",
  11. "data": ["86.25","33.80","145.58","21.79","176.09","132.41","291.05","191.89","151.54","94.25","141.75","157.14"]
  12. }, {
  13. "name": "深圳",
  14. "data": ["143.94","186.29","183.64","251.48","195.48","152.16","52.47","184.12","203.79","39.16","56.37","161.64"]
  15. }, {
  16. "name": "广州",
  17. "data": ["57.60","77.61","307.24","165.05","175.41","276.88","269.04","296.11","105.31","283.39","134.08","265.38"]
  18. }, {
  19. "name": "重庆",
  20. "data": ["200.82","215.56","249.80","222.67","216.98","60.12","309.68","273.35","150.99","251.97","26.15","186.99"]
  21. }]
  22. },
  23. "seller": {
  24. "title": "商家销量趋势",
  25. "base": 120,
  26. "unit": "万",
  27. "data": [{
  28. "name": "商家1",
  29. "data": ["33.00","86.07","28.77","34.29","102.45","0.30","50.50","21.70","25.41","25.71","66.90","63.29"]
  30. }, {
  31. "name": "商家2",
  32. "data": ["12.83","102.42","37.37","95.55","45.45","112.72","113.53","106.41","75.67","113.91", "37.32", "28.04"]
  33. }, {
  34. "name": "商家3",
  35. "data": ["73.54","40.92","89.81","113.41","76.34","107.15","55.61","0.33","106.29","78.30","98.05","38.67"]
  36. }, {
  37. "name": "商家4",
  38. "data": ["47.19","73.57","44.60","84.03","62.82","15.65","64.72","88.98","29.25","5.41","79.11","118.46"]
  39. }, {
  40. "name": "商家5",
  41. "data": ["74.84","116.45","107.69","11.03","17.31","42.22","97.60","108.64","43.87","110.65","5.96","38.41"]
  42. }]
  43. },
  44. "commodity": {
  45. "title": "商品销量趋势",
  46. "base": 50,
  47. "unit": "万",
  48. "data": [{
  49. "name": "女装",
  50. "data": ["47.71","13.34","19.30","7.93","41.93","23.01","22.63","26.91","0.62","39.23","48.74","29.48"]
  51. }, {
  52. "name": "手机数码",
  53. "data": ["46.66","46.52","23.65","1.73","44.26","47.07","17.86","40.20","3.78","31.46","28.01","8.63"]
  54. }, {
  55. "name": "男装",
  56. "data": ["26.98","30.71","42.59","29.50","26.86","17.65","30.15","15.85","9.28","30.20","32.35","34.46"]
  57. }, {
  58. "name": "大家电",
  59. "data": ["20.26","46.23","43.84","46.75","28.29","32.36","45.30","16.73","40.40","45.07","29.86","41.92"]
  60. }, {
  61. "name": "美妆护肤",
  62. "data": ["7.58","23.66","39.78","30.20","25.72","36.20","47.55","35.39","27.85","37.56","16.91", "3.91"]
  63. }]
  64. },
  65. "common": {
  66. "month": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
  67. },
  68. "type": [{
  69. "key": "map",
  70. "text": "地区销量趋势"
  71. }, {
  72. "key": "seller",
  73. "text": "商家销量趋势"
  74. }, {
  75. "key": "commodity",
  76. "text": "商品销量趋势"
  77. }]
  78. }

数据请求过来后在进行 相应处理 渲染图表

data中预留的变量:

data(){
  return{
    chartInstance:null,// 预留初始化实例对象
    allData:null, // 服务器请求过来的数据
    showChoice:false, // 是否显示可选项
    choiceType:'map', // 显示的数据类型
    titleFontSize:0 // 指明标题的字体
  }
},

1.准备好两个数组 颜色透明度 0.5  ->  0.1

2.抽取时间轴的数据

3.抽取组合 series 系列的数组 

4.抽取 legend 分类提示

5.重新生成 option 调用 setOption 渲染图表

  1. updateChart(){
  2. // 数据更新时 重新渲染
  3. // 预设半透明颜色的值
  4. const colorArr1 = [
  5. 'rgba(11,168,44,0.5)',
  6. 'rgba(44,110,255,0.5)',
  7. 'rgba(22,242,217,0.5)',
  8. 'rgba(254,33,30,0.5)',
  9. 'rgba(250,105,0,0.5)'
  10. ]
  11. // 预设全透明颜色的值
  12. const colorArr2 = [
  13. 'rgba(11,168,44,0.1)',
  14. 'rgba(44,110,255,0.1)',
  15. 'rgba(22,242,217,0.1)',
  16. 'rgba(254,33,30,0.1)',
  17. 'rgba(250,105,0,0.1)'
  18. ]
  19. // 处理请求过来的 this.allData 数据 直接用变量 导进设置中
  20. const timeArr = this.allData.common.month // 类目轴的月份
  21. const valueArr = this.allData[this.choiceType].data // 数值轴的数据
  22. const seriesArr = valueArr.map((item,index) => {
  23. return {
  24. type:'line', // 类型是折线图
  25. data:item.data, // 数据是每一项的data
  26. stack:this.choiceType, // 设置成堆叠图一样的字符串就可以
  27. name:item.name, // 每一项的提示 name
  28. // 每一项面积颜色的设置 运用到 上面定义的两个数组
  29. areaStyle:{
  30. color:new this.$echarts.graphic.LinearGradient(0,0,0,1,[
  31. {
  32. offset:0,
  33. color:colorArr1[index]
  34. },
  35. {
  36. offset:1,
  37. color:colorArr2[index]
  38. }
  39. ])
  40. }
  41. }
  42. })
  43. const legendArr = valueArr.map(item => {
  44. return item.name
  45. })
  46. const dataOption = {
  47. xAxis: {
  48. data:timeArr
  49. },
  50. legend:{
  51. data:legendArr
  52. },
  53. series:seriesArr
  54. }
  55. this.chartInstance.setOption(dataOption)
  56. },

尺寸变化的适配-第三篇文章已经详细讲过

  1. screenAdapter(){
  2. // 页面分辨率发生改变时 重新渲染
  3. this.titleFontSize = this.$refs.trend_1.offsetWidth / 100 * 3.6
  4. const adapterOption = {
  5. // legend 是提示类目的文字 可以总的设置 也可以在单独的 series 里设置
  6. legend: {
  7. itemWidth: this.titleFontSize,
  8. itemHeight: this.titleFontSize,
  9. itemGap: this.titleFontSize,
  10. textStyle: {
  11. fontSize: this.titleFontSize / 2
  12. }
  13. }
  14. }
  15. this.chartInstance.setOption(adapterOption)
  16. this.chartInstance.resize()
  17. },

标题显示以及对于数据的切换操作

 

请求过来的数据当中 有 三种类型  map  seller  commodity 默认是 map

在template 当中添加 标题选择模块  附加一定的样式 使得标题显示在对应的位置

  1. 整体的 位置 由title 样式决定  动态样式 comStyle 会随着窗口变化和主题切换而改动
  2. showTitle  根据 this.choiceType 动态决定标题
  3. icon-font 字体图标 小箭头 点击切换 下拉标题的选择
  4. v-for 渲染下拉标题 过滤掉当前选择的标题
  5. 为每一小项 添加点击事件 传入 对应的key  更新this.choiceType 后重新渲染图标 并隐藏下拉
  1. <template>
  2. <div class="comP3">
  3. <div class="title" :style="comStyle">
  4. <span>{{'▎ ' + showTitle}}</span>
  5. <span class="iconfont title-icon" :style="comStyle" @click="showChoice = !showChoice">&#xe6eb;</span>
  6. <div class="select-con"
  7. :style="theme === 'chalk' ? 'background-color: #222733;' : 'background-color: #ffffff;'"
  8. v-show="showChoice">
  9. <div class="select-item" :style="marginStyle" v-for="item in selectTypes" :key="item.key" @click="handleSelect(item.key)">
  10. {{item.text}}
  11. </div>
  12. </div>
  13. </div>
  14. <div class="comP2" ref="trend_1"></div>
  15. </div>
  16. </template>
  17. <style scoped lang="less">
  18. .title {
  19. position: absolute;
  20. left: 20px;
  21. top: 20px;
  22. z-index: 10;
  23. cursor: pointer;
  24. user-select: none;
  25. color: white;
  26. .title-icon {
  27. margin-left: 10px;
  28. }
  29. .select-con {
  30. /*background-color: #222733;*/
  31. }
  32. }
  33. </style>

与之对应的计算属性和方法:

  1. computed:{
  2. ...mapState(['theme']),
  3. // 准备遍历选项的 元数据
  4. selectTypes(){
  5. if (!this.allData){
  6. return []
  7. }else {
  8. return this.allData.type.filter(item =>{
  9. return item.key !== this.choiceType
  10. })
  11. }
  12. },
  13. // 显示当前选中的标题
  14. showTitle(){
  15. if(!this.allData){
  16. return ''
  17. }else {
  18. return this.allData[this.choiceType].title
  19. }
  20. },
  21. // 设置给标题的样式
  22. comStyle(){
  23. return `font-size:${this.titleFontSize}px;color:${getThemeValue(this.theme).titleColor}`
  24. },
  25. marginStyle(){
  26. return `padding-left:${this.titleFontSize}px`
  27. },
  28. },
  29. methods:{
  30. handleSelect(currentType){
  31. this.choiceType = currentType
  32. this.updateChart()
  33. this.showChoice = false
  34. }
  35. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/630573
推荐阅读
相关标签
  

闽ICP备14008679号