datart系列04:基于threejs自定义插件3D-MAP

概述 datart自定义插件的方式,基于threejs自定义插件3D-MAP。 应用场景 根据经纬度进行的城市数据展示场景,适用数据大屏,3D地图等 验证数据 见插件文件:air_quality.sql、air_quality_sd.sql 前置条件 三个纬度、一个指标 三个纬度有顺序要求(1、需要显示的名称,2、经度,3、纬度) 备注:三个维度有顺序要求是为了保证不改动源码扩展插件,动源码有两种解决方式如下: 第一种:增加经度、纬度的维度类型,根据类型判断 第二种:扩展经度、纬度的维度拖入框,类似双Y轴方式 规则设定 地图:地图json文件url地址 基准值:适配不同数据级别展示,推荐设置样本数据最大值 缩放级别:地图缩放等级,适配不同区域展示情况 效果:水波、气泡、热力图 中心坐标:设置中心坐标的经度、纬度,控制地图显示区域 使用说明 插件地址:https://github.com/dumplingbao/datar-plug 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <div id="container"></div> <script> let f1 = new dumplingbaoThree.Map( document.getElementById('container'), { data: { // 城市数据 cityData: [ { city: "青岛", value: 100, EN: [120.3844, 36.1052],//经纬度 }, { city: "济南", value: 89, EN: [117.00, 36.40], } ] } }, { // config: { // mapJson: 'https://geo.datav.aliyun.com/areas_v3/bound/370000_full.json', // valueMax: 100, // level: 3, // longitude: 118.77, // latitude: 36.40 // }, config: { // 地图json地址 mapJson: 'https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json', // 基准值,推进样本数据最大值 valueMax: 100, // 缩放级别 level: 16, // 中心坐标经度 longitude: 105.11, // 中心坐标纬度 latitude: 35.98 }, } ); </script> 备注: 根据datart插件使用说明进行操作 根据需要优化后提交官方自定义插件库,部分规则依据当前使用的版本,命名规则等未按官方提供插件库的方式 地图json文件推荐,阿里云datav:http://datav.aliyun.com/portal/school/atlas/area_selector 私有化部署,只需把文件放到私有化文件服务器或者可访问的地址即可 省份地图,推荐缩放级别在3或4即可,省份中心坐标自行百度 插件存在已知bug,后续修复,正常使用满足 效果展示

2023/1/11
articleCard.readMore

datart系列03:图表插件开发

概述 开篇写过,datart借助自定义插件的方式,实现自定义扩展插件,就有了无限的可能。 通过最近一段时间的使用,datart自定义插件的方式同时把原来的不可能或很麻烦的二次开发变成了可能。 本身一些复杂的定制化的需求就需要独立于BI之外去做,借助自定义插件既保留的原来的灵活性,又可以抽离形成标准化,本身BI系统就是希望通过标准化来进行数据的分析展示 示例:库存01 数据结构 展示效果 示例:库存02 示例:库存03 数据结构 展示效果

2022/4/15
articleCard.readMore

datart系列02:图表插件开发作品

概述 今天整理了两个为未能参赛的作品,个人感觉还是比较好的两个点,就索性整理发出来。 作品:手绘风格(D3) 这个上一篇中说到了,也是时间的问题,未能找到原因,本以为是iframe嵌套导致的,后来官方给了去掉iframe的配置的方法进行了尝试,发现不是这个原因。 其实到现在也没有完全定位不能正常的渲染的原因,今天就换了种实现方式,放弃直接用开源的轮子,直接写源代码到插件里面,发现能够正常展示了,后续在把其它图表的补充完整。效果如下: 作品:3D地图(CesiumJs) 关于Threejs、WebGL、CesiumJs这里不做赘述,虽然CesiumJs受众相对较小,而且偏重GIS,但是利用cesiumjs做数字孪生应该也有很多了,所以就集成到datar插件试一下,而且CesiumJs号称永久开源免费,但是这个完全不在参赛作品计划内,原因很简单,用到了付费插件,虽然费用很低,做项目没有任何问题,但是参赛开源就不好了。但是CesiumJs作为datart插件集成还是很简单的,单纯的3D地球,肯定满足不了实际场景,但是花点实际研究研究API搞点特效出来,还是不难的,而且CesiumJs好用,效果出众,下面就看一下效果:

2022/4/5
articleCard.readMore

datart系列01:图表插件开发作品大赛

概述 2022年的第一篇,最近疫情+航空事故,虽是春暖花开,还是宅在家开码。借着datart图表插件开发作品大赛,给开了个头,datart的头,写作的头,但愿后续多写,今年估计的写的方向也会比较分散。 这一篇就当是参加图表插件开发作品大赛的一次开篇总结,也算是预热,这次采用datart自定义插件的形式,全部用自定义插件的方式,不改动源代码,不管怎么说,datart自定义插件发现越用越丝滑,很看好这一特性。后续再写datart源码及二次开发。 作品: 作品1:海洋鱼馆(动画) 这个作品算是魔改,但确实有着特殊的应用场景 这个在Davinci的时候做过扩展,这次全新的素材 造了鱼馆的轮子来适配datart的插件,后期我们再展开思路讲实现,并开源出来(包括素材) 作品2:地图(echarts) 这个也在Davinci扩展了,这次也是做了集成,场景没什么好说的,直接看效果,这个本来也想套一层封装,发现有点问题,直接用原生js做的集成 作品3:智能仓库(threejs) 智能数字化车间,3D车间模型等等,这种3D场景化很多人都追求,甚至是偏执。查了资料,看了Threejs官网所有的demo,逛了社区,确实没找到高大上且合适的场景化模型。就从网上找了个智能仓库的场景做了集成,个人理解这种3D场景就是先做场景化的模型(这种模型确实需要专业人来做,上手有门槛),在场景位置上展示数据或者图表。这个也是造了适配datart的轮子,算是个demo,半成品吧,后期展开讲,也开源出来,有专业水平的可以做模型然后集成到datart。 作品4:手绘风格(D3) 这个效果没做成功,在Davinci的时候因为受限于echarts就没有做,这次可以扩展D3,本以为这个应该是最简单,确没有成功,初步判断应该是iframe嵌套导致滤镜不成功,没找到合适的方案。不过除了滤镜D3其它的效果集成还是没有任何问题的,后续再研究。 总结: 总结一下datart自定义插件,对于前端来说可能算不上新技术,但是对于BI来说就是很好一次微创新: 特殊化定制,满足个性化需求 上手容易,官方这块文档很详细 扩展灵活,很丝滑 像D3这种灵活性很高的,本是就具备无限可能,所以datart也具备无限可能

2022/3/27
articleCard.readMore

我的2021年新Mac设置

