Vue项目实战:智慧学成项目

智慧学成数据展示项目

该项⽬是基于web的轻量级系统,数据展示平台,解决了数据展示的复杂性。采⽤完全前后端分离的开发模式,使⽤ Vue.js 技术栈构建的PC端 SPA 单⻚⾯应⽤程序,UI ⽅⾯使⽤了ElementUI。

该项目主要功能是统计线上课程的各方面信息,把用户,课程,热门学科,学习频次等数据展示出来,方便运营人员直观的了解用户的学习趋势,热门的产品,是当前web开发中,比较火热的数据展示项目。

项⽬来自黑马程序员前端项目库,

共包含业务模块:9 个,后台接⼝:16个,适合了解Vue基础语法的同学练习。

项目初始化

1. 使用@vue/cli创建项目的基本结构
vue create zhxc_pro
2. 使用交互式命令行选择需要引入的模块,安装项目依赖
zhxc_pro
├─ .browserslistrc
├─ .editorconfig
├─ .eslintrc.js
├─ .gitignore
├─ babel.config.js
├─ package-lock.json
├─ package.json
├─ public
│  ├─ favicon.ico
│  └─ index.html
├─ README.md
└─ src
   ├─ App.vue
   ├─ assets
   │  └─ logo.png
   ├─ components
   │  └─ HelloWorld.vue
   ├─ main.js
   ├─ router
   │  └─ index.js
   └─ views
      ├─ About.vue
      └─ Home.vue
3.安装其他依赖
  1. 安装less less-loader

    npm install less less-loader
    
  2. 安装axios

    npm install axios
    
  3. 安装dayjs echarts element-ui

    npm install dayjs
    
    npm install echarts
    
    npm install element-ui
    
4. 梳理项目结构
  1. 清空App.vue文件

    <template>
      <div id="app">
    
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="less" scoped>
    
    </style>
    
    
  2. 清空components和views文件夹

  3. 清空router文件夹下 index.js 中的routes 数组里的路由规则

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter)
    
    const routes = [
    
    ]
    
    const router = new VueRouter({
      routes
    })
    
    export default router
    
  4. 将准备好的图片,字体图标等静态资源复制到项目中

  5. 在src --> assets --> styles中创建全局样式文件 global.css

    html,
    body,
    #app {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    
  6. 在main.js中导入element和global.css

    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import './assets/styles/global.css'
    

Login页面

1. 创建Login.vue文件
  1. 在src–> views 文件夹下创建 Login.vue

  2. 在路由中添加对应的路由规则

    const routes = [
      { path: '/', redirect: '/login' },
      { path: '/login', name: 'login', component: () => import('@/views/Login.vue') }
    ]
    
