欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot整合Echarts實現(xiàn)數(shù)據(jù)大屏

 更新時間:2024年03月04日 10:31:16   作者:OpenYuan開袁  
這篇文章給大家介紹了三步實現(xiàn)SpringBoot全局日志記錄,整合Echarts實現(xiàn)數(shù)據(jù)大屏,文中通過代碼示例給大家介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下

效果展示

image.png

image.png

MySQL

建表

CREATE TABLE `access_log` (
  `access_log_id` bigint NOT NULL AUTO_INCREMENT,
  `access_time` datetime NOT NULL COMMENT '訪問時間',
  `access_ip` varchar(30) NOT NULL COMMENT '訪問IP',
  `api_group` varchar(50) NOT NULL DEFAULT '默認' COMMENT '接口分組',
  `req_url` varchar(100) NOT NULL COMMENT '請求URL',
  `req_method` varchar(10) NOT NULL COMMENT '請求方式',
  `os` varchar(100) NULL DEFAULT NULL COMMENT '操作系統(tǒng)',
  `browser` varchar(50) NULL DEFAULT NULL COMMENT '瀏覽器',
  `lsp` varchar(15) NULL DEFAULT NULL COMMENT '運營商',
  `country` varchar(15) NULL DEFAULT NULL COMMENT '國家',
  `province` varchar(15) NULL DEFAULT NULL COMMENT '省',
  `city` varchar(15) NULL DEFAULT NULL COMMENT '城市',
  PRIMARY KEY (`access_log_id`)
) COMMENT='訪問日志表';

后端

POJO實體

@Data
@TableName(value = "access_log")
public class AccessLog implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 訪問日志ID  
     */
    @TableId(type = IdType.AUTO)
    private Long accessLogId;

    /**
     * 訪問時間  
     */
    private Date accessTime;

    /**
     * 訪問IP  
     */
    private String accessIp;

    /**
     * 接口分組  
     */
    private String apiGroup;

    /**
     * 請求URL  
     */
    private String reqUrl;

    /**
     * 請求方式  
     */
    private String reqMethod;

    /**
     * 操作系統(tǒng)  
     */
    private String os;

    /**
     * 瀏覽器  
     */
    private String browser;

    /**
     * 運營商  
     */
    private String lsp;

    /**
     * 國家  
     */
    private String country;

    /**
     * 省  
     */
    private String province;

    /**
     * 城市  
     */
    private String city;
}

Mapper接口

@Repository
public interface AccessLogMapper extends BaseMapper<AccessLog> {
    
}

自定義注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

    /**
     * 給接口分組
     */
    String apiGroup() default "默認";
}

案例:

@Log(apiGroup = "文章模塊")
@RestController
@RequestMapping("/article")
public class ArticleController {
    ......
}

攔截器

ps:https://api.vvhan.com/api/getIpInfo?ip=[你的IP],這個網(wǎng)址是一個免費獲取國家、省、市、運營商的地址
當然這種對IP地址的解析應(yīng)該是放在定時任務(wù)中,每天晚上定時解析日志IP,如果解析IP的API掛了,接口會受到影響,我這里只是為了方便寫在這里

@Slf4j
@Component
public class AccessLogInterceptor implements HandlerInterceptor {
    