看到SHAWN @SWYX WANG的My 2021 New Mac Setup的文章,相同的是都是用Mac作为程序开发,因此借着我的新Mac,我也进行了整理,写下这一份整理笔记。 系统设置 这个根据个人不同的喜好 修复触控板方向:触控板 -> 滚动和缩放 - 自然关闭 禁用 Spotlight 搜索除应用程序和系统首选项之外的所有杂项 禁用询问 Siri 禁用字典查找:触控板 -> 指向和点击 -> 查找和数据检测器关闭 首选项 → 显示文件扩展名 从 程序坞(Dock) 中删除所有内容,除了:Finder、系统偏好设置和垃圾箱 启用三指拖移:辅助功能 -> 指针控制 -> 启用拖移。(备注:启用后原三指操作变为四指) 浏览器设置 Chrome自然必不可少,下载安装即可,设置为默认 扩展程序: Morpheon 黑暗主题 React Devtools Vue.js devtools GitHub-Chart go get for Github Markdown Nice Octotree - GitHub code tree Sourcegraph 终端设置 命令行真的是程序员必备的了,这个终端就很重要了,Mac的终端默认是bash,这个可真是太bash了,连ll命令都不行,当然可以配置。还是不推荐bash(就像window下的cmd,宁愿选择git下的bash),这个确实没法让我们起飞。 备注:bash就是shell一种增强版本,就是经常在sh文件里看到的#! /bin/bash shell有很多种,常用的基本上就是bash、zsh、fish了,他们的区别无外乎就是命令、格式(包括高亮、特殊格式显示)、提示信息等方面上的区分。 可以先看一下Mac提供了哪些shell(可以直接到bin目录下看),可以通过偏好设置就像修改,也可以直接通过下面的命令设置,设置完成需要重新进入终端 1 2 3 4 5 6 7 8 9 10 # 查看所有的shell cat /etc/shells # 查看系统用户默认shell cat /etc/passwd | grep sh ## 系统默认的终端为bash,切换该终端为zsh chsh -s /bin/zsh # 切回默认终端bash chsh -s /bin/bash # 切换终端fish chsh -s /bin/fish 没有需要安装,这里我安装的zsh而且是Oh My Zsh,安装简单,直接看官网。 Oh My Zsh可以设置主题和插件,提示信息非常nice,详细配置不再赘述,我摘了一段和zsh的区别: 1 # Zsh 是一个shell,就像bash或fish 一样,它解释命令并运行它们。Oh My Zsh 是一个构建在 zsh 之上的框架,其结构允许它拥有插件和主题,并从一开始就提供我们认为最好的设置。您可以在没有 Oh My Zsh 的情况下使用 zsh,但如果您没有 zsh,则无法使用 Oh My Zsh。 如果需要fish的,推荐阮一峰的文章:Fish shell 入门教程 超级终端(Hyper Terminal) Hyper Terminal,一个通用的串行交互软件,可以通过串口、调制解调器或以太网连接,使用该程序连接到其他计算机、Telnet 站点、公告板系统 (BBS)、联机服务和主机、嵌入式系统等。 超级终端还能对外观进行主题设置并可以安装插件,配置直接通过修改.hyper.js即可。 环境及应用程序安装 关闭SIP 关闭SIP(SIP 全称为「System Integrity Protection」即「系统完整性保护」)还是有必要的,关闭之后才能修改某些文件的权限,一般建议修改完再打开,长期关闭回更方便,即使有些软件sudo进行安装也可以,还是关闭了吧。 以前的快捷键Command+R进入到恢复模式,M1芯片直接按住电源按钮即可进入。 顶部菜单拉中打开终端,输入: 1 csrutil disable 然后重启,设置权限就可以了 1 2 3 sudo chmod -R 777 目标文件夹 或者 sudo chmod a+w 目标文件夹 Homebrew 安装: 1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 如果443,修改host文件 1 2 3 sudo vi /etc/hosts # 加入 199.232.4.133 raw.githubusercontent.com 或者使用国内源 使用国内源: 1 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 配置的中科大的资源 jdk 官网下载安装(1.8),默认不需要配置环境变量 maven 官网下载最新版,解压配置环境变量即可 1 2 3 4  // vi ~/.bash_profile export MAVEN_HOME=/Users/bao/software/apache-maven-3.8.4 export PATH=$PATH:$MAVEN_HOME/bin git 1 2 3 4 brew install git git --version git config --global user.name "用户名" git config --global user.email "邮箱" nodejs 直接安装 1 2  ~/ brew install node  ~/ node -v 但是实际工作会涉及到多node版本的问题,建议还是用n或者mvn来管理,这里我们用n,个人感觉好用轻巧 1 2 3 4 5 6 7 8 9  ~/ brew install n  ~/ n stable // 安装最新稳定版  ~/ n 14.17.0 // 历史版本地址:https://nodejs.org/zh-cn/download/releases/  ~/ n ls // 列出所有版本 node/14.17.0 node/16.13.0  ~/ n // 切换版本  ~/ n rm <version> // 删除某个版本 如果已经安装了,node卸载方法 验证 1 2  ~/ which node /User/<your's-user-name>/.nvm/versions/node/<latest-node-lts-version>/bin/node 卸载 1  ~/ rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*} IntelliJ IDEA (v2021.2.3) 官网下载,需破解 VSCode 官网下载即可,简单 其它 Redis Desktop Manager(需破解) Navicat Premium 15(需破解) UltraEdit(需破解) FinalShell 其它应用 CleanMyMac X (电脑清理、破解版) WPS Office 超级右键 iShot(截图工具) Typora(Markdown编辑工具) AppDelete(软件卸载、破解版) Photoshop Parallels Desktop(Linux、win11、破解版) MindNode(思维导图) 最后一游 Wonderbox

2021/11/27
articleCard.readMore

小程序:Painter画布

Painter这个小程序画布组件应该很多人在用,github上超3K的star就已经说明这个组件的强大了。这里我们用这个组件实现短讯(如24小时动态)的分享和海报生成。 效果 图二生成的图片,也是分享出去的效果,可以点击分享跳转到短讯的详情即可,分享到群如下: 介绍 Painter组件地址:https://github.com/Kujiale-Mobile/Painter 可以通过源代码看一下组件的实现方式,其实Painter的readMe里面已经把组件的实现方式描述的很详细了,组件接收json格式,然后通过pen.js(画笔)画出json格式不同类型(文本、图片、矩形、qrcode )的view绘制,这种方式设计巧妙,对于很多复杂的情况需求都能满足。而且代码完善,优化调整也很方便。 Painter提供的工具能够将json数据直接转换效果,方便调试,链接地址: 链接1:https://painterjs.github.io/ 链接2:https://lingxiaoyi.github.io/painter-custom-poster/ 我们上面短讯的效果,只需利用Painter封装两个组件,一个用于分享,一个用于生成海报,控制两个组件显示隐藏即可。通过按钮传递标题、时间、标签、内容等信息,并通过组件接收,然后拼装json文件传递给Painter组件。 1 2 3 4 5 <!-- 分享绘图组件 --> <share-box wx:if="{{isCanDraw}}" isCanDraw="{{isCanDraw}}" time="{{timeShare}}" source="{{sourceShare}}" id="{{idShare}}" title="{{titleShare}}" content="{{contentShare}}" bind:close="handleClose" bind:initData="initData" bind:createPoster="createPoster"/> <!-- 海报组件 --> <poster-box isPoster="{{isPoster}}" time="{{timeShare}}" source="{{sourceShare}}" id="{{idShare}}" title="{{titleShare}}" content="{{contentShare}}" bind:closePoster="handleClosePoster"/> 此外,我们利用lin-ui实现了日期的吸顶效果(备:lin-ui对于吸顶效果的封装很易用,可以尝试一下)、内容展示的卡片效果,不再赘述,详细实现可直接查看下面的代码地址。 代码 已提交github,扫码关注公众号(diss带码),回复:webview,获得源码github地址

2021/8/3
articleCard.readMore

小程序:mqtt+webview控制显示内容

