grafana使用d3开发panel

举报
Nick Qiu 发表于 2020/10/23 12:33:08 2020/10/23
【摘要】 使用d3创建 panel插件简介本文讲解如何使用d3创建一个panel插件如何创建panel插件参考第本系列文章-第一篇为了简化说明,重新修改SimplePanel.tsx文件,初始化成如下:import React from 'react';import { PanelProps } from '@grafana/data';import { SimpleOptions } from 't...

使用d3创建 panel插件

简介

本文讲解如何使用d3创建一个panel插件

  • 如何创建panel插件参考第本系列文章-第一篇

  • 为了简化说明,重新修改SimplePanel.tsx文件,初始化成如下:

import React from 'react';import { PanelProps } from '@grafana/data';import { SimpleOptions } from 'types';import {  useTheme } from '@grafana/ui';

interface Props extends PanelProps<SimpleOptions> {}export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) => {  const theme = useTheme();  const values = [4, 8, 15, 16, 23, 42];  const barHeight = height / values.length;  return (    <svg width={width} height={height}>
    <g>
      {values.map((value, i) => (        <rect x={0} y={i * barHeight} width={value} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))}    </g>
  </svg>
  );
};

操作步骤

  • grafana已经绑定了d3我们可以直接访问d3包,但是因为开发的时候要使用d3的类型定义,所以需要安装d3的类型定义

yarn add --dev @types/d3
  • 导入 d3到SimplePanel.tsx.

import * as d3 from 'd3';
  • 利用d3的缩放功能重新适配柱状图,创建一个scale,数值的方位在0max(values),对应实际显示柱状图在0svg的width之间

const scale = d3
  .scaleLinear()
  .domain([0, d3.max(values) || 0.0])
  .range([0, width]);
  • 重新编写前端渲染函数,使用scale计算宽度

  return (
    <svg width={width} height={height}>
    <g>
      {/* {values.map((value, i) => (
        <rect x={0} y={i * barHeight} width={value} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))} */}
       {values.map((value, i) => (
        <rect x={0} y={i * barHeight} width={scale(value)} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))}
    </g>
  </svg>
  );
  • 完整SimplePanel.tsx代码

import React from 'react';import { PanelProps } from '@grafana/data';import { SimpleOptions } from 'types';import {  useTheme } from '@grafana/ui';import * as d3 from 'd3';


interface Props extends PanelProps<SimpleOptions> {}export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) => {  const theme = useTheme();  const values = [4, 8, 15, 16, 23, 42];  const barHeight = height / values.length;  const scale = d3
  .scaleLinear()
  .domain([0, d3.max(values) || 0.0])
  .range([0, width]);  
  return (
    <svg width={width} height={height}>
    <g>
      {/* {values.map((value, i) => (
        <rect x={0} y={i * barHeight} width={value} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))} */}
       {values.map((value, i) => (
        <rect x={0} y={i * barHeight} width={scale(value)} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))}
    </g>
  </svg>
  );
};
  • 编译程序

yarn dev
  • 刷新grafana加载程序,如下图可以看到,柱状图可以自己缩放,适应panel的大小,大大的减少了计算的复杂度

  • 添加宽度标尺子

export const SimplePanel: React.FC<Props> = ({ options, data, width, height }) => {  const theme = useTheme();  const values = [4, 8, 15, 16, 23, 42];  const padding = 20;  const chartHeight = height - padding;  const barHeight = chartHeight / values.length;  const scale = d3
  .scaleLinear()
  .domain([0, d3.max(values) || 0.0])
  .range([0, width]);  // 声明一个坐标
  const axis = d3.axisBottom(scale);  
  return (
    <svg width={width} height={height}>
      {/* 坐标渲染 */}
    <g
      transform={`translate(0, ${chartHeight})`}
      ref={node => {
        d3.select(node).call(axis as any);
      }}
    />
    <g>
       {values.map((value, i) => (
        <rect x={0} y={i * barHeight} width={scale(value)} height={barHeight - 1} fill={theme.palette.greenBase} />
      ))}
    </g>
  </svg>
  );
};
  • 最终效果如下图

image.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200