【Grafana】Grafana集成Echart,基于插件实现自定义数据源+自定义图表

目录

一、目的

二、实现案例

三、Echart集成Grafana

四、附录


一、目的

grafana提供时序数据展示,默认提供的模板可能无法满足需求,比如我目前需要一个双层饼图,grafana只能提供最为基础的 PIE chart,而grafana提供了插件开发的功能,故可以把echart相关图表集成到grafana中获取满足自己需求的图表。

产出结果示例:

二、实现案例

案例集成:

  • 数据源:时序数据库Influxdb (可自由调整,都可以兼容,比如Prometheus)
  • 图表模板:echart (大部分图表应该都可以兼容)

grafana集成influxdb很容易,这边不再赘述。

简单贴一下安装过程,方便大家:

grafana安装:

grafana安装:

wget https://dl.grafana.com/oss/release/grafana-7.1.0-1.x86_64.rpm

sudo yum -y install grafana-7.1.0-1.x86_64.rpm

基本命令:
启动:
systemctl start grafana-server
systemctl restart grafana-server

查看版本:
grafana-server -v

访问:ip:3000 进入控制台,默认账号密码admin

 influxdb安装:

influxdb安装:
下载 rpm 文件
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.8.2.x86_64.rpm

安装
sudo yum localinstall influxdb-1.8.2.x86_64.rpm

启动 InfluxDB:
systemctl start influxdb

设为开机启动:
systemctl enable influxdb

连接 InfluxDB
( -precision 参数表明了任何返回的时间戳的格式和精度,rfc3339 是让 InfluxDB 返回 RFC339 格式(YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ)的时间戳。)

influx -precision rfc3339

创建数据库
CREATE DATABASE mydb

influxdb插入数据:

INSERT cost,name='云服务器' value=1048
INSERT cost,name='负载均衡' value=335
INSERT cost,name='物理机房' value=510
INSERT cost,name='网络带宽' value=251
INSERT cost,name='serverless' value=234
INSERT cost,name='对象存储' value=147
INSERT cost,name='其他费用' value=102

 数据源这边ok了,grafana这边需要集成插件到控制台,插件下载地址( https://download.csdn.net/download/qq_37822090/20304362 )。

插件下载完成后,需要上传到grafana插件目录,并进行构建:

#下载grafana插件开发相关node_modules
npm install

#构建yarn
yarn install

#Build plugin in development mode or run in watch mode
yarn dev

#Build plugin in production mode ,可先跳过
yarn build

源码结构图:

构建完成之后 ,重启grafana:

systemctl restart grafana-server

注意:插件开发构建过程中npm构建失败很常见,yarn构建失败,需要自己联调,一定要构建完成才能使用。

(我这边基于官方grafana插件编写构建失败拖了很长时间,服务器访问github还需要自己修改host,有时候还不成功,这个插件构建时应该没有那种问题,出现问题了一步一步走就ok,我这边都成功了)。

主要引起的原因:

nodejs版本,我这边使用最新的 v12.18.3

grafana版本,github上提示支持 6.3+ & 7.0+,我这边使用的7.1.0

执行构建命令时,root用户可能执行失败,切换下用户,文件授权也需要自行调整

三、Echart集成Grafana

直接去echart上面捞就行,如图:

 获取到左边源码图,粘贴到插件funtion位置,自行修改,如图示例:

 我这边编写的数据获取使用录入了的influxdb+外部ajax远程请求一个接口完成简单计算,为了试用它的ajax功能,有需要的可以贴过去试用:

if (data.series.length==0) {
  return
}
let s = 1
$.ajax({
    type: "GET",
    async: false,
    url: "http://10.200.19.43:9041/test1",
    success: function (res) {
      s = res
    }
});
const names = data.series[0].fields.find((f) => f.type === 'number').values.buffer;
const values = data.series[1].fields.find((f) => f.type === 'number').values.buffer;
const result = values.map((a,i) => ({name: names[i], value: a*s}));
console.log(s)

console.log(result)
option = {
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
        data: ['云服务器', '负载均衡', '对象存储', '网络带宽', '阿里云', '腾讯云', '物理机']
    },
    series: [
        { 
            name: '费用来源',
            type: 'pie',
            selectedMode: 'single',
            radius: [0, '30%'],
            label: {
                position: 'inner',
                fontSize: 14,
            },
            labelLine: {
                show: false
            },
            data: [
                {value: 1548, name: '阿里云'},
                {value: 775, name: '腾讯云'},
                {value: 679, name: '物理机'}
            ]
        },
        {
            name: '费用来源',
            type: 'pie',
            radius: ['45%', '60%'],
            labelLine: {
                length: 30,
            },
            label: {
                formatter: '{a|{a}}{abg|}\n{hr|}\n  {b|{b}:}{c}  {per|{d}%}  ',
                backgroundColor: '#F6F8FC',
                borderColor: '#8C8D8E',
                borderWidth: 1,
                borderRadius: 4,
                
                rich: {
                    a: {
                        color: '#6E7079',
                        lineHeight: 22,
                        align: 'center'
                    },
                    hr: {
                        borderColor: '#8C8D8E',
                        width: '100%',
                        borderWidth: 1,
                        height: 0
                    },
                    b: {
                        color: '#4C5058',
                        fontSize: 14,
                        fontWeight: 'bold',
                        lineHeight: 33
                    },
                    per: {
                        color: '#fff',
                        backgroundColor: '#4C5058',
                        padding: [3, 4],
                        borderRadius: 4
                    }
                }
            },
            data: result
        }
    ]
};