看到mqtt+webview似乎不知道能做什么,mqtt微消息服务更适用iot物联网,这个应该熟悉,但是似乎还是得从webview说起。webview的场景不仅仅是手机端的APP或者小程序用到,好多基于android主板显示的设备、大屏等webview都发挥了很大的作用。这里我们一是验证小程序的mqtt,二是通过mqtt控制设备自动切换显示内容,这样试想一下,其实就是远程操控设备显示内容的一种很好的方式。 效果 mqtt小程序端 需要mqtt.js客户端库:https://github.com/mqttjs/MQTT.js 小程序配置: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 const app = getApp() var mqtt = require('../../../utils/mqtt.min') var client = null Page({ /** * 页面的初始数据 */ data: { webUrl: 'https://www.baidu.com' }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.connnectMqtt() }, connnectMqtt: function (){ var that = this const options = { connectTimeout: 4000, // 超时时间 clientId: 'mqtt_' + Math.random().toString(16).substr(2, 8), port: 8083, //重点注意这个坑 } client = mqtt.connect("wx://xx.xx.xx.xx/mqtt", options); client.on('reconnect', (error) => { console.log('正在重连:', error) }) client.on('error', (error) => { console.log('连接失败:', error) }) client.on('connect', (e) => { console.log('成功连接服务器')        //订阅一个主题 client.subscribe('test', { qos: 0 }, function(err) { if (!err) { console.log("订阅成功") } }) }) client.on('message', function (topic, message) { console.log('received msg:' + message.toString()); that.setData({ webUrl: message.toString() }) console.log(that.data.webUrl) }) } }) 1 <web-view src="{{webUrl}}" bindmessage="getmessage"></web-view> mqtt服务端安装 EMQ X 是一款完全开源,高度可伸缩,高可用的分布式 MQTT 消息服务器 git地址:https://gitee.com/emqx/emqx docker安装步骤 1 $ docker search emqx // 查看版本 1 $ docker pull emqx/emqx // 拉取镜像 1 $ docker run -dit --name emqx -p 18083:18083 -p 1883:1883 -p 8083:8083 -p 8084:8084 emqx/emqx:latest // 运行 1 $ docker exec -it emqx /bin/sh // 进入命名 web管理界面 http://127.0.0.1:18083 #账号: admin #密码: public 端口介绍 1883:MQTT 协议端口 8883:MQTT/SSL 端口 8083:MQTT/WebSocket 端口 8080:HTTP API 端口 18083:Dashboard 管理控制台端口 mqtt客户端工具 我们没必要写后台代码,直接用个mqtt客户端工具做测试,用的MQTTX,这个就根据个人习惯选了 MQTTX地址:https://github.com/emqx/MQTTX/releases 安装完成配置验证即可。 代码 已提交github,扫码关注公众号(diss带码),回复:webview,获得源码github地址

2021/7/22
articleCard.readMore

小程序:webview + PDF预览

