美文网首页
grafana使用d3开发panel

grafana使用d3开发panel

作者: Nick_4438 | 来源:发表于2020-10-18 16:31 被阅读0次

    使用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

    相关文章

      网友评论

          本文标题:grafana使用d3开发panel

          本文链接:https://www.haomeiwen.com/subject/njecmktx.html