echartsInstance.setOption(option);

至此完成一个案例echart集成gragana,结果如图:

influxdb v2.0 跨表集成案例:

console.log(data)

if (data.series.length==0) {
  return
}
let s = 1
// $.ajax({
//     type: "GET",
//     async: false,
//     url: "http://10.200.19.43:9041/test1",
//     success: function (res) {
//       s = res
//     }
// });
//data.series.map((s) =>console.log(s.fields[1]));


const names = [];
const values = [];
const totalNames = [];
const totalValues = [];
for (var i = 0; i < data.series.length; i++) {
	if(data.series[i].refId=='A'){
		names.push(data.series[i].fields[1].labels.instanceType);
		values.push(data.series[i].fields[1].state.calcs.lastNotNull);
	} else if(data.series[i].refId=='B'){
		totalNames.push(data.series[i].fields[1].labels.name);
		totalValues.push(data.series[i].fields[1].state.calcs.lastNotNull);
	} else if(data.series[i].refId=='C'){
	  	names.push(data.series[i].fields[1].labels.storageClass);
		values.push(data.series[i].fields[1].state.calcs.lastNotNull);
	}
}

//data.series.map((s) =>(s.refId==='A'?s.fields[1].labels.instanceType:''));

const result = values.map((a,i) => ({name: names[i], value: a*s}));
const totalResult = totalValues.map((a,i) => ({name: totalNames[i], value: a*s}));

console.log(s)

console.log(result)
option = {
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
        data: ["实例", "存储"]
    },
    series: [
        { 
            name: '费用来源',
            type: 'pie',
            selectedMode: 'single',
            radius: [0, '30%'],
            label: {
                position: 'inner',
                fontSize: 14,
            },
            labelLine: {
                show: false
            },
            data: totalResult
        },
        {
            name: '费用来源',
            type: 'pie',
            radius: ['45%', '60%'],
            labelLine: {
                length: 30,
            },
            label: {
                formatter: '{a|{a}}{abg|}\n{hr|}\n  {b|{b}:}{c}  {per|{d}%}  ',
                backgroundColor: '#F6F8FC',
                borderColor: '#8C8D8E',
                borderWidth: 1,
                borderRadius: 4,
                
                rich: {
                    a: {
                        color: '#6E7079',
                        lineHeight: 22,
                        align: 'center'
                    },
                    hr: {
                        borderColor: '#8C8D8E',
                        width: '100%',
                        borderWidth: 1,
                        height: 0
                    },
                    b: {
                        color: '#4C5058',
                        fontSize: 14,
                        fontWeight: 'bold',
                        lineHeight: 33
                    },
                    per: {
                        color: '#fff',
                        backgroundColor: '#4C5058',
                        padding: [3, 4],
                        borderRadius: 4
                    }
                }
            },
            data: result
        }
    ]
};