一般文件预览除了图片基本主要指office的文件预览,不同文件(word、Excel、pdf)格式差异大,所以很难有共性。相对来说PDF的预览会相对简单一些,而且大都能转换成pdf,我们就已pdf为例。小程序官方未提供,目前能找到和想到的方式,如下: 第一:采用wx.openDocument 1 2 3 4 5 6 7 8 9 10 11 12 wx.downloadFile({ url: 'www.file.com/file.ppt',//可以是后台传过来的路径 success: function(res) { const filePath = res.tempFilePath wx.openDocument({ filePath: filePath, success: function(res) { //成功 } }) } }) 效果: 说明:这种实际上是先下载了临时路径,好处是pdf、word、Excel都能预览,坏处是这种方式不一定能接受。 第二:webview+第三方pdf库 pdfjs是个很好的pdf预览的js库,可以不用改造直接使用,简单部署个服务,或者通过nginx配置一下即可,这里我们直接通过cdn阿里oss文件服务器来运行 pdfjs获取地址:https://github.com/mozilla/pdf.js oss服务demo: 1 https://byfile.disscode.cn/pdfjs-2.8/web/viewer.html?file=https://byfile.disscode.cn/blog/2021/wx/pdf/01.pdf 小程序配置就很简单了,就是通过webview的方式调用pdfjs服务,只需传递pdf文件地址即可 1 <web-view src="https://byfile.disscode.cn/pdfjs-2.8/web/viewer.html?file={{url}}"></web-view> 备注:PDF.js访问远程服务器(非同域名下)报file origin does not match viewer’s 需要将pdfjs下面的viewer.js中注释掉代码 1 2 3 // if (origin !== viewerOrigin && protocol !== 'blob:') { // throw new Error('file origin does not match viewer\'s'); // } 第三:延伸markdown文件渲染 markdown格式的内容渲染已有组件可以支持,尝试markdown的文件直接进行渲染,这里直接找到第三方库marked.js进行尝试 github地址:https://github.com/markedjs/marked 同样制作oss服务的demo 1 https://byfile.disscode.cn/marked/marked.html?file=https://byfile.disscode.cn/blog/2021/wx/mk/%E3%80%90BLOG%E3%80%91hexo%E6%90%AD%E5%BB%BAblog%E6%95%99%E7%A8%8B.md 小程序同样是webview的方式: 1 <web-view src="https://byfile.disscode.cn/marked/marked.html?file={{url}}"></web-view> 但是,markdown采用这种方式直接渲染文件,发现图片、换行等样式渲染还是有问题的,所以期待更多尝试。 备注:测试去掉域名的校验,要么就添加到小程序业务域名里面,否则不能正常访问 第四:代码 已提交github,扫码关注公众号(diss带码),回复:webview,获得源码github地址

2021/7/20
articleCard.readMore

小程序:数十年Lite

概述 端午参加毕业十周年聚会,聚会之前花了几天时间撸了个小程序,聚会结束了,十年也真的过去了。 效果 组件介绍 ColorUI 很棒的小程序UI,而且很大一个特点是特别的简洁,组件也很完善 github地址:https://github.com/weilanwl/ColorUI/ 效果地址:http://demo.color-ui.com/ Painter 这个用来生成图片、海报确实好用 github地址:https://github.com/Kujiale-Mobile/Painter 菊码 代码 已提交github,扫码关注公众号(diss带码),回复:数十年,获得源码github地址 备注:后端采用springboot + MongoDB,源码已去除后端,可以直接运行,数据目前读取的json文件 温馨提示:发布动态(上传图片)功能涉及个人小程序审核就去掉了,但是可以当成后台工具,要么就单独做个后台管理的web端

2021/7/17
articleCard.readMore

验证码:五福临门

一看 验证码这个既熟悉又常用的功能,一提起来你就会想起各种各样的验证码,一个偶然的机会,就冒出来做个验证码,慢慢的就演变成现在的五福临门验证码。先看一下效果图: 由来 春节前看到一篇关于验证码的文章,动态刷新、滑动验证,这里的动,总感觉没有“动” 加上之前做的游鱼,就想让它动起来,所以最初就是在滑块验证码的基础上,让滑块在外面游动起来 后来支付宝集五福,让我突然感觉可以考虑,五个福字随机掉下来一个在外面游动,然后滑动原位置,正好符合春节的气息 再后来参与了支付宝打印福字的活动,然后就手写了五福,这样不仅是随机五福,还可以随机不同主题的五福了 春节前开始的,前期做了技术验证,春节陆陆续续进行了实现 后来找资料做轨迹校验,断断续续,今天暂时把前端部分发出来,后端验证决定后续再补一篇 下面是个设计效果图: 认知 验证码虽然已经司空见惯了,但是还是想讲一下验证的一些接触,从中也能体会乐趣。 起初进入技术行业,还是一个验证码不流行的阶段,计算机识别技术更是起步,所以扭曲、污染的文字无法辨识,所以最初见到的就是4个字母数字,一条飞线。 慢慢的越来越流行,越来越多样,越来越看不懂 越来越烧脑,亦或是恶搞 新时代的验证码越来越多样,出现了两极分化,一种让你赏心悦目,一种让你抢不到票 验证码在技术里面或许是小场面,但却蕴藏着大智慧,而且是紧跟时代的产物,根据人们需求的变化而变化,当然破解和识别技术的提升也在嘶声呐喊和“催更” 技术 验证码可以防止:恶意破解密码、刷票、论坛灌水等 软件包:成熟的插件和软件包,直接引入使用就可以了 第三方:网易易盾等,购买按官方文档使用 网易易盾:https://dun.163.com/ 无痕验证:阿里云-人机验证 https://help.aliyun.com/product/28308.html 用过阿里云的都知道,阿里云登录输入账号密码就可以了,点击登录也没有多余的操作,以为就没有验证,其实阿里做的是无痕验证,即使没有可视化的验证码出现,其实已经对你登录做了人机的校验了,所以不要以为没有可见的验证码就误以为没有验证。 实现 技术栈:前端nodejs+vue,后端java+redis 滑块验证:vue-drag-drop 游动:animateplus 目前的前端部分演示demo(目前只支持pc端):http://bless.disscode.cn/#/loginSlider 五福临门 一曰寿,二曰富,三曰康宁,四曰攸好德,五曰考终命 五福含意:第一福是“长寿”、第二福是“富贵”、第三福是“康宁”、第四福是“好德”、第五福是“善终”。有人简称为寿富康德善。

2021/3/5
articleCard.readMore

开源论坛:社区选择Discourse

回想以往逛论坛、贴吧的年代,似乎渐行渐远,现在人类追求的多样性超出想象,但论坛并未走下神坛,只是换了一种或者是以多种方式存在。社区、小组、圈子等都有更多的载体和工具,今天就说一下开源论坛discourse。 Discourse应该也已经20多年了,并不新鲜,也是因为平常经常浏览的技术社区用的就是discourse,所以就搭建一下,深入感受一下discourse,以备后用。 Discourse总体下来,觉得挺适合做社区,尤其是技术性比较聚集的论坛 开源论坛 创始人想要让改变十年未变的互联网论坛模样 基于Ruby on Rails 和 Ember.js 开发,数据库使用 PostgreSQL 和 Redis 最大的特点是简洁和专业性,以话题为关系聚集用户 Discourse官网: 官方网站:https://www.discourse.org/ 官方社区:https://meta.discourse.org/ Github项目:https://github.com/discourse/discourse 搭建步骤 安装git和Docker 1 2 apt-get install git wget -qO- https://get.docker.io/ | sh 安装Discourse 1 2 3 4 mkdir /var/discourse git clone https://github.com/discourse/discourse_docker.git /var/discourse cd /var/discourse cp samples/standalone.yml containers/app.yml(or ./discourse-setup 初始化) 修改配置文件 1 2 3 4 5 6 7 8 9 vim containers/app.yml UNICORN_WORKERS(如果是1Gb内存就是2,2GB内存以上就是3-4) DISCOURSE_DEVELOPER_EMAILS管理员邮箱 DISCOURSE_HOSTNAME 绑定的域名 DISCOURSE_SMTP_ADDRESS是邮局服务器 DISCOURSE_SMTP_PORT是SMTP的端口 DISCOURSE_SMTP_USER_NAME账号 DISCOURSE_SMTP_PASSWORD密码 特别注意的是:端口号465是没有效果的 1 DISCOURSE_SMTP_PORT: 587 以上配置完了,会收不到邮件有两种方式修改 第一种:用官方的工具launcher创建管理员账号 1 2 3 cd /var/discourse ./launcher enter app rake admin:create 创建管理员账号,按要求输入管理员邮箱和登录密码 登录网站,用刚才创建的账号直接登录。 在settings页面设置notification email为发件邮箱,就是之前配置文件里面写的那个邮箱。 在邮件测试页面发一封测试邮件,应该测试成功了。 第二种:编辑发件邮箱 1 2 3 4 5 vim containers/app.yml //定位文件底部,打开注释 - exec: rails r "SiteSetting.notification_email='xxx@qq.com'" //重新build一下 ./launcher rebuild app 修改完成后,重新构建 1 ./launcher rebuild app nginx与discourse discourse配置修改: 1 2 cd /var/discourse vim containers/app.yml 修改:(设置端口代理) 1 2 expose: - "9090:80" # http 最后运行 1 ./launcher rebuild app nginx增加配置: 增加discourse.conf即可 添加Github第三方登录 打开Github application,进入Developer applications,新建应用程序 Homepage url为你的discourse地址,authorization callback url为你的discourse地址加上/auth/github/callback,然后复制Client ID和Client Secret, 最后打开discourse,进入管理-设置-登录,找到下图所示三个字段,勾选填入刚才复制的内容 然后确定、完成。 点击=>完成! 常见问题 计算技术论坛关于discourse的问题:https://www.ossez.com/search?q=discourse 其它 体验了一下Discourse的管理界面和可配置的操作,后台支持定制化的配置和插件化,而且确实很简洁,并能够提供对外API,有时间可以继续探究 我的discourse地址:https://lt.disscode.cn/

2021/3/2
articleCard.readMore

牛年开篇:网站拜年

牛年开篇:网站拜年 开启新年第一篇,本应该在春节假期完成,趁着马上元宵节,就以此开篇。 重新调整了一下个人网站,来个新年新气象,也希望牛年牛转乾坤,更上一层楼。 力求简单,做几点要求: 个人网站,我们还是区分一下企业和产品网站 前端展示,先不牵扯后端,当然也是为了快速部署 新年元素、牛元素 兼容手机端 达成几个目的: 迎接新的一年 宣传,似乎这个是必不可少,即使没有什么可宣传的内容 github网络的限制,导致博客受限,同时选择了简书,后期考虑通过网站,进而做调整 服务器的充分利用 网站地址:https://disscode.cn 建站方式 服务器:云服务器,扩展性、灵活性高(推荐) 虚拟主机:这个的经济优势很明显 第三方:快捷建站网站 域名 无论何种方式,有个自己的域名这个是最好的、也算是必须的,申请渠道很多,申请一个即可(备注:需要备案) ssl证书 ssl证书其实是挺贵的,但是可以用免费的,ssl证书其实对于网站来说也是必不可少的,没有证书的网站就感觉别扭 推荐免费证书: Let’s Encrypt ohttps 阿里云、腾讯云等 网站代码 技术栈:nodejs + react 找了一些网站,最好选了个开源的网站代码,推荐一下,记得点赞 github地址:https://github.com/ArthurYung/react-my-website 发布 如果是服务器,采用Nginx来部署就很简单了

2021/2/24
articleCard.readMore

github自定义主页秀

github自定义主页秀 ​ github支持自定义主页已经有一段时间了,今天尝试了一下。详细教程可以从网上搜索一下,比较简单,也可以直接到我的github(下面有链接)复制一下,记得点赞奥。 😎 秀一秀 🔨 创建 ​ 很简单,创建与github账号同名公开的仓库,并初始化README.md,完成 🔧 美景 ​ 每日刷新或者随机(自己去选对应的类型的api) ​ https://api.lyiqk.cn/ ​ 备注:github由于缓存了图片,不会每次都刷新 ​ 建议用必应每日一图:https://api.lyiqk.cn/bing 🔑 我的自定义主页 ​ 连接地址:https://github.com/dumplingbao/dumplingbao ​ 备注:由于是markdown格式,预览效果与实际展示有所不同

2020/9/3
articleCard.readMore

Davinci-二次开发系列08:mongoDB(JDBC查询)四种解决方案

​ 关于Davinci使用mongoDB的问题,就一直没有断过。我们不管怎么评价mongoDB,似乎年轻的mongoDB俨然是主流数据库了。而且现在对于BI来说能不能支持主流的NoSQL数据库,已经成为一个很重要的衡量标准。目前BI通过JDBC的方式访问NoSQL数据库还是首选,但是mongo官方未提供JDBC驱动包,这里介绍四种mongo-JDBC查询数据的解决方案:(备注:mongo-JDBC问题不仅限于Davinci,也不限于BI,一些实际应用中也会碰到) 序号方案备注综述 1利用presto连接facebook开源SQL查询引擎优点:开源、免费、兼容性良好 缺点:需要单独部署服务 21、unityjdbc破解版 2、unityjdbc试用版商业化产品优点:集成简单、不需要单独部署 缺点:收费、_id字段值不显示 试用版本地mongo支持需要解决 破解版只能简单的查询、子查询等有问题,存在问题比较多 3mongo-bi连接器mongo官方优点:官方出品、免费、兼容性极好 缺点:需要单独部署服务 推荐用此方式 4开源手写驱动包开源优点:灵活性可控 缺点:成本高、耗精力 利用presto连接 ​ Presto是一个facebook开源的分布式SQL查询引擎,而且支持跨库查询,当然也支持mongoDB,Davinci通过presto做类似的桥接,然后也能实现mongoDB的jdbc查询,如果公司使用presto,采用这种方案也是不错的选择,兼容性可以。 ​ 这里我们重点介绍后面两种,没有实际进行尝试,大家可以尝试一下,简单介绍一下步骤: ​ 第一:首先需要安装presto-server服务,看好版本,支持MongoDB的才可以 ​ 第二:配置mongodb.properties 1 2 3 connector.name=mongodb mongodb.seeds=ip:port mongodb.schema-collection=admin ​ 第三:Davinci配置数据源 ​ jdbc:presto://ip:port/mongodb/test ​ 第四:view实现JDBC查询 ​ select * from mongodb.数据库名.集合 unityjdbc ​ 由于unityjdbc是收费的,这里我们用网上的破解版和试用版都试一下。 官方试用版 ​ 第一:试用版,去官网unityjdbc下载JDBC Driver for MongoDB,这里我们用的是``这个版本下载地址:http://www.unityjdbc.com/download.php?type=mongodb ​ 第二:下载下来的UnityJDBC_Trial_Install.jar 需要java -jar安装,安装完获取unityJdbc.jar(或者mongodb_unityjdbc_full.jar这个jar包也可以) ​ 第三:mongodb-driver的依赖默认是注释掉的,将注释去掉,并将unityJdbc.jar引入到工程里面或者复制进去,在porm里面引入本地依赖 1 2 3 4 5 6 7 8 9 10 11 12 <!--mongodb --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.6.3</version> </dependency> <dependency> <groupId>unityjdbc</groupId> <artifactId>unityjdbc</artifactId> <scope>system</scope> <systemPath>${project.basedir}/lib/unityjdbc.jar</systemPath> </dependency> ​ 第四:Davinci配置数据源(强调一下,我用官方的包,连接本地mongo报hostname的错误,就先用官方的测试库) jdbc:mongo://localhost:27017/数据库 官方测试地址 jdbc:mongo://ds029847.mongolab.com:29847/tpch 创建view(_id不能正常显示) 创建widget 子查询 关联查询 网传破解版 试了一下分享出来的破解版,除去上面的安装步骤,直接引入即可 创建数据源,这个包比试用版好的是本地mongo能直接使用 jdbc:mongo://localhost:27017/数据库 创建view(_id不显示、集合列表不显示) 创建widget 从错误上来就不能很好的兼容,子查询关联查询更是不能正常使用 mongo-bi连接器 ​ mongo官方没有提供mongo的JDBC驱动,但是提供了mongo-bi-connector,允许使用所选的BI工具通过标准SQL查询对MongoDB数据进行可视化。 ​ 搜了一下资料,BI Connector 可以使用 SQL 或 ODBC 数据源方式直接访问 MongoDB,MongoDB 早期版本直接使用 Postgresql FDW 来实现 SQL 到 MQL 的转换,后来实现更加轻量级的 mongosqld 来支持 BI 工具的连接。这里我们就尝试一下mongosqld,来验证一下。 下载并安装mongo-bi-connector ​ 官方下载:https://www.mongodb.com/try/download/bi-connector,支持windows、linux版本 ​ 默认安装即可 配置文件 ​ 默认配置即可,如果有mongo做了限制,或者调整端口,修改mongosqld-config.yml,详细配置看官网 1 2 3 4 5 6 7 8 9 10 11 12 13 net: bindIp: "127.0.0.1" # To bind to multiple IP addresses port: 3307 mongodb: net: uri: "mongodb://127.0.0.1:27017" ssl: enabled: false auth: username: xxx password: xxx source: xxx mechanism: SCRAM-SHA-1 启动mongosqld ​ 我使用的windows版本双击mongosqld.exe运行即可 maven引入依赖包 1 2 3 4 5 6 7 8 9 10 11 12 <!-- 这个包必须有 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> <!-- 非必须,这个是JDBC认证插件,如果你做测试或者你的mongo本身在裸奔,就没必要了 --> <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>5.1.42</version> </dependency> 创建数据源 备注:这里使用mysql即可 创建view(_id和集合列表均正常) 创建widget 子查询 关联查询 开源手写驱动包 ​ 这个绝对是一个解决方案,其实工作中就会封装mongo的一些比如关联查询类似的组件,写这个驱动包也未必没有优势,我觉着如果上面的方案兼容sql的场景如果存在问题,那么自己写的驱动包改造就容易的多,第三方的包就没那么好改了。 ​ 这里推荐一个mongo的JDBC开源驱动包,如果有自己想写的想法仅供参考。 ​ 连接:https://gitee.com/f4haofeng/mongodb-jdbc/tree/master/src/main/java/com/mongodb 综上所述 ​ 其实,表格里面已经比较了,根据个人需求选择即可,还是推荐使用mongo官方的BI连接器的方式,虽然我们没有对性能进行比较,但从使用性、兼容性、子查询、关联查询等方面比较,BI连接器的方式完全能够胜任。 交流学习 学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/8/24
articleCard.readMore

Davinci-二次开发系列07:BI新元素尝试

​ 忙于工作,停更很长时间了,最近继续开搞,先写此一篇。生活犹如演绎,写作算是解说,先看效果: ​ 由来 ​ 想在BI里面引入一些别具一格的新元素,这个想法由来已久,本来是想做下面的这种效果: ​ 这个是chart.xkcd 手绘风格图表库,我之前写过一篇介绍,详细介绍可以查看手绘风格的图表库(char.xkcd),可是由于davinci采用的是echarts,通过尝试未找到合适的很好的解决方案,只能暂时搁置了。 ​ 所以先做了这个鱼馆的场景,缘起于之前做过的项目,类似于一个积分系统,从积分到最终呈现单独做的。试想一下,如果有这样的BI工具,支持这样的场景,也就能根据数据快速生成,所以这样想,需求、场景都是有的,就尝试在BI里面集成这种鱼馆的效果,也算给BI的一种新的元素。 技术选型 ​ 技术点在动画选型上,后端不需要操作,这里我们推荐几种技术实现 jQuery:之前就是用jQuery实现的,完全没有问题,就是代码量看上去比较繁琐 lufylengend:这是个h5的引擎,简单、功能强大,有兴趣可以了解一下,用于实现这个功能偏重,但是后续考虑增加一些特性会比较方便,功能没得说。 animate相关的npm包: ​ 1、animate-npm:这个包有点像被抢注了,功能实在简单,简单到看上去就不是你想要的 ​ 2、bendc/animate:这个是个封装的js文件,是6年前开发的了,完全够用,操作方便 ​ 3、bendc/animateplus:这个包和上一个是一个作者,一看就是升级版,也已经开发有3年了,支持npm直接安装 ​ 这里我们用的bendc/animateplus,也可以尝试其它的,我们用到的动画只是简单的,不需要复杂的功能,更不需要复杂的算法。这里特别强调一下,这个本身就是开源的封装,没有完整的api,知识盲点会导致需要不断的尝试才行。 功能点介绍 序号功能备注 1数据模型一个维度,一个指标,示例:用户和积分 2主题鱼馆背景可切换,海洋元素一些引入 3速度速度可设定 4积分等级目前固定,通过积分判断区间和对应的等级及动物 5信息展示默认展示维度信息,如用户及积分信息 背景切换 速度切换 显示指标 单击显示指标信息,再次单击隐藏指标信息,我们也不提倡排名看分就隐藏 示例数据结构 积分等级处理 ​ 这里效果图是随机取的动物,正常配置通过积分判断所处的等级和对应的动物,目前是静态的配置文件,后续也应该是可配置化。 交流学习 学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。 备注:技术选型尝试多次,每个都有各自的优缺点,就会有所取舍,亦或者不能完全深入了解,这次BI里面加入这种非常规的东西也算是一种尝试,欢迎进群交流,留言和点赞。gif图片太大,进行了压缩,影响效果,由于素材牵扯版权的问题,暂时也不能提交代码,希望能制作素材的朋友联系。

2020/8/20
articleCard.readMore

Davinci-二次开发系列06:导出excel合并单元格

前言 ​ 系统数据导出excel已经很具普遍性,不单单是BI有这需求,表单性质的数据大都希望直接导出excel,这个需求甚至比邮件接收更加突出。 ​ Davinci导出excel有两种方式,都在dashboard页面 单个widget导出 整个dashboard导出,多个sheet页,一个sheet页对应一个widget数据 表格数据 ​ Davinci透视驱动和图表驱动下都有表格的功能,表格中维度指标是自动合并的,效果如下: 图表驱动 透视驱动 表格导出excel ​ 这里先不考虑图形效果的数据导出,表格数据更希望导出excel是相同的样式,也就是自动合并单元格,现有的表格数据导出效果如下: 图表驱动 透视驱动 图表驱动表格excel自动合并单元格 合并后效果图 图表驱动 透视驱动 了解现有逻辑 1 2 3 4 5 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> 通过代码和依赖可以看出采用的poi处理导出excel 改造计划 ​ 如果通过现有的方式加入合并单元格的逻辑改造有点麻烦,这里我们直接找较完善的poi合并单元格的方法来直接引用并调用,如果有更好的方式可以一起讨论交流,欢迎留言。 ​ 参考poi合并单元格:https://www.cnblogs.com/mr-wuxiansheng/p/7930378.html 代码改造 ​ 参考上面链接这里直接提供改造后端的代码 一 新增PoiInfo实体类,严格意义上这应该是DO这样我们放的DTO下面 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package edp.davinci.dto.poiDto; import lombok.Data; import java.io.Serializable; /** * POI Excel报表导出,列合并实体<br> */ @Data public class PoiInfo implements Serializable{ private static final long serialVersionUID = 1L; private String content; private String oldContent; private int rowIndex; private int cellIndex; public PoiInfo() { } public PoiInfo(String content, String oldContent, int rowIndex, int cellIndex) { this.content = content; this.oldContent = oldContent; this.rowIndex = rowIndex; this.cellIndex = cellIndex; } @Override public String toString() { return "PoiInfo [content=" + content + ", oldContent=" + oldContent + ", rowIndex=" + rowIndex + ", cellIndex=" + cellIndex + "]"; } } 二 废弃writeLine方法,新增createSheet方法 1 \server\src\main\java\edp\davinci\service\excel\AbstractSheetWriter.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 /** * @param queryColumns 标题集合 queryColumns的长度应该与list中的model的属性个数一致 * @param maps 内容集合 * @param mergeIndex 合并单元格的列 */ public Boolean createSheet(Sheet sheet,List<QueryColumn> queryColumns, Map<String, List<Map<String, Object>>> maps, int[] mergeIndex){ if (queryColumns.size()==0){ return false; } int n = 0; for(Map.Entry<String, List<Map<String, Object>>> entry : maps.entrySet()){ /*初始化head,填值标题行(第一行)*/ Row row0 = sheet.createRow(0); for(int i = 0; i<queryColumns.size(); i++){ /*创建单元格,指定类型*/ Cell cell_1 = row0.createCell(i, Cell.CELL_TYPE_STRING); cell_1.setCellValue(queryColumns.get(i).getName()); } /*得到当前sheet下的数据集合*/ List<Map<String, Object>> list = entry.getValue(); /*遍历该数据集合*/ List<PoiInfo> poiInfos = new ArrayList(); if(true){ Iterator iterator = list.iterator(); int index = 1; while (iterator.hasNext()){ Row row = sheet.createRow(index); /*取得当前这行的map,该map中以key,value的形式存着这一行值*/ Map<String, String> map = (Map<String, String>)iterator.next(); /*循环列数,给当前行塞值*/ for(int i = 0; i<queryColumns.size(); i++){ String old = ""; /*old存的是上一行统一位置的单元的值,第一行是最上一行了,所以从第二行开始记*/ if(index > 1){ old = poiInfos.get(i)==null?"": poiInfos.get(i).getContent(); } /*循环需要合并的列*/ for(int j = 0; j < mergeIndex.length; j++){ if(index == 1){ /*记录第一行的开始行和开始列*/ PoiInfo poiInfo = new PoiInfo(); poiInfo.setOldContent(String.valueOf(map.get(queryColumns.get(i).getName()))); poiInfo.setContent(String.valueOf(map.get(queryColumns.get(i).getName()))); poiInfo.setRowIndex(1); poiInfo.setCellIndex(i); poiInfos.add(poiInfo); break; }else if(i > 0 && mergeIndex[j] == i){ /*这边i>0也是因为第一列已经是最前一列了,只能从第二列开始*/ /*当前同一列的内容与上一行同一列不同时,把那以上的合并, 或者在当前元素一样的情况下,前一列的元素并不一样,这种情况也合并*/ /*如果不需要考虑当前行与上一行内容相同,但是它们的前一列内容不一样则不合并的情况,把下面条件中                   ||poiModels.get(i).getContent().equals(map.get(title[i])) && !poiModels.get(i - 1).getOldContent().equals(map.get(title[i-1]))去掉就行*/ if(!poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName()))) || poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName()))) && !poiInfos.get(i - 1).getOldContent().equals(String.valueOf(map.get(queryColumns.get(i-1).getName())))){ /*当前行的当前列与上一行的当前列的内容不一致时,则把当前行以上的合并*/ CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index - 1, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex()); //在sheet里增加合并单元格 sheet.addMergedRegion(cra); /*重新记录该列的内容为当前内容,行标记改为当前行标记,列标记则为当前列*/ poiInfos.get(i).setContent(String.valueOf(map.get(queryColumns.get(i).getName()))); poiInfos.get(i).setRowIndex(index); poiInfos.get(i).setCellIndex(i); } } /*处理第一列的情况*/ if(mergeIndex[j] == i && i == 0 && !poiInfos.get(i).getContent().equals(String.valueOf(map.get(queryColumns.get(i).getName())))){ /*当前行的当前列与上一行的当前列的内容不一致时,则把当前行以上的合并*/ CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index - 1, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex()); //在sheet里增加合并单元格 sheet.addMergedRegion(cra); /*重新记录该列的内容为当前内容,行标记改为当前行标记*/ poiInfos.get(i).setContent(String.valueOf(map.get(queryColumns.get(i).getName()))); poiInfos.get(i).setRowIndex(index); poiInfos.get(i).setCellIndex(i); } /*最后一行没有后续的行与之比较,所有当到最后一行时则直接合并对应列的相同内容*/ if(mergeIndex[j] == i && index == list.size()){ CellRangeAddress cra=new CellRangeAddress(poiInfos.get(i).getRowIndex(), index, poiInfos.get(i).getCellIndex(), poiInfos.get(i).getCellIndex()); //在sheet里增加合并单元格 sheet.addMergedRegion(cra); } } Cell cell = row.createCell(i, Cell.CELL_TYPE_STRING); cell.setCellValue(String.valueOf(map.get(queryColumns.get(i).getName()))); /*在每一个单元格处理完成后,把这个单元格内容设置为old内容*/ poiInfos.get(i).setOldContent(old); } index++; } } n++; } return true; } 三 放弃原来template.query 使用lambda表达式的调用方式(注释部分),修改如下 1 \server\src\main\java\edp\davinci\service\excel\SheetWorker.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // template.query(sql, rs -> { // Map<String, Object> dataMap = Maps.newHashMap(); // for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { // dataMap.put(SqlUtils.getColumnLabel(queryFromsAndJoins, rs.getMetaData().getColumnLabel(i)), rs.getObject(rs.getMetaData().getColumnLabel(i))); // } // writeLine(context, dataMap); // count.incrementAndGet(); // }); List<Map<String, Object>> list = template.queryForList(sql); // 获取合并列 List<Integer> listIt = new ArrayList<Integer>(); for (int j = 0; j < context.getQueryColumns().size(); j++) { QueryColumn queryColumn = context.getQueryColumns().get(j); if(!queryColumn.getType().equals("value")){ listIt.add(j); } } int[] mergeIndex = new int[listIt.size()]; int i = 0; for(Integer it: listIt){ mergeIndex[i++] = it.intValue(); } Map<String, List<Map<String, Object>>> map = new HashMap(); map.put("合并单元格数据", list); createSheet(context.getSheet(),context.getQueryColumns(),map,mergeIndex); 完成以上配置,效果就有了 存在问题 透视驱动表头样式 ​ 目前无法做到透视驱动的表头样式,数据导出excel也仅仅和图表驱动类似的单元格数据的合并。 表头样式进行分组合并影响导出 ​ 表头样式进行分组合并设置,会影响导出,后续再进行处理。 图表驱动表格合并存在不合理情形 数据第一层维度数据不同,第二次数据相同合并,似乎不合理,excel做了处理,这样就不一致,如下情况: 交流学习 学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/5/14
articleCard.readMore

Metabase-BI系列12:0.35版本表达式是真的香

​ 2020年3月30日,Metabase0.35版本真的来了,正如官方所说,0.35真的是一个重要的版本,最重磅的升级就是自定义表达式的升级,直接使Metabase的查询编辑器有了质的飞跃,对数据分析中自定义列、数据过滤器、数据聚合功能有了很大的提升。 ​ 这个重要的升级通俗讲: 提升数据处理能力,不用写sql就能进行更多的数据转换 不同数据库,通用处理规则,提升用户体验 改为用[]方式获取字段,自动提示操作十分人性化 升级前后对比 序号功能升级前升级后(0.35之后) 1自定义列只支持数字类型的+,-,*,/1、支持字符字段 2、新增字符和数字处理18个函数abs,concat等 3、支持升级前功能 2过滤器1、单个字段判断筛选 2、数字类型是,不是,为空,不为空 3、字符类型除上面四个外,还有包含,不包含,以..开始,以..结束 4、其它类型不再赘述,升级前后未变化1、支持自定义表达式 2、新增函数支持between,contains,ednWith,startWith,interval 3、扩展运算符:AND,OR,NOT,>,>=,<,<=,=,!= 4、支持升级前功能 3聚合1、支持自定义表达式 2、原有聚合函数的+,-,*,/1、支持自定义表达式 2、新增了9中数字的处理函数 3、支持升级前功能 过滤器: 聚合: 新增表达式介绍 这次表达式确实扩展了很多,这里挑了几个常用的预览一下,也可以去Metabase官方查看全部表达式 名称句法备注例 Betweenbetween(column, start, end)1、日期范围内 2、数字区间内between( [Rating], 3.75, 5 ) Casecase(condition, output, condition, output …)多情况判断,如枚举类型case( [Weight] > 200, “Large”, [Weight] > 150, “Medium”, “Small” ) 返回非空值coalesce( value1, value2, …)按顺序查看每个参数中的值,并为每行返回第一个非空值。coalesce( [Comments], [Notes], “No comments” ) 字符串拼接concat(value1, value2, …)1、字符串或字段拼接 2、数值会转换字符拼接(已测试)concat([Last Name] , “, “, [First Name]) 长度length(text)返回文本中的字符数length([Comment]) 小写转换lower(text)以小写形式返回文本字符串。lower( [Status] ) 去除左空格ltrim(text)ltrim( [Comment] ) 正则表达式提取regexextract(text, regular_expression)根据正则表达式提取匹配的子字符串regexextract( [Address], “[0-9]+” ) 替换replace(text, position, length, new_text)replace( [Order ID], 8, 3, [Updated Part of ID] ) 去除右空格rtrim(text)rtrim( [Comment] ) 截取字符串substring(text, position, length)substring( [Title], 0, 10 ) 去除空格trim(string)trim( [Comment] ) 大写转换upper(text)upper( [Status] ) 也可直接查看更多表达式连接(谷歌自动翻译):https://ossbao.oss-cn-qingdao.aliyuncs.com/blog/Metabase/12/Metabase-bds.html 0.35其它说明 新增表达式并不能兼容所有的数据库,因为数据库差异很大,做到这种程度已经很牛x了,表达式数据库兼容情况参加官方说明 此外0.35版本调整了查询结果缓存内存的策略,改为数据库流,调整了一些api,着眼性能提升 当然少不了的就是修复bug了,参加官方说明 交流学习 刚建的群,学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/4/12
articleCard.readMore

Davinci-二次开发系列05:echarts-gl map3D扩展

echarts-gl ​ 介绍一下echarts-gl,charts-gl专门为echarts补充了丰富三维可视化组件。这里的gl应该是global的意思,很多地方简写GL,不建议这样写,因为和真实的GL太冲突,更何况最近肖某的事情,和BL有着千丝万缕的关系,所以,就别和GL扯上关系,我们还是写全称echarts-gl。 echarts-gl map3D ​ 这次介绍echarts-gl map3D,就是用echarts-gl实现的地图的3D模式,也是在系列03的基础上进行的改造,开启3D,切换地图,效果如下: echarts-gl安装 1 cnpm install echarts-gl --save 页面引入 1 import 'echarts/dist/echarts-gl' 特别注意一下:如果集成了百度地图,这个引入不要放入到app.tsx里面,会出现一直加载不完的情况,所以最好放到chart.tsx 控制参数 ​ 在样式里面,添加控制参数,开启3D render调整 ​ 在render下面的map.ts调整图形,主要是series的属性 1 2 map:'' // 注意与echarts.registerMap第一个参数保持一致 type: 'map3D' // 通过type指定必须是map3D,还有一种方式geo3D,见echarts官方实例 完成以上配置,效果就有了 echarts-gl事件存在问题 ​ echarts-gl图表事件一直存在问题,算是个坑,截止目前,我统计了一下官方issue关于事件目前一直open的最少四个,echarts-gl目前维护进度也较慢。 ​ 试了几个版本的echarts-gl,发现对于不同的版本: 有版本需要加getZr(),有的版本不需要 有的事件需要加getZr(),有的事件不需要 有的版本获取不到区域名称,只能获取到坐标,有的版本能 有的版本区域域名加了getZr()能获取到,有的不加能获取到,有的都能,有的都不能 ​ 我目前使用的版本1.1.1,单击事件不用加getZr(),右键事件需要加,但是右键事件获取不到区域名称,如果发现某个版本单击和右键事件都有,并能获取到取到区域名称,烦请留言告知,在此谢过。 ​ 就拿我们用的单击和右键事件来说: ​ 单击事件实现方式: 1 2 3 4 5 6 7 8 // 方式一 myChart.on('click', function (params) { console.log(params); }); // 方式二 myChart.getZr().on('click', function (params) { console.log(params); }); ​ 右键事件 1 2 3 4 5 6 7 8 // 方式一 myChart.on('contextmenu', function (params) { console.log(params); }); // 方式二 myChart.getZr().on('contextmenu', function (params) { console.log(params); }); 几个推荐和注意 echarts-gl地图下钻 ​ 如果echarts-gl 地图下钻,一些类似边框、颜色等属性,需要在下钻事件里面重新调整,否则下钻到新的地图属性不能匹配。 echarts-gl map3D组合图形 ​ 如果仅仅echarts-gl map3D效果没那么出众,一般都是配合其它图形,在地图上放柱形、雨滴等会更突出3D效果,所以可以进一步扩展。 echarts-gl性能 ​ 这里map3D较简单,性能未发现问题,echarts-gl有很多空间性很强的图形,这种图形渲染加载都会比2D慢,所以性能也是需要考虑的,其它3D图形用的维度指标较多,性能有待测试验证。 geo3D和map3d区别 geo3D不支持visualMap,显示3D地理,上面可以加柱状图,各省份数据无法展示。 map3d支持visualMap,可以显示区域数据,不能绘制柱状图,但是也有说可以隐藏一个geo3D来实现,所以待验证,大家可以尝试一下。 交流学习 刚建的群,学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/4/3
articleCard.readMore

Davinci-二次开发系列04:自定义水印扩展

水印(watermark) ​ 目前来看,水印已经具有很高的附加价值了,钱币的水印能防伪,资料上的水印能宣传,甚至很多对外的产品软件都把去水印当成VIP的一项特殊功能,随着知识产权加强,知识付费的流行,水印也成了防止盗用的一种很重要的手段。 ​ Davinci的水印我觉着官方迟早会出,但目前来看短时间出不来,出成什么样子也不确定,所以我们就先制瓜吃瓜。 ​ 效果: 水印制作 自定义水印位置 ​ 既然是自定义水印,自然也离不开用户和权限,为了先实现自定义,不考虑复杂因素,自定义水印根据项目划分,支持快捷显示项目名称等,不考虑用户自定义和项目自定义水印同时存在的情况。 ​ 在用户界面》》组织》》项目》》设置》》水印设置 水印显示位置 目前来看有这么几个位置: widget编辑区(编辑区理论不需要水印,观点不一) dashboard看板 display大屏 widget分享面板(官方留了口子,但没有实现完善,暂不考虑) dashboard分享面板 display分享面板 widget工作区: dashboard页面: display页面: 水印属性 开启关闭 项目名称 用户名 水印文本(比如“内部资料,严禁外传”这类) 水印时间戳(支持多种日期格式) 水印颜色 备注:未实现上传图片等格式的水印 水印编码实现 用户信息获取 ​ 登录用户信息获取目前有两种 ​ 方式一: 1 2 3 const mapStateToProps = createStructuredSelector({ loginUser: makeSelectLoginUser(), }) ​ 方式二: 1 const loginUser = localStorage.getItem('loginUser') 项目信息获取 1 2 3 const mapStateToProps = createStructuredSelector({ currentProject: makeSelectCurrentProject() }) 后台改造 后台改造比较简单: 第一:project表增加config字段,类型text,注意和json的转换 第二:分享功能增加project信息,用于展示项目名称,因为分享不登录状态即可访问,所以无法显示用户名 前端改造 前端改造难点除代码语法外, 第一:重点还是在用户名称和项目名称获取上 第二:自定义水印在组织里面,项目的获取和值传递 第三:分享功能,项目信息传递 第四:水印组件引入可以放在多个位置,放到widget下面会比较省劲,尤其是要求多个地方都呈现水印 几个推荐和注意 dashboard和display水印问题 ​ 第一:看上面的效果图能明显看到水印是最终实在单个widget下面的,而不是在整个面板上的,整体效果就差一些 ​ 第二:尤其是大屏这种,可以考虑每个大屏自定义水印,因为大屏有自身特有的组件 导出excel水印 数据导出excel同样需要水印,推荐实现 分享链接的水印 Davinci里面widget、dashboard、display都支持分享,widget不完善,分享不受权限控制,也不是我们正常进入到某个项目里面的操作,而我们的自定义水印是根据项目设定的,所以分享链接需要根据dashboard获取项目信息和水印的配置信息,并传递到widget组件里。 定时任务邮件接收水印 邮件接收报表带水印是非常合理的,根据水印时间戳更是能够准确判断当前报表的出具时间。 交流学习 刚建的群,学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/4/3
articleCard.readMore

Davinci-二次开发系列03:区域地图下钻与选择

概述 系列02中讲到百度地图扩展,地图应用场景多样,对于BI数据的呈现区域地图(非经纬度坐标)似乎应用更加广泛,这次说一下对于区域地图的几点改造。一个是下钻,一个是指定自定义的区域地图。 地图下钻 层级下钻,没有具体的几级,可以一直下钻并返回,这里做了国家、省份、市、区县、街道的下钻。 指定地图 指定需要展示的地图,并可以钻取和上卷。 吐槽一下Davinci地图 Davinci 地图目前十分的不友好,不得不吐槽一下: 不能很好的扩展地图 地图数据逻辑,通过地理类型和对照js文件去汇总,这种十分的不灵活 地图真实应用需求类似下钻不能满足 地图改造点 去掉原有的地图类型 ​ 原有地图类型:地图、气泡图、热力图、飞行图, ​ 改造后:去掉地图类型 ​ 这些需求在区域地图上是有的,官方就是考虑这些类型的实现导致区域地图显得复杂,尤其是飞行图这种实际BI应用场景中较少,而且飞行图是要有起点的,默认指定的第一个为起始点,非配置化,略显鸡肋。我们已经在百度地图扩展里做了一些实现,这里直接去掉原有的地图类型,简化代码,更突出区域地图的功能。 数据类型扩展 ​ 原类型:地理国家、地理省份、地理城市 ​ 扩展后:增加地理区县和地理街道 ​ 备注:实际改造了数据组装逻辑之后,类型仅仅是体现特殊性的地理维度,并不是严格的层级区分了,就是说改造之后实际指定的类型不影响数据展示。 数据组装逻辑改造 ​ 原逻辑:根据配置的地理类型,根据层级对照的js文件进行汇总计算。 ​ 改造后:根据实际数据进行自动汇总处理,与类型无关,即相同字段名称的汇总。 增加单击下钻右键返回事件 ​ 添加单击和右键事件实现下钻返回。 1 2 3 4 5 6 7 8 instance.off('click') instance.on('click', (params) => { // 添加单击事件 }) instance.on('contextmenu', (params) => { // 添加右键事件 }) 地图json文件扩展 ​ 既然能够指定区域地图,就要有地图的json文件,这里推荐两个免费的json地图地址。 ​ 阿里的:http://datav.aliyun.com/tools/atlas/#&lat=33.54139466898275&lng=104.2822265625&zoom=4 ​ 个人的:https://gallery.echartsjs.com/editor.html?c=xr1IEt3r4Q 更新很及时,行政区划调整比较及时。 ​ 中国闭源软件多,开源软件少,可能一个原因是付费的少,这些作者提供的json文件着实给力,所以建议大家使用之余,能力范围内打赏一下(非广告)。 几个推荐和注意 json文件改造自定义上传 ​ 可以改造json文件自定义上传,这样用户可以自己上传json文件然后从地图样式里面指定。 json层级建立对照字典表 ​ 对于自定义上传的json文件建立层级对照表,源码里面通过js文件对照的,不利于维护。 普通图表下钻功能的影响 ​ Davinci dashboard有下钻的功能,并且图表的钻添加了右键事件,所以需要进一步验证是否存在冲突的问题。 交流学习 刚建的群,学习Metabase、Davinci等开源BI,群号:72569367,感兴趣的可以加一下。

2020/3/28
articleCard.readMore