10.9.1-Dataway+Echarts动态图表方案

news/2024/11/29 13:29:25/

文章目录

  • 1. 技术选型
  • 2. 实现方案
    • 2.1. 方案介绍
    • 2.2. 方案实现(demo)
      • 2.2.1. 使用echarts绘制html静态页
        • 2.2.1.1. 选择合适的图表
        • 2.2.1.2. 下载html demo
      • 2.2.2. 使用Dataway准备数据接口
        • 2.2.2.1. 部署dataway
        • 2.2.2.2. 创建数据接口
      • 2.2.3. 调试html demo + dataway接口
      • 2.2.4. 发布html到nginx
        • 2.2.4.1. 将完整url,放入到系统菜单上(配置菜单),使其可访问
  • 3. 后期工作

整体 目标:

无代码或低代码,可以实现数据的图形化显示。

1. 技术选型

  • 图表:Apache ECharts。样例官网:https://echarts.apache.org/examples/zh/index.html
  • 后端接口数据:Hasor Dataway。官网:https://www.dataql.net/docs/dataway/overview

2. 实现方案

2.1. 方案介绍

**流程整合方案:**Dataway数据接口 + ECharts绘制Html = 动态图表

  • 工作流图:

  • 数据流图:

2.2. 方案实现(demo)

我们以一个日历图为例,来看一个动态图表实现的全过程。

  • 目标:在日历图上,显示有数据推送的日期,并根据推送的数据量多少,对日期色块以深浅进行区分。

  • 效果:

2.2.1. 使用echarts绘制html静态页

根据需求,从Apache ECharts样例官网:https://echarts.apache.org/examples/zh/index.html,筛选符合需求的图表。

2.2.1.1. 选择合适的图表

日历坐标系可以满足。

2.2.1.2. 下载html demo

下载样例,下载到的是一个完整可运行的html demo

<!--此示例下载自 https://echarts.apache.org/examples/zh/editor.html?c=calendar-simple
-->
<!DOCTYPE html>
<html lang="zh-CN" style="height: 100%">
<head><meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0"><div id="container" style="height: 100%"></div><script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script><script type="text/javascript">var dom = document.getElementById('container');var myChart = echarts.init(dom, null, {renderer: 'canvas',useDirtyRect: false});var app = {};var option;function getVirtualData(year) {const date = +echarts.time.parse(year + '-01-01');const end = +echarts.time.parse(year + '-12-31');const dayTime = 3600 * 24 * 1000;const data = [];for (let time = date; time <= end; time += dayTime) {data.push([echarts.time.format(time, '{yyyy}-{MM}-{dd}', false),Math.floor(Math.random() * 10000)]);}return data;
}
option = {visualMap: {show: false,min: 0,max: 10000},calendar: {range: '2017'},series: {type: 'heatmap',coordinateSystem: 'calendar',data: getVirtualData('2017')}
};if (option && typeof option === 'object') {myChart.setOption(option);}window.addEventListener('resize', myChart.resize);</script>
</body>
</html>

至此,静态页面有了,我们需要的是一个动态数据接口,选择使用dataway开源项目来实现动态接口的创建。

dataway手册:https://www.dataql.net/docs/dataway/overview

需要的数据格式应该是:

[['2022-11-16',9],['2022-11-17',8],['2022-12-03',66],['2022-12-05',1014],['2022-12-06',2253],['2022-12-07',135]
]

2.2.2. 使用Dataway准备数据接口

2.2.2.1. 部署dataway