echartsInstance.setOption(option);

四、附录

集成echart插件下载地址:https://download.csdn.net/download/qq_37822090/20304362

echart相关模板地址:Apache ECharts

插件github地址(感谢这位大佬提供的插件):https://github.com/Billiballa/bilibala-echarts-panel

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要基于Luckysheet实现自定义报表,需要先了解Luckysheet的一些基本概念和操作。Luckysheet使用似于Excel的电子表格界面,支持常见的电子表格功能,如公式计算、条件格式、筛选等。同时,Luckysheet还提供了一些自定义功能,例如自定义函数、数据验证、图表等。 基于Luckysheet实现自定义报表的具体步骤如下: 1. 创建一个新的Luckysheet文件。 在页面中插入Luckysheet的HTML标签,并在JavaScript中初始化一个空的Luckysheet文件。例如: ```html <div id="luckysheet"></div> ``` ```javascript <script> $(function() { // 初始化Luckysheet文件 luckysheet.create({ container: 'luckysheet', // 指定容器 showinfobar: false, // 隐藏信息栏 showsheetbar: false, // 隐藏工作表栏 showtoolbar: false, // 隐藏工具栏 showstatusbar: false, // 隐藏状态栏 }); }); </script> ``` 2. 设计报表的结构和样式。 根据报表的需求,设计出电子表格的结构和样式,包括表头、数据区域、分组、合并单元格等。可以通过Luckysheet提供的API来修改电子表格的属性,例如单元格样式、字体大小、颜色等。例如: ```javascript // 设置单元格样式 luckysheet.setStyle(0, 0, 1, 1, { backgroundColor: '#f6f8fa', fontWeight: 'bold', textAlign: 'center', }); // 设置字体大小和颜色 luckysheet.setFontSize(0, 0, '14px'); luckysheet.setFontColor(0, 0, '#333'); ``` 3. 实现数据源的获取和填充。 将报表需要展示的数据传递给前端,根据数据源的不同,可以使用不同的方式获取数据,例如从数据库中查询、从文件中读取、从API中获取等。获取到数据后,将数据填充到电子表格中。可以使用Luckysheet提供的API来设置单元格的值、公式等。例如: ```javascript // 设置单元格的值 luckysheet.setCellValue(1, 1, 'John'); luckysheet.setCellValue(1, 2, 'Doe'); // 设置单元格的公式 luckysheet.setCellFormula(2, 1, '=SUM(A2:B2)'); ``` 4. 实现报表的自定义功能。 根据报表的需求,实现自定义的功能,例如自定义函数、数据验证、图表等。可以使用Luckysheet提供的API来实现这些功能,也可以自己编写JavaScript代码来实现。例如: ```javascript // 实现自定义函数 luckysheet.setCustomFunction('CUSTOMFUNC', function() { // 自定义函数的实现 }); // 实现数据验证 luckysheet.setValidation(1, 1, { type: 'dropdown', // 下拉框验证 value: ['Male', 'Female'], // 下拉框选项 }); // 实现图表 luckysheet.createChart({ // 创建图表 chartType: 'bar', // 图表型 range: 'A2:B5', // 图表数据范围 position: { row: 8, col: 1 }, // 图表位置 title: 'Sales Report', // 图表标题 }); ``` 5. 导出报表。 根据需要,将报表导出为PDF、Excel、图片等格式。可以使用第三方库或框架来实现导出功能,例如jsPDF、ExcelJS、html2canvas等。 以上就是基于Luckysheet实现自定义报表的基本步骤。具体实现时,还需要根据报表的需求进行调整和修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值