superset 图表加水印

转载wenqiang1208的文章

superset 作为一个数据可视化的工具,其中的图表,报表数据是非常敏感的,为了防止数据外泄,大部分公司需要在敏感图表上加上水印。

本篇文章有2种方式去介绍如何在superset上添加水印。

我们主要在首页,看板,chart图表,sqllab上加上水印。

 

 

版本信息

superset版本0.36

(可能适用于0.37或者0.38)

ps: 由于在原生的36版本上做了二次开发,可能会有部分代码不一致

先放几个加上水印的superset吧

首页

yGRgu8.png

看板详情yGWpgx.png

1、使用第三方水印库加上水印

遇到不会写的代码怎么办,熟练的打开 最大的同性交友网站(狗头) Github, 输入 waterMark 找找看。

经过一番搜索 貌似找到一个可用的开源库。

https://github.com/saucxs/watermark-dom

(版本迭代多,功能吻合, 配置简单,使用简单)

1.1 引入第三方库

cd superset-frontend
npm install watermark-dom -s

1.2 添加公共配置项

由于需要在好几个页面上加上水印,那最好把配置提取出来,这样方便修改

增加文件 superset-frontend/src/waterMark.js

文件内容

const waterMarkConf = {
    watermark_txt: 'superset水印',
    watermark_color: 'black',
    watermark_font: '微软雅黑',
    watermark_fontsize: 15,
    watermark_height: 88,
    watermark_width: 170,
    watermark_x_space: 10,
    watermark_y_space: 5,
    watermark_alpha: 0.15,
    watermark_angle: 20,
}
export default waterMarkConf;

这些参数 可以参考 第三方库的配置 修改

1.3 welcome首页 添加水印

首页的目录地址

superset-frontend/src/welcome/App.jsx

修改该文件,添加内容

import watermark from 'watermark-dom';
import waterMarkConf from '../waterMark.js'

watermark.init({...waterMarkConf,  watermark_txt: `测试水印 ${user.username}`})

ps:由于需要加上名字, 这边覆盖了原有的水印内容,

username 是从后端的的 相关接口 传入的, 可以在 superset/views/core.py 搜索 bootstrap_data,

注意: 首页的看板列表页面和 dashboard菜单下的列表页面 是用的同一套组件,所以在首页修改后,看板菜单的列表页面 也修改了

1.4 dashboard详情页面

看板详情页面的地址: superset-frontend/src/dashboard/App.jsx

同理修改

import watermark from 'watermark-dom';
import waterMarkConf from 'src/waterMark';

// username 不存在的话,需要获取
const username = bootstrapData.username;

watermark.load({...waterMarkConf,  watermark_txt: `玩物得志 ${username}`});

注意: 由于看板详情页面的后端接口没有返回用户信息,需要修改一下后端接口返回用户名

superset/views/core.py 中的 @expose("/dashboard/<dashboard_id>/") 接口

在返回的数据bootstrap_data 增加用户名

"username": g.user.username if g.user else '',

1.5 chart图表详情页面

chart图表详情页面地址: superset-frontend/src/explore/App.jsx

与看板详情页面同理

后端接口 superset/views/core.py

 @expose("/explore/<datasource_type>/<datasource_id>/", methods=["GET", "POST"])
    @expose("/explore/", methods=["GET", "POST"])

1.6 SqlLab页面

Sqllab详情页面 superset-frontend/src/SqlLab/App.jsx

同理 修改

后端接口 superset/views/core.py

def _get_sqllab_payload(user_id: int) -> Dict[str, Any] 函数中的返回值 增加 username

额外注意

如果样式有问题的话, 可能是 body 和 #app 有冲突 可以尝试调整 superset-frontend/stylesheets/less/index.less

2、自定义watermark工具

由于前端做了较多的二次开发 导致 第一种方式的部分页面不兼容水印,样式比较难调。

因此 有了第二种方式。目前第二种方式 比较稳定

参考大佬的链接: https://www.cnblogs.com/feng3037/p/14028780.html

有做略微调整

2.1 新建waterMark工具文件

新建 superset-frontend/src/waterMark.js

const watermark = ({
        // 使用 ES6 的函数默认值方式设置参数的默认取值
        container = document.body,
        width = '170px',
        height = '88px',
        textAlign = 'left',
        textBaseline = 'bottom',
        font = '15px Microsoft Yahei',
        fillStyle = 'black',
        content = '玩物得志',
        rotate = 20,
        zIndex = 10000,
        opacity = 0.08,
    } = {}, ...res) => {
    const args = res
    const canvas = document.createElement('canvas')

    canvas.setAttribute('width', width)
    canvas.setAttribute('height', height)
    const ctx = canvas.getContext('2d')

    ctx.textAlign = textAlign
    ctx.textBaseline = textBaseline
    ctx.font = font
    ctx.fillStyle = fillStyle
    ctx.rotate(- rotate * Math.PI / 180 )
    ctx.fillText(content, 35, 90)

    const base64Url = canvas.toDataURL()
    const __wm = document.querySelector('.__wm')
    const watermarkDiv = __wm || document.createElement('div')
    const styleStr = `
  position:absolute;
  top:0;
  left:0;
  width:100%;
  height:100%;
  z-index:${zIndex};
  pointer-events:none;
  opacity:${opacity};
  background-repeat:repeat;
  background-image:url('${base64Url}')`

    watermarkDiv.setAttribute('style', styleStr)
    watermarkDiv.classList.add('__wm')

    if (!__wm) {
        container.insertBefore(watermarkDiv, container.firstChild)
    }

    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver
    if (MutationObserver) {
        let mo = new MutationObserver(function () {
            const __wm = document.querySelector('.__wm')
            console.log(__wm)
            // 只在__wm元素变动才重新调用 __canvasWM
            if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
                // 避免一直触发
                mo.disconnect()
                mo = null
                watermark(JSON.parse(JSON.stringify(args)))
            }
        })

        mo.observe(container, {
            attributes: true,
            subtree: true,
            childList: true
        })
    }

}
export default watermark;

2.2 修改各个详情页面

与第一种方式 修改类似,再App.js 文件中添加

// 引入
import watermark from '../waterMark';
// 初始化
watermark({
  content: `测试水印 ${user.username}`,
  container: document.querySelector('body')
})

额外注意

可能需要调整样式,非必须

1、

superset-frontend/stylesheets/less/index.less

body {
  position: absolute;

  min-height: 100% !important;
  height: auto !important;
  width: 100%;
  display: flex;
  flex-direction: column;
}

2、

如果 loading gif 位置变化的话,可以调整下面的文件

superset/templates/superset/basic.html

调整下面的代码

 <img src="/static/assets/images/loading.gif" style="width: 50px; position: absolute; top: 200px; left: 50%; transform: translate(-50%,-50%)">
 

总结

1、本人前端半吊子水平,如果有问题 请见谅。

2、欢迎大家一起来交流 superset 二次开发

posted @ 2021-09-24 11:36  数据行者  阅读(753)  评论(0编辑  收藏  举报