    @Autowired
    private AccessLogMapper accessLogMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        try {
            // 獲取客戶端真是IP地址,這種網(wǎng)上很多現(xiàn)成代碼
            String accessIp = NetUtil.getRemoteHost(request);
            // 獲取User-Agent
            String requestUserAgent = request.getHeader("User-Agent");
            // 獲取瀏覽器用戶標識
            UserAgent userAgent = UserAgentUtil.parse(requestUserAgent);
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Log logAnnotation = handlerMethod.getMethod().getDeclaringClass().getAnnotation(Log.class);

            AccessLog accessLog = new AccessLog();
            accessLog.setAccessIp(accessIp);
            accessLog.setAccessTime(new Date());
            if (logAnnotation != null) {
                accessLog.setApiGroup(logAnnotation.apiGroup());
            }
            accessLog.setReqUrl(request.getRequestURI());
            accessLog.setReqMethod(request.getMethod());
            accessLog.setOs(userAgent.getOs().getName());
            accessLog.setBrowser(userAgent.getBrowser().getName());

            // 解析IP
            try {
                String ipParseStr = HttpUtil.get("https://api.vvhan.com/api/getIpInfo?ip=" + accessIp);
                JSONObject ipParseJson = JSONUtil.parseObj(ipParseStr);
                if (ipParseJson.getBool("success")) {
                    JSONObject infoJson = ipParseJson.getJSONObject("info");
                    accessLog.setLsp(infoJson.getStr("lsp"));
                    accessLog.setCountry(infoJson.getStr("country"));
                    accessLog.setProvince(infoJson.getStr("prov"));
                    accessLog.setCity(infoJson.getStr("city"));
                }
            } catch (Exception e) {
                accessLog.setLsp("未知");
                accessLog.setCountry("未知");
                accessLog.setProvince("未知");
                accessLog.setCity("未知");
            }
            accessLogMapper.insert(accessLog);
        } catch (Exception e) {
            log.error("", e);
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

注冊攔截器

@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    
    @Autowired
    private AccessLogInterceptor accessLogInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注冊全局日志攔截器
        registry.addInterceptor(accessLogInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/static/**")
                .excludePathPatterns("/error");

        // 其他攔截器......
    }
}

測試

到這里就完成一個簡單的全局日志攔截器了,隨便發(fā)幾個請求測試一下,成功記錄入庫!

image.png

進階——整合Echarts實現(xiàn)數(shù)據(jù)大屏

數(shù)據(jù)VO實體

瀏覽器訪問占比情況VO

@Data
public class AccessBrowserGroupVo {
    
    private String browser;
    
    private Integer count;
}

運營商訪問占比情況VO

@Data
public class AccessLspGroupVo {
    
    private String lsp;
    
    private Integer count;
}

各省份訪問情況VO

@Data
public class AccessProvinceGroupVo {
    
    private String province;
    
    private Integer count;
}

每天訪問情況VO

@Data
public class AccessTimeGroupVo {
    
    private String accessTime;
    
    private Integer count;
}

查詢SQL

瀏覽器訪問統(tǒng)計

<select id="countBrowserGroupAccess" resultType="com.xiaoyuan.common.vo.logs.AccessBrowserGroupVo">
  select browser, count(*) as count from access_log group by browser
</select>

運營商訪問統(tǒng)計

<select id="countLspGroupAccess" resultType="com.xiaoyuan.common.vo.logs.AccessLspGroupVo">
  select lsp, count(*) as count from access_log group by lsp
</select>

各省份訪問統(tǒng)計

<select id="countProvinceGroupAccess" resultType="com.xiaoyuan.common.vo.logs.AccessProvinceGroupVo">
  select province, count(*) as count from access_log group by province order by count desc limit 15
</select>

近15天內(nèi)訪問統(tǒng)計

<select id="countTimeGroupAccess" resultType="com.xiaoyuan.common.vo.logs.AccessTimeGroupVo">
    SELECT
        date_match.date_c as access_time,
        IFNULL( count, 0 ) as count
    FROM
        (
            SELECT
                DATE_FORMAT( @now := date_sub( @now, INTERVAL 1 DAY ), '%Y-%m-%d' ) AS date_c
            FROM
                ( SELECT @now := date_add( CURDATE(), INTERVAL 1 DAY ) FROM access_log LIMIT 15 ) date_match
            ORDER BY
                date_c
        ) date_match
            LEFT JOIN (
            SELECT
                DATE_FORMAT( access_time, '%Y-%m-%d' ) AS access_time,
                count(*) AS count
            FROM
                access_log
            WHERE
                    access_time >= (
                    SELECT
                        date_sub( curdate(), INTERVAL 15 DAY ))
            GROUP BY
                DATE_FORMAT( access_time, '%Y-%m-%d' )
        ) acc ON acc.access_time = date_match.date_c
</select>

后端業(yè)務(wù)

封裝統(tǒng)一接口返回

/**
 * FileName:    R
 * Author:      小袁
 * Date:        2022/3/12 12:23
 * Description: 統(tǒng)一結(jié)果返回的類
 */
@Data
public class R<T> {

    private Boolean success;

    private Integer code;

    private String message;

    private T data;

    // 成功靜態(tài)方法
    public static <T> R<T> success() {
        R<T> r = new R<>();
        r.setSuccess(true);
        r.setCode(HttpStatusEnum.SUCCESS.getCode());
        r.setMessage(HttpStatusEnum.SUCCESS.getName());
        return r;
    }

    public static <T> R<T> success(String message) {
        R<T> r = new R<>();
        r.setSuccess(true);
        r.setCode(HttpStatusEnum.SUCCESS.getCode());
        r.message(message);
        return r;
    }

    public static <T> R<T> success(T object) {
        R<T> r = new R<>();
        r.setData(object);
        r.setSuccess(true);
        r.setCode(HttpStatusEnum.SUCCESS.getCode());
        r.setMessage(HttpStatusEnum.SUCCESS.getName());
        return r;
    }

    public static <T> R<T> success(String msg, T object) {
        R<T> r = new R<>();
        r.setData(object);
        r.setCode(HttpStatusEnum.SUCCESS.getCode());
        r.setMessage(msg);
        return r;
    }

    // 失敗靜態(tài)方法
    public static <T> R<T> fail() {
        R<T> r = new R<>();
        r.setSuccess(false);
        r.setCode(HttpStatusEnum.FAIL.getCode());
        r.setMessage(HttpStatusEnum.FAIL.getName());
        return r;
    }

    public static <T> R<T> fail(String msg) {
        R<T> r = new R<>();
        r.setSuccess(false);
        r.setCode(HttpStatusEnum.FAIL.getCode());
        r.setMessage(msg);
        return r;
    }

    public static <T> R<T> fail(HttpStatusEnum httpStatusEnum) {
        R<T> r = new R<>();
        r.setSuccess(false);
        r.setCode(httpStatusEnum.getCode());
        r.setMessage(httpStatusEnum.getName());
        return r;
    }

    public R<T> message(String message){
        this.setMessage(message);
        return this;
    }

    public R<T> code(Integer code){
        this.setCode(code);
        return this;
    }

    public R<T> data(T data){
        this.setData(data);
        return this;
    }
}

封裝客戶端響應(yīng)碼

/**
 * FileName:    Code
 * Author:      小袁
 * Date:        2022/5/1 23:29
 * Description: 客戶端響應(yīng)狀態(tài)碼
 */
public enum HttpStatusEnum implements BaseCodeEnum {

    SUCCESS(200, "成功"),
    FAIL(20001, "失敗"),
    INTERNAL_SERVER_ERROR(500, "服務(wù)器異常"),

    private final Integer code;
    private final String name;

    HttpStatusEnum(int code, String msg) {
        this.code = code;
        this.name = msg;
    }

    @Override
    public Integer getCode() {
        return this.code;
    }

    @Override
    public String getName() {
        return this.name;
    }
}

Mapper接口

@Repository
public interface AccessLogMapper extends BaseMapper<AccessLog> {

    List<AccessLspGroupVo> countLspGroupAccess();

    List<AccessBrowserGroupVo> countBrowserGroupAccess();

    List<AccessProvinceGroupVo> countProvinceGroupAccess();

    List<AccessTimeGroupVo> countTimeGroupAccess();
}

Service接口

public interface AccessLogService extends IService<AccessLog> {

    List<AccessLspGroupVo> countLspGroupAccess();

    List<AccessBrowserGroupVo> countBrowserGroupAccess();

    List<AccessProvinceGroupVo> countProvinceGroupAccess();

    List<AccessTimeGroupVo> countTimeGroupAccess();
}

Service實現(xiàn)類

@Slf4j
@Service
public class AccessLogServiceImpl extends ServiceImpl<AccessLogMapper, AccessLog> implements AccessLogService {
    
    @Override
    public List<AccessLspGroupVo> countLspGroupAccess() {
        return this.baseMapper.countLspGroupAccess();
    }

    @Override
    public List<AccessBrowserGroupVo> countBrowserGroupAccess() {
        return this.baseMapper.countBrowserGroupAccess();
    }

    @Override
    public List<AccessProvinceGroupVo> countProvinceGroupAccess() {
        return this.baseMapper.countProvinceGroupAccess();
    }

    @Override
    public List<AccessTimeGroupVo> countTimeGroupAccess() {
        return this.baseMapper.countTimeGroupAccess();
    }
}

Controller接口

@RestController
@RequestMapping("/stat/access")
public class AccessStatController {
    
    @Autowired
    private AccessLogService accessLogService;

    /**
     * 查詢15天內(nèi)的訪問次數(shù)情況-折線圖
     */
    @GetMapping("/query_line_by_day")
    public R<List<AccessTimeGroupVo>> queryAccessLogByTimeGroup() {
        return R.success(accessLogService.countTimeGroupAccess());
    }

    /**
     * 查詢省份訪問占比-柱形圖
     */
    @GetMapping("/query_col_by_province")
    public R<List<AccessProvinceGroupVo>> queryAccessLogByProvinceGroup() {
        return R.success(accessLogService.countProvinceGroupAccess());
    }

    /**
     * 查詢運營商訪問占比-餅圖
     */
    @GetMapping("/query_pie_by_lsp")
    public R<List<AccessLspGroupVo>> queryAccessLogByLspGroup() {
        return R.success(accessLogService.countLspGroupAccess());
    }

    /**
     * 查詢?yōu)g覽器訪問占比-餅圖
     */
    @GetMapping("/query_pie_by_browser")
    public R<List<AccessBrowserGroupVo>> queryAccessLogByBrowserGroup() {
        return R.success(accessLogService.countBrowserGroupAccess());
    }
}

前端配置

安裝axios、echarts

npm install axios
npm install echarts

封裝request

import axios from 'axios'
import { Message, MessageBox,} from 'element-ui'
import store from '../store'
import { getToken } from '@/utils/auth'
import router from '@/router'

// 創(chuàng)建axios實例
const service = axios.create({
  baseURL: process.env.BASE_API, // api 的 base_url
  // timeout: 5000 // 請求超時時間
})

// request攔截器
service.interceptors.request.use(
  config => {
    if (store.getters.token) {
     config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)

// response 攔截器
service.interceptors.response.use(
  response => {
    /**
     * code為非200是拋錯 可結(jié)合自己業(yè)務(wù)進行修改
     */
    const res = response.data

    const url = response.config.url

    if (res.code !== 200) {
      if (url.indexOf("/login") < 0 && res.code === 40005) {
        store.dispatch('FedLogOut').then(() => {
          router.push(`/login`)
        })
        Message({
          message: res.message,
          type: 'warning',
          duration: 2 * 1000,
        })

        return Promise.resolve(res)
      }else if (res.code >= 40000) {
        Message({
          message: res.message,
          type: 'error',
          duration: 3 * 1000
        })
        return Promise.resolve(res)
      }else {
        Message({
          message: res.message,
          type: 'error',
          duration: 5 * 1000
        })
        return Promise.reject(new Error(res.message || 'Error'))
      }
    } else {
      return res
    }
  },
  error => {
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

定義API

import request from "../../utils/request";

export default {
  getAccessStatByTime() {
    return request({
      url: '/stat/access/query_line_by_day',
      method: 'get'
    })
  },

  getAccessStatByProvince() {
    return request({
      url: '/stat/access/query_col_by_province',
      method: 'get'
    })
  },

  getAccessStatByLsp() {
    return request({
      url: '/stat/access/query_pie_by_lsp',
      method: 'get'
    })
  },

  getAccessStatByBrowser() {
    return request({
      url: '/stat/access/query_pie_by_browser',
      method: 'get'
    })
  },
}

封裝echarts

<template>
  <div :id="id" :class="className" :style="{ height: height, width: width }" />
</template>

<script>
import * as echarts from 'echarts'
export default {
  name: 'echart',
  props: {
    className: {
      type: String,
      default: 'chart'
    },
    id: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '2.5rem'
    },
    options: {
      type: Object,
      default: ()=>({})
    }
  },
  data () {
    return {
      chart: null
    }
  },
  watch: {
    options: {
      handler (options) {
        // 設(shè)置true清空echart緩存
        this.chart.setOption(options, true)
      },
      deep: true
    }
  },
  mounted () {
    // echarts.registerTheme('tdTheme', tdTheme); // 覆蓋默認主題
    this.initChart();
  },
  beforeDestroy () {
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart () {
      // 初始化echart
      this.chart = echarts.init(this.$el)
      this.chart.setOption(this.options, true)
    }
  }
}
</script>

<style>
body {
  margin: 0;
  padding: 0;
}
</style>

餅圖-瀏覽器訪問占比

<template>
  <div>
    <Echart :options="options"
      id="lspEcharts"
      height="300px"
      width="100%"/>
  </div>
</template>

<script>
  import statAccess from "@/api/stat/statAccess";
  import Echart from "@/components/Echart/index.vue";

  export default {
    components: {
      Echart
    },
    data() {
      return {
        options: {},
        lspData: []
      }
    },
    methods: {
      initData() {
        statAccess.getAccessStatByBrowser().then(res => {
          this.lspData = res.data.map(obj => {
            return {
              name: obj.browser,
              value: obj.count
            }
          })
          this.executeDraw()
        })
      },
      executeDraw() {
        this.options = {
          title: {
            text: '瀏覽器訪問占比',
            left: 'center',
            textStyle: {
              color: '#FDF5E6'
            }
          },
          tooltip: {
            trigger: 'item'
          },
          legend: {
            orient: 'vertical',
            left: 'left',
            top: '20%',
            textStyle: {
              color: '#FDF5E6'
            }
          },
          series: [
            {
              name: '訪問次數(shù)',
              type: 'pie',
              radius: '90%',
              top: '20%',
              data: this.lspData,
              label: {
                color: '#FDF5E6'
              },
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        }
      }
    },
    mounted() {
      this.initData()
    }
  }
</script>

餅圖-運營商訪問占比

<template>
  <div>
    <Echart :options="options"
            id="lspEcharts"
            height="300px"
            width="100%"/>
  </div>
</template>

<script>
import statAccess from "@/api/stat/statAccess";
import Echart from "@/components/Echart/index.vue";

export default {
  components: {
    Echart
  },
  data() {
    return {
      options: {},
      lspData: []
    }
  },
  methods: {
    initData() {
      statAccess.getAccessStatByLsp().then(res => {
        this.lspData = res.data.map(obj => {
          return {
            name: obj.lsp,
            value: obj.count
          }
        })
        this.executeDraw()
      })
    },
    executeDraw() {
      this.options = {
        title: {
          text: '運營商訪問占比',
          left: 'center',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        tooltip: {
          trigger: 'item'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          top: '20%',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        series: [
          {
            name: '訪問次數(shù)',
            type: 'pie',
            radius: '90%',
            top: '20%',
            data: this.lspData,
            label: {
              color: '#FDF5E6'
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      }
    }
  },
  mounted() {
    this.initData()
  }
}
</script>

折線圖-每天訪問量情況

<template>
  <div>
    <Echart :options="options"
            id="timeEcharts"
            height="400px"
            width="100%"/>
  </div>
</template>

<script>
import statAccess from "@/api/stat/statAccess";
import Echart from "@/components/Echart/index.vue";

export default {
  components: {
    Echart
  },
  data() {
    return {
      options: {},
      xAxis: [],
      yAxis: []
    }
  },
  methods: {
    initData() {
      statAccess.getAccessStatByTime().then(res => {
        let x = []
        let y = []
        for (let i = 0; i < res.data.length; i++) {
          x.push(res.data[i].accessTime)
          y.push(res.data[i].count)
        }
        this.xAxis = x
        this.yAxis = y
        this.executeDraw()
      })
    },
    executeDraw() {
      this.options = {
        title: {
          show: true,
          text: '小袁博客15天內(nèi)訪問情況統(tǒng)計',
          left: 'center',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        legend: {
          show: true,
          left: '1%',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'line' }
        },
        grid:{
          left:"1%",
          right:"1%",
          bottom:"1%",
          containLabel:true,
        },
        xAxis: {
          type: 'category',
          data: this.xAxis,
          boundaryGap: ['5%', '5%',],//坐標軸兩邊留白
          axisLabel: {
            color: '#FDF5E6'
          },
          axisLine: {//坐標軸
            lineStyle:{
              opacity: 0.01,//設(shè)置透明度就可以控制顯示不顯示
            },
          },
          splitLine: {//網(wǎng)格線
            lineStyle:{
              color: '#eeeeee',
            },
          },
          axisTick: {//刻度線
            show: false,//去掉刻度線
          },
        },
        yAxis: {
          type: 'value',
          name:'次         ',//是基于Y軸線對齊,用空格站位讓坐標軸名稱與刻度名稱對齊
          axisLabel: {
            color: '#eee'
          },
          nameTextStyle: {
            color:'#444e65',
            align:'left',//文字水平對齊方式
            verticalAlign:'middle',//文字垂直對齊方式
          },
          axisTick: {//刻度線
            show: false,//去掉刻度線
          },
          axisLine: {//坐標軸線
            lineStyle:{
              opacity: 0,//透明度為0
            },
          },
          splitLine: {//網(wǎng)格線
            show: true,//網(wǎng)格線
            lineStyle:{
              color: 'rgba(211, 211, 211, 0.5)',
            },
          },
        },
        series: [
          {
            data: this.yAxis,
            smooth: true,
            type: 'line',
            name: '訪問次數(shù)',
            itemStyle: {//折線拐點標志的樣式。
              normal: {
                color: '#98F5FF',
              },
            },
          }
        ]
      }
    }
  },
  mounted() {
    this.initData()
  }
}
</script>

柱狀圖-各省份訪問情況

<template>
  <div>
    <Echart :options="options"
            id="lspEcharts"
            height="300px"
            width="100%"/>
  </div>
</template>

<script>
import statAccess from "@/api/stat/statAccess";
import Echart from "@/components/Echart/index.vue";

export default {
  components: {
    Echart
  },
  data() {
    return {
      options: {},
      axis: [],
      series: []
    }
  },
  methods: {
    initData() {
      statAccess.getAccessStatByProvince().then(res => {
        let x = []
        let y = []
        for (let i = 0; i < res.data.length; i++) {
          x.push(res.data[i].province)
          y.push(res.data[i].count)
        }
        this.axis = x
        this.series = y
        this.executeDraw()
      })
    },
    executeDraw() {
      this.options = {
        tooltip: {},
        title: {
          text: '各城市訪問情況占比',
          left: 'center',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        grid:{
          left: "1%",
          right: "1%",
          bottom: "1%",
          containLabel: true,
        },
        legend: {
          show: true,
          left: '1%',
          textStyle: {
            color: '#FDF5E6'
          }
        },
        xAxis: {
          data: this.axis,
          axisLine: {
            show: false,
          },
          axisLabel: {
            color: '#FDF5E6'
          }
        },
        yAxis: {
          // 網(wǎng)格樣式
          splitLine: {
            show: false,
          },
          axisLabel: {
            color: '#FDF5E6'
          }
        },
        series: [{
          name: '訪問量',
          type: 'bar',
          data: this.series,
          barWidth: 15,
          itemStyle: {
            color: {
              type:'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [
                {
                  offset: 0,
                  color: 'rgba(255, 130, 71, 1)',
                },
                {
                  offset: 1,
                  color: 'rgba(255, 130, 71, 0.5)',
                },
              ],
              globaCoord: false,
            },
            barBorderRadius: [5, 5, 0, 0], // (順時針左上,右上,右下,左下)
          },
        }],
      }
    }
  },
  mounted() {
    this.initData()
  }
}
</script>

首頁

直接引入

<template>
  <div class="dashboard-container">
    <div class="dashboard-bg"></div>
    <div class="echart-div">
      <el-row :gutter="1" class="item">
      <el-col :span="8">
        <BrowserPie></BrowserPie>
      </el-col>
      <el-col :span="16">
        <TimeLine></TimeLine>
      </el-col>
      </el-row>
      <el-row style="margin-top: 35px" class="item">
        <el-col span="8">
          <LspPie></LspPie>
        </el-col>
        <el-col span="16">
          <ProvinceCol></ProvinceCol>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import LspPie from "./components/LspPie.vue";
import ProvinceCol from "./components/ProvinceCol.vue";
import BrowserPie from "./components/BrowserPie.vue";
import TimeLine from "./components/TimeLine.vue";

export default {
  components: {
    LspPie,
    ProvinceCol,
    BrowserPie,
    TimeLine
  },
  name: 'home',
  data() {
    return {
    }
  },
  mounted() {
  },
  methods: {
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.dashboard {
  &-container {
    .echart-div {
      padding: 30px;
    }
  }
  &-text {
    font-size: 22px;
    line-height: 46px;
  }
  .personal {
    .box-card-header {
      position: relative;
      height: 220px;
      img {
        width: 100%;
        height: 100%;
        transition: all 0.2s linear;
        &:hover {
          transform: scale(1.1, 1.1);
          filter: contrast(130%);
        }
      }
    }
  }
}
.dashboard {
  &-bg {
    background-image: url('../../assets/img/home_bg.png');
    background-size: cover;
    background-repeat: no-repeat;
    background-attachment: fixed; /* 可選,固定背景圖片 */
    background-position: center; /* 可選,設(shè)置背景圖片位置 */
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    filter: blur(1px);
  }
}
</style>

結(jié)束

到這里整篇文章就結(jié)束了,我們重新捋一下整個流程

  • 全局過濾器攔截請求
  • 對請求信息進行解析入庫
  • 定義API接口
  • 前端引入axios、echarts
  • 編寫圖形Vue組件
  • 前后端數(shù)據(jù)交互

以上就是SpringBoot整合Echarts實現(xiàn)數(shù)據(jù)大屏的詳細內(nèi)容,更多關(guān)于SpringBoot Echarts數(shù)據(jù)大屏的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java 實現(xiàn)微信和支付寶支付功能

    Java 實現(xiàn)微信和支付寶支付功能

    這篇文章主要介紹了Java 實現(xiàn)微信和支付寶支付功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • springcloud下hibernate本地化方言配置方式

    springcloud下hibernate本地化方言配置方式

    這篇文章主要介紹了springcloud下hibernate本地化方言配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • springcloud?feign服務(wù)之間調(diào)用,date類型轉(zhuǎn)換錯誤的問題

    springcloud?feign服務(wù)之間調(diào)用,date類型轉(zhuǎn)換錯誤的問題

    這篇文章主要介紹了springcloud?feign服務(wù)之間調(diào)用,date類型轉(zhuǎn)換錯誤的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java目錄樹的創(chuàng)建與獲取

    Java目錄樹的創(chuàng)建與獲取

    在Java開發(fā)中,經(jīng)常會涉及到生成目錄樹的需求,本文主要介紹了Java目錄樹的創(chuàng)建與獲取,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-03-03
  • java中的forkjoin框架的使用

    java中的forkjoin框架的使用

    這篇文章主要介紹了java中的fork join框架的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • Maven清理java項目中未使用到 jar 依賴包的方法

    Maven清理java項目中未使用到 jar 依賴包的方法

    本文主要介紹了Maven清理java項目中未使用到 jar 依賴包的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • springcloud?gateway無法路由問題的解決

    springcloud?gateway無法路由問題的解決

    gateway網(wǎng)關(guān)的重要作用之一便是進行路由轉(zhuǎn)發(fā)工作,下面這篇文章主要給大家介紹了關(guān)于springcloud?gateway無法路由問題的解決方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • java解析JT808協(xié)議的實現(xiàn)代碼

    java解析JT808協(xié)議的實現(xiàn)代碼

    這篇文章主要介紹了java解析JT808協(xié)議的實現(xiàn)代碼,需要的朋友可以參考下
    2020-03-03
  • Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    Spring?Boot中KafkaListener的介紹、原理和使用方法案例詳解

    本文介紹了Spring Boot中 @KafkaListener 注解的介紹、原理和使用方法,通過本文的介紹,我們希望讀者能夠更好地理解Spring Boot中 @KafkaListener 注解的使用方法,并在項目中更加靈活地應(yīng)用
    2023-09-09
  • 基于Maven?pom文件中屬性變量總結(jié)

    基于Maven?pom文件中屬性變量總結(jié)

    這篇文章主要介紹了Maven?pom文件中屬性變量總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論