2. 完成页面基本结构
  1. 完成template区域的结构

    <template>
      <div class="login-container">
        <div class="login-box">
          <h3>智慧学成统计系统</h3>
          <el-form ref="form">
            <el-form-item>
              <el-input></el-input>
            </el-form-item>
            <el-form-item>
              <el-input></el-input>
            </el-form-item>
            <el-form-item>
              <el-input></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary">登录</el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
    </template>
    
  2. 添加相应的样式

    <style lang="less" scoped>
    .login-container {
      height: 100%;
      background: url("../assets/images/background.png") no-repeat;
      .login-box {
        width: 650px;
        height: 600px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        background-color: rgba(255, 255, 255, 0.89);
        border-radius: 10px;
        .el-form {
          margin: 0 auto;
          width: 385px;
          height: 40px;
          .el-form-item {
            margin-bottom: 22px;
            /deep/ .el-input__inner {
              background-color: transparent;
              border: 0;
              border-bottom: 1px solid #cdcdcd;
            }
          }
          .el-button {
            margin-top: 50px;
            width: 100%;
            height: 60px;
            background: linear-gradient(270deg, #5efce8, #736efe);
          }
        }
        > h3 {
          text-align: center;
          margin: 90px 0;
          font-size: 36px;
          color: #1b7bef;
        }
      }
    }
    </style>
    
  3. 为输入框添加前置图标,因为这里的图标使用的是图片文件所以我们需要使用el-input组件提供的具名插槽prefix

    <el-form ref="form">
      <el-form-item>
        <el-input placeholder="用户名">
            <img class="prefix" slot="prefix" src="@/assets/images/username.png" alt="">
        </el-input>
      </el-form-item>
      <el-form-item>
        <el-input placeholder="密码">
            <img class="prefix" slot="prefix" src="@/assets/images/pwd.png" alt="">
        </el-input>
      </el-form-item>
      <el-form-item>
        <el-input placeholder="验证码">
            <img class="prefix" slot="prefix" src="@/assets/images/yzm.png" alt="">
        </el-input>
    </el-form-item>
    

    设置图片大小为30px

          .el-form-item {
            margin-bottom: 22px;
            .prefix {
                width: 30px;
            	}
    		}
    
  4. 创建自定义指令,实现为prefix中图片添加边框,显示选中状态

      directives: {
        act: {
          update: function (el, binding) {
            if (binding.value) {
              el.style.cssText = 'border:1px dashed #ccc;'
            } else {
              el.style.cssText = 'border:0'
            }
          }
        }
      }
    
  5. 给el-input输入框绑定focus事件 修改v-act指令的值

            <el-form-item>
              <el-input @focus="focusHandle('username')" placeholder="用户名">
                <img
                  v-act="activeStr == 'username'"
                  class="prefix"
                  slot="prefix"
                  src="@/assets/images/username.png"
                  alt
                />
              </el-input>
            </el-form-item>
    
    
    
    	<script>
    		export default {
                  data () {
                        return {
                          activeStr: ''
                        }
                      },
                      methods: {
                        focusHandle (val) {
                          this.activeStr = val
                        }
                      },
    			}
    	</script>
    
3. 为login表单绑定数据,并添加表单验证
      <el-form ref="form" :model="loginForm" :rules="loginFormRules">
        <el-form-item prop="username">
          <el-input @focus="focusHandle('username')" v-model="loginForm.username" placeholder="用户名">
            <img
              v-act="activeStr == 'username'"
              class="prefix"
              slot="prefix"
              src="@/assets/images/username.png"
              alt
            />
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input @focus="focusHandle('pwd')" v-model="loginForm.password" placeholder="密码">
            <img
              v-act="activeStr == 'pwd'"
              class="prefix"
              slot="prefix"
              src="@/assets/images/pwd.png"
              alt
            />
          </el-input>
        </el-form-item>
        <el-form-item prop="verifycode">
          <el-input @focus="focusHandle('yzm')" v-model="loginForm.verifycode" placeholder="验证码">
            <img
              v-act="activeStr == 'yzm'"
              class="prefix"
              slot="prefix"
              src="@/assets/images/yzm.png"
              alt
            />
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary">登录</el-button>
        </el-form-item>
      </el-form>
<script>
export default {
  data () {
    return {
      activeStr: '',
      loginForm: {
        username: '',
        password: '',
        verifycode: ''
      },
      loginFormRules: {
        username: [
          { required: true, message: '请输入用户名称', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入用户密码', trigger: 'blur' }
        ],
        verifycode: [
          { required: true, message: '请输入验证码', trigger: 'blur' }
        ]
      }
    }
  }
}
</script>
4.添加验证码区域
  1. 在 src–> utils 目录下创建操作本地存储的工具函数 storage.js

    /**
     * 封装本地存储操作模块
     */
    
    /**
     * 存储数据
     */
    export const setItem = (key, value) => {
        // 将数组、对象类型的数据转换为 JSON 格式字符串进行存储
        if (typeof value === 'object') {
          value = JSON.stringify(value)
        }
        window.sessionStorage.setItem(key, value)
      }
      
      /**
       * 获取数据
       */
      export const getItem = key => {
        const data = window.sessionStorage.getItem(key)
        try {
          return JSON.parse(data)
        } catch (err) {
          return data
        }
      }
      
      /**
       * 删除数据
       */
      export const removeItem = key => {
        window.sessionStorage.removeItem(key)
      }
      
    
  2. 在src–>utils 目录下创建用于生成验证码的工具函数 verify.js

    import { setItem } from './storage'
    /**
     *
     * @param {String} el 选择器
     * @param {*} option 配置对象 { lineNum:干扰线数量 ,textLen:验证码长度 ,width:画布宽 ,height:画布高 }
     */
    function Gcode(el, option) {
    
        this.el = typeof el === "string" ? document.querySelector(el) : el;
    
        this.option = option || {};
    
        this.text = ""
    
        this.init();
    
    
    }
    
    Gcode.prototype = {
    
        constructor: Gcode,
    
        init: function () {
    
            if (this.el.getContext) {
                var ctx = this.el.getContext("2d"),
    
                    // 设置画布宽高
    
                    cw = this.el.width = this.option.width || 90,
    
                    ch = this.el.height = this.option.height || 30,
    
                    textLen = this.option.textLen || 4,
    
                    lineNum = this.option.lineNum || 2;
    
                this.randomText(textLen);
    
                this.onClick(ctx, textLen, lineNum, cw, ch);
    
                this.drawLine(ctx, lineNum, cw, ch);
    
                this.drawText(ctx, this.text, ch);
    
            }
    
        },
    
        onClick: function (ctx, textLen, lineNum, cw, ch) {
    
            var _ = this;
    
            this.el.addEventListener("click", function () {
    
                _.randomText(textLen);
    
                _.drawLine(ctx, lineNum, cw, ch);
    
                _.drawText(ctx, _.text, ch);
    
            }, false)
    
        },
    
        // 画干扰线
    
        drawLine: function (ctx, lineNum, maxW, maxH) {
    
            ctx.clearRect(0, 0, maxW, maxH);
    
            for (var i = 0; i < lineNum; i++) {
    
                var dx1 = Math.random() * maxW,
    
                    dy1 = Math.random() * maxH,
    
                    dx2 = Math.random() * maxW,
    
                    dy2 = Math.random() * maxH;
    
                ctx.strokeStyle = " rgb(" + 255 * Math.random() + "," + 255 * Math.random() + "," + 255 * Math.random() + ")";
    
                ctx.beginPath();
    
                ctx.moveTo(dx1, dy1);
    
                ctx.lineTo(dx2, dy2);
    
                ctx.stroke();
    
            }
    
        },
    
        // 画文字
    
        drawText: function (ctx, text, maxH) {
    
            var len = text.length;
    
            for (var i = 0; i < len; i++) {
    
                var dx = 20 * Math.random() + 20 * i,
    
                    dy = Math.random() * 5 + maxH / 2;
    
                ctx.fillStyle = " rgb(" + 255 * Math.random() + "," + 255 * Math.random() + "," + 255 * Math.random() + ")";
    
                ctx.font = " 22px Helvetica";
    
                ctx.textBaseline = " middle";
    
                ctx.fillText(text[i], dx, dy);
    
            }
    
        },
    
        // 生成指定个数的随机文字
    
        randomText: function (len) {
    
            var source = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
    
            var result = [];
    
            var sourceLen = source.length;
    
            for (var i = 0; i < len; i++) {
    
                var text = this.generateUniqueText(source, result, sourceLen);
    
                result.push(text)
    
            }
            this.text = result.join("")
            setItem('verify_code', this.text)
        },
    
        // 生成唯一文字
    
        generateUniqueText: function (source, hasList, limit) {
    
            var text = source[Math.floor(Math.random() * limit)];
    
            if (hasList.indexOf(text) > -1) {
    
                return this.generateUniqueText(source, hasList, limit)
    
            } else {
    
                return text
    
            }
    
        }
    
    }
    
    export default Gcode
    
  3. 给el-input添加后缀图标 suffix

            <el-form-item prop="verifycode">
              <el-input @focus="focusHandle('yzm')" v-model="loginForm.verifycode" placeholder="验证码">
                <img
                  v-act="activeStr == 'yzm'"
                  class="prefix"
                  slot="prefix"
                  src="@/assets/images/yzm.png"
                  alt
                />
                <canvas slot="suffix" id="verifybox"></canvas>
              </el-input>
            </el-form-item>
    
  4. 在mounted生命周期中调用utils里的工具方法生成验证码

      mounted () {
        // 创建验证码
        return new Gcode('#verifybox', 4)
      }
    
  5. 自定义校验验证码的校验规则

      data () {
        // 自定义校验规则
        const checkVerify = (rule, value, callback) => {
          const vfCode = getItem('verify_code')
          if (vfCode !== value) {
            return callback(new Error('请填写正确的验证码'))
          }
          callback()
        }
        return {
          activeStr: '',
          loginForm: {
            username: '',
            password: '',
            verifycode: ''
          },
          loginFormRules: {
            username: [
              { required: true, message: '请输入用户名称', trigger: 'blur' }
            ],
            password: [
              { required: true, message: '请输入用户密码', trigger: 'blur' }
            ],
            verifycode: [
              { required: true, message: '请输入验证码', trigger: 'blur' },
              { validator: checkVerify, trigger: 'blur' }
            ]
          }
        }
      }
    
5. 全局配置axios
6. 给登录按钮绑定点击事件
7. 获取el-form实例调用表单预验证函数发出登录请求
  methods: {
    focusHandle (val) {
      this.activeStr = val
    },
    async login () {
      this.$refs.form.validate(async vali => {
        if (!vali) return this.$message.error('请填写正确的登录信息')
        const { data: res } = await this.$http.post('common/login', this.loginForm)
        if (res.code !== 200) return this.$message.error('登录失败')
        this.$router.push('/home')
      })
    }
  }

Home 页面

页面初始化
  1. 初始化页面结构

    <template>
      <el-container>
        <el-header height="80px">
          <div class="title">
            <span>智慧云课堂</span>
          </div>
          <div class="right_box">
            <i class="el-icon-warning-outline help" ></i>
            <span class="help">帮助</span>
            <img src="@/assets/images/personal.jpg" alt />
            <span>HolyCode</span>
          </div>
        </el-header>
        <el-container>
          <el-aside width="250px"></el-aside>
          <el-main>
            <router-view></router-view>
          </el-main>
        </el-container>
      </el-container>
    </template>
    
    <script>
    	export default {}
    </script>
    
    <style lang="less" scoped>
    .el-container {
      height: 100%;
      .el-header {
        background-color: #1b7bef;
        box-shadow: 6px 3px 10px 0 rgba(0, 0, 0, 0.3);
        z-index: 99;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding-left: 65px;
        font-size: 24px;
        color:#fff;
        .right_box {
          display: flex;
          align-items: center;
          .help {
            font-size: 14px;
            color:#cdcdcd;
            margin-left: 10px;
          }
          img {
            width: 36px;
            margin-left: 30px;
            border-radius: 50%;
          }
          > span:nth-child(4){
            margin-left: 10px;
            font-size: 18px;
          }
        }
      }
      .el-aside {
        background-color: #1b7bef;
      }
    }
    </style>
    
  2. 引入侧边栏的静态数据

    <script>
        import asideList from '../utils/asideList'
        export default {
          data () {
            return {
              asideList
            }
          }
        }
    </script>
    
  3. 循环生成NavMenu

            <el-menu
              class="el-menu-vertical-demo"
              background-color="#1b7bef"
              text-color="#a7c7ed"
              active-text-color="#e7eaec"
              :default-active="'/board'"
            >
              <el-menu-item v-for="item in asideList" :key="item.path" :index="'/'+item.path">
                <template>
                  <i :class="item.icon"></i>
                  <span>{{ item.name }}</span>
                </template>
              </el-menu-item>
            </el-menu>
    
  4. 监听路由变化 记录navmenu的选中状态

课程购买量页面

1. 获取图表数据
  1. 添加对应路由规则

  2. 创建Buy.vue文件

  3. 初始化结构

    <template>
      <div>
        <el-breadcrumb separator-class="el-icon-arrow-right">
          <el-breadcrumb-item>当前位置</el-breadcrumb-item>
          <el-breadcrumb-item>课程购买量</el-breadcrumb-item>
        </el-breadcrumb>
        <el-card>
          <el-tabs>
            <el-tab-pane label="课程购买量统计" name="buy">
    
            </el-tab-pane>
            <el-tab-pane label="课程访问量" name="visit">
    
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </div>
    </template>
    
  4. 获取课程访问量数据

    • 引入dayjs
    • 查询近一周的数据使用dayjs来格式化时间
    • 发起请求
    <script>
    import dayjs from 'dayjs'
    export default {
      data () {
        return {
          queryInfo: {
            startDate: '',
            endDate: '',
            courseld: ''
          },
          buyList: []
        }
      },
      mounted () {
        this.queryInfo.startDate = dayjs().subtract(10, 'day').format('YYYY-MM-DD')
        this.queryInfo.endDate = dayjs().format('YYYY-MM-DD')
        this.getBuyList()
      },
      methods: {
        async getBuyList () {
          const { data: res } = await this.$http.get('course/courseBuy', { params: { ...this.queryInfo } })
          console.log(res)
        }
      }
    }
    </script>
    
2. 初步展示图表
  1. 引入echart import echarts from ‘echarts’

  2. 创建图表容器

          <el-tabs  v-model="tabsActive">
            <el-tab-pane label="课程购买量统计" name="buy">
                <div ref="chartbox"  style="height:600px"></div>
            </el-tab-pane>
            <el-tab-pane label="课程访问量" name="visit">
    
            </el-tab-pane>
          </el-tabs>
    
  3. 初始化图表容器对象

  4. 封装绘制函数

  5. 在获取数据的函数里 得到返回值之后调用绘制图表函数

3. 自定义折线图的样式
  1. 设置tooltip 提示框组件

    • 设置 show 属性为 true

    • 设置 trigger 属性为 ‘axis’ 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用

    • 设置 axisPointer 坐标轴指示器配置项中的 type 属性设置为 'none' 无指示器

    • 设置 背景色 backgroundColor 为 rgba(245, 245, 245, 0.8)

    • 设置 文字样式 textStyle 中的color 为 #000

              tooltip: {
                show: true,
                trigger: 'axis',
                axisPointer: {
                  type: 'none'
                },
                backgroundColor: 'rgba(245, 245, 245, 0.8)',
                textStyle: {
                  color: '#000'
                },
                borderWidth: 1,
                borderColor: '#ccc',
                padding: 10
              }
      
    • 设置 formatter 中的模板字符串

                formatter: function (params) {
                  return `<div style="width:194px;height:96px;border-radius:4px;position:relative;">
                  <p>${params.name}</p>
                  <div style="width:8px;height:8px; position:absolute;top:42px;left:10px;background-color:#6BCEF0;border-radius:50%;"></div>
                  <ul>
                    <li>
                      <span style="margin-right:20px">${params.seriesName ? params.seriesName : params.name}</span>
                      <span>${params.value}</span>
                    </li>
                  </ul>
                </div>`
                }
      
  2. 设置 xAxis 属性 boundaryGap 坐标轴两边留白策略 boundaryGap: false

  3. 设置 折线图 line 的 series

            series: [
              {
                data: this.buyNumList,
                smooth: true, // 是否为平滑曲线
                name: '新增会员数', // tooltip中显示
                symbol: 'circle', // 标记的图形
                symbolSize: 6, // 标记大小
                lineStyle: { // 折线样式
                  width: 2,
                  shadowColor: 'rgba(0,0,0,0.4)',
                  shadowBlur: 7,
                  shadowOffsetY: 30 // 阴影y轴上的偏移值
                },
                itemStyle: { // 拐点样式
                  color: '#509BF2',
                  borderColor: '#fff'
                },
                type: 'line'
              }
            ]
    
4. 添加自定义工具栏

结构

        <div class="toolbox">
          <div class="download">下载数据</div>
          <div class="chart_type">
            <span>图标类型:</span>
            <div class="type_box">
              <i class="iconfont icon-zhexiantu"></i>
              <i class="iconfont icon-zhuzhuangtu"></i>
              <i class="iconfont icon-zhuzhuangtu1"></i>
            </div>
          </div>
        </div>

样式

  .toolbox {
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    .download {
      color: #1b7befff;
      font-weight: 600;
      margin-right: 30px;
      cursor: pointer;
    }
    .chart_type {
      display: flex;
      align-items: center;
      span {
        margin-right: 20px;
      }
      .type_box {
        border-radius: 4px;
        border: 1px solid #d0d0d0;
        display: flex;
        justify-content: center;
        i:nth-child(3) {
          border: 0;
        }
        i {
          display: block;
          border-right: 1px solid #d0d0d0;
          box-sizing: border-box;
          width: 52px;
          height: 36px;
          color: #c1c1c1;
          font-size: 26px;
          padding-left: 13px;
          padding-top: 5px;
        }
        .active {
          color: #fff;
          background-color: #1b7bef;
        }
      }
    }
  }
5. 为自定义工具栏 添加选中高亮
<div class="type_box">
  <i @click="changeType('line')" :class="{'iconfont':true, 'icon-zhexiantu':true, 'active': 'line'==chartType?true:false}"></i>
  <i @click="changeType('bar')" :class="{'iconfont':true, 'icon-zhuzhuangtu':true, 'active': 'bar'==chartType?true:false}"></i>
  <i @click="changeType('hbar')" :class="{'iconfont':true, 'icon-zhuzhuangtu1':true, 'active': 'hbar'==chartType?true:false}"></i>
</div>

封装图表组件

1. 抽离结构代码
<template>
  <div ref="chartbox" style="height:600px"></div>
</template>
2. 定义接受的数据 prop
  props: {
    chartType: {
      type: String,
      default: 'line'
    },
    valueData: {
      type: Array,
      required: true
    },
    cateData: {
      type: Array,
      required: true
    },
    tipName: {
      type: String,
      required: true
    }
  }
3. 封装工具文件 chart.js
// 公共的tooltip 配置
const tooltip = {
  show: true,
  trigger: 'axis',
  axisPointer: {
    type: 'none'
  },
  backgroundColor: 'rgba(245, 245, 245, 0.8)',
  textStyle: {
    color: '#000'
  },
  borderWidth: 1,
  borderColor: '#ccc',
  padding: 10,
  formatter: function (params) {
    return `<div style="width:194px;height:96px;border-radius:4px;position:relative;">
            <p>${params[0].name}</p>
            <div style="width:8px;height:8px; position:absolute;top:42px;left:10px;background-color:#6BCEF0;border-radius:50%;"></div>
            <ul>
              <li>
                <span style="margin-right:20px">${
            params[0].seriesName ? params[0].seriesName : params[0].name
            }</span>
                <span>${params[0].value}</span>
              </li>
            </ul>
          </div>`
  }
}

// line
const lineopt = {
  tooltip,
  xAxis: {
    type: 'category',
    data: [],
    boundaryGap: false
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [],
      smooth: true, // 是否为平滑曲线
      name: '新增会员数', // tooltip中显示
      symbol: 'circle', // 标记的图形
      symbolSize: 6, // 标记大小
      lineStyle: {
        // 折线样式
        width: 2,
        shadowColor: 'rgba(0,0,0,0.4)',
        shadowBlur: 7,
        shadowOffsetY: 30 // 阴影y轴上的偏移值
      },
      itemStyle: {
        // 拐点样式
        color: '#509BF2',
        borderColor: '#fff'
      },
      type: 'line'
    }
  ]
}

export const drawnLine = (chartbox, options) => {
  lineopt.xAxis.data = options.cateData
  lineopt.series[0].data = options.valueData
  lineopt.series[0].name = options.tipName
  return chartbox.setOption(lineopt)
}
// bar

// hbar

          <li>
            <span style="margin-right:20px">${
        params[0].seriesName ? params[0].seriesName : params[0].name
        }</span>
            <span>${params[0].value}</span>
          </li>
        </ul>
      </div>`

}
}

// line
const lineopt = {
tooltip,
xAxis: {
type: ‘category’,
data: [],
boundaryGap: false
},
yAxis: {
type: ‘value’
},
series: [
{
data: [],
smooth: true, // 是否为平滑曲线
name: ‘新增会员数’, // tooltip中显示
symbol: ‘circle’, // 标记的图形
symbolSize: 6, // 标记大小
lineStyle: {
// 折线样式
width: 2,
shadowColor: ‘rgba(0,0,0,0.4)’,
shadowBlur: 7,
shadowOffsetY: 30 // 阴影y轴上的偏移值
},
itemStyle: {
// 拐点样式
color: ‘#509BF2’,
borderColor: ‘#fff’
},
type: ‘line’
}
]
}

export const drawnLine = (chartbox, options) => {
lineopt.xAxis.data = options.cateData
lineopt.series[0].data = options.valueData
lineopt.series[0].name = options.tipName
return chartbox.setOption(lineopt)
}
// bar

// hbar

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值