只需要在基础的springboot开箱代码基础上加上maven依赖及少量配置,即可run一个dataway服务。

  • dataway依赖表创建

    CREATE TABLE `interface_release` (`pub_id` varchar(64) NOT NULL COMMENT 'Publish ID',`pub_api_id` varchar(64) NOT NULL COMMENT '所属API ID',`pub_method` varchar(12) NOT NULL COMMENT 'HttpMethod:GET、PUT、POST',`pub_path` varchar(512) NOT NULL COMMENT '拦截路径',`pub_status` varchar(4) NOT NULL COMMENT '状态:-1-删除, 0-草稿,1-发布,2-有变更,3-禁用',`pub_comment` varchar(255) NOT NULL COMMENT '注释',`pub_type` varchar(24) NOT NULL COMMENT '脚本类型:SQL、DataQL',`pub_script` mediumtext NOT NULL COMMENT '查询脚本:xxxxxxx',`pub_script_ori` mediumtext NOT NULL COMMENT '原始查询脚本,仅当类型为SQL时不同',`pub_schema` mediumtext NOT NULL COMMENT '接口的请求/响应数据结构',`pub_sample` mediumtext NOT NULL COMMENT '请求/响应/请求头样本数据',`pub_option` mediumtext NOT NULL COMMENT '扩展配置信息',`pub_release_time` varchar(32) NOT NULL COMMENT '发布时间(下线不更新)',PRIMARY KEY (`pub_id`),KEY `idx_interface_release_api` (`pub_api_id`),KEY `idx_interface_release_path` (`pub_path`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='Dataway API 发布历史。';CREATE TABLE `interface_release` (`pub_id` varchar(64) NOT NULL COMMENT 'Publish ID',`pub_api_id` varchar(64) NOT NULL COMMENT '所属API ID',`pub_method` varchar(12) NOT NULL COMMENT 'HttpMethod:GET、PUT、POST',`pub_path` varchar(512) NOT NULL COMMENT '拦截路径',`pub_status` varchar(4) NOT NULL COMMENT '状态:-1-删除, 0-草稿,1-发布,2-有变更,3-禁用',`pub_comment` varchar(255) NOT NULL COMMENT '注释',`pub_type` varchar(24) NOT NULL COMMENT '脚本类型:SQL、DataQL',`pub_script` mediumtext NOT NULL COMMENT '查询脚本:xxxxxxx',`pub_script_ori` mediumtext NOT NULL COMMENT '原始查询脚本,仅当类型为SQL时不同',`pub_schema` mediumtext NOT NULL COMMENT '接口的请求/响应数据结构',`pub_sample` mediumtext NOT NULL COMMENT '请求/响应/请求头样本数据',`pub_option` mediumtext NOT NULL COMMENT '扩展配置信息',`pub_release_time` varchar(32) NOT NULL COMMENT '发布时间(下线不更新)',PRIMARY KEY (`pub_id`),KEY `idx_interface_release_api` (`pub_api_id`),KEY `idx_interface_release_path` (`pub_path`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='Dataway API 发布历史。';
    
  • dataway springboot项目引入相关依赖

    <!--hasor dataway-->
    <dependency><groupId>net.hasor</groupId><artifactId>hasor-spring</artifactId><version>4.2.2</version>
    </dependency>
    <dependency><groupId>net.hasor</groupId><artifactId>hasor-dataway</artifactId><version>4.2.2</version>
    </dependency><!--作为 Spring Boot 项目有着自己完善的数据库方面工具支持。我们这次采用 druid + mysql + spring-boot-starter-jdbc 的方式。-->
    <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.30</version>
    </dependency>
    <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version>
    </dependency>
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version>
    </dependency>
    
  • dataway springboot项目配置

    # 解决接口返回中文都是乱码
    server.servlet.encoding.charset=utf-8
    server.servlet.encoding.force=true
    server.servlet.encoding.enabled=true# 是否启用 Dataway 功能(必选:默认false)
    HASOR_DATAQL_DATAWAY=true
    # 是否开启 Dataway 后台管理界面(必选:默认false)
    HASOR_DATAQL_DATAWAY_ADMIN=true
    # dataway  API工作路径(可选,默认:/api/)
    HASOR_DATAQL_DATAWAY_API_URL=/api/
    # dataway-ui 的工作路径(可选,默认:/interface-ui/)
    HASOR_DATAQL_DATAWAY_UI_URL=/interface-ui/
    # SQL执行器方言设置(可选,建议设置)
    HASOR_DATAQL_FX_PAGE_DIALECT=mysql# db
    spring.datasource.url=jdbc:mysql://localhost:3306/cdc?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=Asia/Shanghai
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    # druid
    spring.datasource.druid.initial-size=3
    spring.datasource.druid.min-idle=3
    spring.datasource.druid.max-active=10
    spring.datasource.druid.max-wait=60000
    spring.datasource.druid.stat-view-servlet.login-username=admin
    spring.datasource.druid.stat-view-servlet.login-password=admin
    spring.datasource.druid.filter.stat.log-slow-sql=true
    spring.datasource.druid.filter.stat.slow-sql-millis=1
    
  • dataway springboot把数据源设置到 Hasor 容器中

    package com.example.simple;import net.hasor.core.ApiBinder;
    import net.hasor.core.DimModule;
    import net.hasor.db.JdbcModule;
    import net.hasor.db.Level;
    import net.hasor.spring.SpringModule;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;import javax.sql.DataSource;@DimModule
    @Component
    public class ExampleModule implements SpringModule {@Autowiredprivate DataSource dataSource = null;@Overridepublic void loadModule(ApiBinder apiBinder) throws Throwable {// .DataSource form Spring boot into HasorapiBinder.installModule(new JdbcModule(Level.Full, this.dataSource));}
    }
    
  • 在 dataway springboot 中启用 Hasor

    package com.example.simple;import net.hasor.spring.boot.EnableHasor;
    import net.hasor.spring.boot.EnableHasorWeb;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;@EnableHasor()
    @EnableHasorWeb()
    @SpringBootApplication
    public class SimpleApplication {public static void main(String[] args) {System.setProperty("file.encoding","UTF-8");SpringApplication.run(SimpleApplication.class, args);}}
  • 至此,即可启动应用

2.2.2.2. 创建数据接口

书接上回,我们需要的数据格式应该是:

[['2022-11-16',9],['2022-11-17',8],['2022-12-03',66],['2022-12-05',1014],['2022-12-06',2253],['2022-12-07',135]
]
  • sql编写

    对此,我们如果通过简单的sql,按天汇总数据量,那sql应该这么写:

    select DATE_FORMAT(add_time,'%Y-%m-%d') as time,sum(received_data_total) as sum 
    from cdc.`cdc_receive_round_log` where add_time > '2022-10-01' and data_platform='zgl' group by DATE_FORMAT(add_time,'%Y-%m-%d') ;
    

    在mysql中执行结果如下:

  • 基于sql,在dataway中创建接口

  • 验证接口是否可访问

    在浏览器访问: http://localhost:8080/api/received_count_per_day2

    可以拿到结果:

    {"success":true,"message":"OK","code":0,"lifeCycleTime":128,"executionTime":32,"value":{"zgl":[{"time":"2022-11-16","sum":9},{"time":"2022-11-17","sum":8},{"time":"2022-12-03","sum":66},{"time":"2022-12-05","sum":1014},{"time":"2022-12-06","sum":2253},{"time":"2022-12-07","sum":135}],"hsh":[{"time":"2022-10-08","sum":582},{"time":"2022-10-11","sum":165},{"time":"2022-10-14","sum":400},{"time":"2022-10-26","sum":200},{"time":"2022-11-03","sum":427},{"time":"2022-11-11","sum":200},{"time":"2022-11-18","sum":1500},{"time":"2022-11-30","sum":700},{"time":"2022-12-01","sum":882746},{"time":"2022-12-02","sum":260753}]}}
    

    上述如图:

but:

dataway接口返回的数据value.zgl内的报文,是一个list中嵌套dict。但是我们echarts需要的数据报文,是list里嵌套list。

我们要怎么将dataway的返参结果调整为echarts所需结构?

方案有二:

其一:通过dataway的dataql语法进行调整

其二:在echarts html中,拿到dataway接口数据报文后,通过js进行调整。

经过思考,毋庸置疑应选方案二,以减少学习成本。(下一节描述此案例如何调整。)

2.2.3. 调试html demo + dataway接口

直接看代码注释:

<!DOCTYPE html>
<html lang="zh-CN" style="height: 100%"><head><meta charset="utf-8">
</head><body style="height: 100%; margin: 0"><!-- 图表容器 --><div id="container" style="height: 100%"></div><!-- echarts js --><script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.4.1/dist/echarts.min.js"></script><!-- 由于需要异步加载数据,此处需要引入jquery --><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script><script type="text/javascript">// 获取dom,以便使用echarts进行渲染var dom = document.getElementById('container');var myChart = echarts.init(dom, null, {renderer: 'canvas',useDirtyRect: false});// 异步加载数据,http://localhost:8080/api/received_count_per_day2 就是我们使用dataway动态创建的接口$.get('http://localhost:8080/api/received_count_per_day2').done(function (data) {// zgl日历数据处理,将list嵌套dict,改为list嵌套list结构。var zgl_origion = data.value.zglvar zgl_echarts_data = []for (var i = 0; i < zgl_origion.length; i++) {var item = []item.push(zgl_origion[i]['time'])item.push(zgl_origion[i]['sum'])zgl_echarts_data.push(item)}//hsh日历数据处理,将list嵌套dict,改为list嵌套list结构。var hsh_origion = data.value.hshvar hsh_echarts_data = []for (var i = 0; i < hsh_origion.length; i++) {var item = []item.push(hsh_origion[i]['time'])item.push(hsh_origion[i]['sum'])hsh_echarts_data.push(item)}// 渲染图表myChart.setOption({title: {text: '' // 图表的头部文本},tooltip: {// 在划过日期块的时候,显示日期和数据。不写的话,默认只会显示数值,没有日期。formatter: function (p) {var format = echarts.format.formatTime('yyyy-MM-dd', p.data[0]);return format + '数量: ' + p.data[1];}},visualMap: {show: false,min: 0,max: 5000,textStyle: { color: '#000' },precision: 0,inRange: {// 在线调色板 https://www.sojson.com/web/panel.html// 色块深浅,将从下面的列表中根据数值大小自动选择color: ['#D4EFDF', '#82E0AA', '#58D68D', '#27AE60', '#229954', '#196F3D'],colorAlpha: 0.9, // 图元的颜色的透明度}},calendar: [{range: '2022',dayLabel: {show: true}},{top: 260,range: '2022',// cellSize: ['auto', 20]}],series: [{type: 'heatmap',coordinateSystem: 'calendar',data: zgl_echarts_data // zgl数据渲染},{type: 'heatmap',coordinateSystem: 'calendar',calendarIndex: 1,data: hsh_echarts_data  // hsh数据渲染}]})});window.addEventListener('resize', myChart.resize);</script>
</body></html>

然后,直接用浏览器访问此页面,或在vscode中的live server进行访问:

可以看到,dataway是已经允许了跨域访问的,无需再做调整。

2.2.4. 发布html到nginx

2.2.4.1. 将完整url,放入到系统菜单上(配置菜单),使其可访问

这里要做的,是echarts html页面路径跟我们将要嵌入的系统域名保持一致,echarts html页面路径可以放在一个特别标记的位置上,比如 https://hello.com/my_echarts/calender_summary.html, 用诸如/my_echarts来让nginx区分是访问原系统页面或我们编写的echarts html页面即可。

同时,dataway接口已经支持跨域访问,不用调整不提。

3. 后期工作

  • 是否支持类似时间区间筛选之类的表头?

    理论上是支持的,因为echarts的图表,默认是放在一个html元素如div中,只需要进行简单的html编写

  • 图表的空间布局摆放要求?

    同上,记上css定位等html技术,即可实现静态页的调整。


http://www.ppmy.cn/news/3314.html

相关文章

LeetCode刷题日记之链表II

1.四数相加II 题目描述 解题思路 1.定义一个哈希Map,其中key存放两数之和&#xff0c;value存放两数和出现的次数。 2.遍历统计出nums1和nums元数相加和出现的次数(ab)。 3.遍历nums3和nums4&#xff0c;并求和(cd),统计出(0-(cd))在Map中出现的次数。 4.返回&#xff08;0-(…

Opencv项目实战:17 贪吃蛇游戏

目录 0、项目介绍 1、效果展示 2、项目搭建 3、项目代码展示与讲解 4、项目资源 5、项目总结 0、项目介绍 这次是一个有意思的计算机视觉游戏——贪吃蛇&#xff0c;我们以食指为蛇头&#xff0c;不断的移动我们的手指&#xff0c;当吃到甜甜圈的时候&#xff0c;蛇身增…

Mongodb数据库的安装部署及基本使用

Mongodb数据库的安装部署及基本使用一、Mongodb数据库介绍1.Mongodb简介2.Mongodb适用场景3.MongoDB特性二、检查本地系统环境1.检查系统版本2.检查yum仓库三、Mongodb的安装1.配置Mongodb的yum源2.安装Mongodb3.修改绑定IP4.启动Mongodb服务四、检查Mongodb状态1.查看Mongodb服…

Python中ArcPy基于矢量范围批量裁剪大量栅格遥感影像

本文介绍基于Python中ArcPy模块&#xff0c;基于矢量数据范围&#xff0c;对大量栅格遥感影像加以批量裁剪掩膜的方法。 本文所需要的代码如下所示。 # -*- coding: utf-8 -*- """ Created on Tue Dec 13 20:07:48 2022author: fkxxgis """impo…

IT Resilience vs. Disaster Recovery 谈谈对弹性与灾备的理解

背景 在大型企业中&#xff0c;可能会花很多时间考虑灾难恢复以及如何避免灾难恢复。毕竟&#xff0c;这是一场噩梦——一场自然灾难或人为破坏的灾难&#xff0c;会摧毁你的IT基础设施&#xff0c;让企业团队陷入困境。 灾难恢复&#xff08;DR&#xff09;和IT Resilience …

Spring Boot使用EasyExcel导入导出Excel

一、导入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version></dependency> 二、实现导出excel操作 1、对我们需要导出的实体类上加上注解&#xff0c;如下&#…

一个关于React数据不可变的无聊问题

对于一个React的开发者来说不知道你有没有想过为什么React追求数据不可变这个范式&#xff1b; 一个月前我想过一个问题如果我在使用useState这个hooks的时候传入的是一个改变后的引用类型对象会发生什么&#xff1f; 例如&#xff1a; import {useState} from "react&…

Python3.1 使用卡通头像网络模型生成卡通头像(基于GAN)

使用GAN网络生成卡通头像 提示&#xff1a;当前生成方法仅为实验场景 参考地址 使用GAN网络模型生成卡通头像使用GAN网络生成卡通头像前言一、下载模型二、编写生成卡通头像Python代码1.引入库2.加载模型3.生成卡通头像方法总结前言 随着人工智能的不断发展&#xff0c;机器学…