当前位置: 首页 > article >正文

项目功能--会员数量折线图

       一、需求分析

         会员信息是机构的核心数据,其会员数量和增长数量可以反映出机构的部分运营情况。通过折线图可以直观的反映出会员数量的增长趋势。我们要展示过去一年时间内每个月的会员总数据量。

        二、代码实现

        ECharts简介:
        ECharts缩写来自Enterprise Charts,商业级数据图表,是一个开源的使用JavaScript实现的数据可视化工具,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,提供直观、交互丰富、可高度个性化定制的数据可视化图表。

实现步骤:
步骤一:将echarts.js文件复制到工程的plugins目录下

步骤二:在report_member.html页面引入echarts.js文件

<script src="../plugins/echarts/echarts.js"></script>

步骤三:参照官方实例导入折线图

<script type="text/javascript">
  // 基于准备好的dom,初始化echarts实例
  var myChart1 = echarts.init(document.getElementById('chart1'));
  //发送ajax请求获取动态数据
  axios.get("/report/getMemberReport.do").then((res)=>{
    myChart1.setOption(
      {
        title: {
          text: '会员数量'
        },
        tooltip: {},
        legend: {
          data:['会员数量']
        },
        xAxis: {
          data: res.data.data.months
        },
        yAxis: {
          type:'value'
        },
        series: [{
          name: '会员数量',
          type: 'line',
          data: res.data.data.memberCount
        }]
      });
  });
</script>

步骤四:根据折线图对数据格式的要求,我们发送ajax请求,服务端需要返回如下格式的数据:

{
    "data":{
            "months":["2023.01","2023.02","2023.03","2023.04"],
            "memberCount":[100,150,200,300]
           },
    "flag":true,
    "message":"获取会员统计数据成功"
}

步骤五:编写controller代码,编写测试数据 测试

//会员数量折线图数据
    @RequestMapping("/getMemberReport")
    public Result getMemberReport(){
        //使用模拟数据测试对象格式是否能够转为Echars所需的数据格式
        Map<String,Object> map = new HashMap<>();

        List<String> months = new ArrayList();
        months.add("2023.05");
        months.add("2023.06");
        months.add("2023.07");
        months.add("2023.08");
        months.add("2023.09");
        map.put("months",months);

        List<Integer> memberCount = new ArrayList<>();
        memberCount.add(100);
        memberCount.add(150);
        memberCount.add(180);
        memberCount.add(200);
        memberCount.add(300);

        map.put("memberCount",memberCount);


        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
    }

步骤六:编写controller类

/**
 * 报表操作
 */
@RestController
@RequestMapping("/report")
public class ReportController {
    @Reference
    private MemberService memberService;
    //会员数量折线图数据
    @RequestMapping("/getMemberReport")
    public Result getMemberReport(){
        Map<String,Object> map = new HashMap<>();
        List<String> months = new ArrayList();
        Calendar calendar = Calendar.getInstance();//获得日历对象,模拟时间就是当前时间
        //计算过去一年的12个月
        calendar.add(Calendar.MONTH,-12);//获得当前时间往前推12个月的时间
        for(int i=0;i<12;i++){
            calendar.add(Calendar.MONTH,1);//获得当前时间往后推一个月日期
            Date date = calendar.getTime();
            months.add(new SimpleDateFormat("yyyy.MM").format(date));
        }
        map.put("months",months);

        List<Integer> memberCount = memberService.findMemberCountByMonths(months);
        map.put("memberCount",memberCount);
        return new Result(true, MessageConstant.GET_MEMBER_NUMBER_REPORT_SUCCESS,map);
    }
}

步骤七:编写服务接口和服务实现类

在MemberService服务接口中扩展方法findMemberCountByMonth

public List<Integer> findMemberCountByMonth(List<String> month);

在MemberServiceImpl服务实现类中实现findMemberCountByMonth方法

//根据月份统计会员数量
public List<Integer> findMemberCountByMonth(List<String> month) {
  List<Integer> list = new ArrayList<>();
  for(String m : month){
    m = m + ".31";//格式:2023.5.31
    Integer count = memberDao.findMemberCountBeforeDate(m);
    list.add(count);
  }
  return list;
}

步骤八:编写Dao接口和Mapper映射文件

在MemberDao接口中扩展方法findMemberCountBeforeDate

public Integer findMemberCountBeforeDate(String date);

在MemberDao.xml映射文件中提供SQL语句

<!--根据日期统计会员数,统计指定日期之前的会员数-->
<select id="findMemberCountBeforeDate" parameterType="string" resultType="int">
  select count(id) from t_member where regTime &lt;= #{value}
</select>

实现成功,测试运行。


http://www.kler.cn/a/388547.html

相关文章:

  • 【Golang】Channel的ring buffer实现
  • 深入理解接口测试:实用指南与最佳实践5.0(三)
  • Java的dto,和多表的调用
  • flink sql + kafka + mysql 如何构建实时数仓
  • 【C++】new操作符的使用说明
  • Java设计模式面试题及参考答案
  • 【计网不挂科】计算机网络期末考试(综合)——【选择题&填空题&判断题&简述题】完整试卷
  • EPLAN商业版与教育版的功能区别有多大
  • 「QT」几何数据类 之 QPoint 整型点类
  • 学习日记_20241110_聚类方法(K-Means)
  • MatSci-LLM ——潜力和挑战以及大规模语言模型在材料科学中的应用
  • 手机上用什么方法可以切换ip
  • 设计模式之建造者模式(各项装修物料组合套餐选配场景)
  • 边缘的检测
  • ssh中公钥和私钥是具体作用,以及通俗解释
  • JavaSecLab靶场搭建
  • JavaWeb:文件上传1
  • (Go基础)变量与常量?字面量与变量的较量!
  • 微信小程序官方评价组件wxacommentplugin下线后如何巧妙调用
  • 【网络原理】关于HTTP状态码以及请求的构造的哪些事
  • 扁平化在APP设计领域成了过眼云烟,3D拟物化又开始回归了。
  • WPF中的依赖属性
  • 「QT」几何数据类 之 QSizeF 浮点型尺寸类
  • 14、NAT和桥接区别
  • STM32F405RGT6单片机原理图、PCB免费分享
  • 智慧城市路面垃圾识别系统产品介绍方案