使用AntV F2实现仪表盘的例子

 

目前公司需要开发移动端图表项目,就选用了f2。目前没在官方实例里面找到罗盘的例子,就参考了G2的写了一个。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Immutable from 'immutable';
import F2 from '@antv/f2';
const color = ['#FF5961', '#FABE32', '#1FDE44'];


export default class PanelChart extends Component {

  static defaultProps = {
    panenlDataObj: {},
    chartId: ''
  };
  static propTypes = {
    panenlDataObj: PropTypes.object,
    chartId: PropTypes.string,
  };

  constructor(props) {
    super(props);
    this.state = {
      chart: null
    };
  }

  componentWillReceiveProps(nextProps) {
    if (!Immutable.is(nextProps.panenlDataObj, this.props.panenlDataObj)) {
      this.changeMainChart(nextProps.panenlDataObj);
    }
  }

  draw = (chart, panenlDataObj) => {
    const lineWidth = 20;
    chart.guide().clear();
    // 绘制仪表盘背景
    chart.guide().arc({
      zIndex: 0,
      top: false,
      start: [0, 0.92],
      end: [100, 0.92],
      style: { // 底灰色
        stroke: '#CBCBCB',
        lineWidth
      }
    });
    chart.guide().arc({
      zIndex: 1,
      start: [0, 0.92],
      end: [40, 0.92],
      style: {
        stroke: color[0],
        lineWidth
      }
    });

    chart.guide().arc({
      zIndex: 1,
      start: [40, 0.92],
      end: [60, 0.92],
      style: {
        stroke: color[1],
        lineWidth
      }
    });

    chart.guide().arc({
      zIndex: 1,
      start: [60, 0.92],
      end: [100, 0.92],
      style: {
        stroke: color[2],
        lineWidth
      }
    });

    chart.guide().arc({
      zIndex: 1,
      start: [40, 0.92],
      end: [60, 0.92],
      style: {
        stroke: color[1],
        lineWidth
      }
    });

    chart.guide().arc({
      zIndex: 1,
      start: [0, 0.92],
      end: [40, 0.92],
      style: {
        stroke: color[0],
        lineWidth
      }
    });
    // 绘制指标数字
    chart.guide().html({
      position: ['50%', '75%'],
      html: '<div style="width: 300px;text-align: center;">'
    + `<p style="font-size: 12px; color: #666;margin-top: 30px;margin-bottom: 2px;display: ${panenlDataObj.goalVal === undefined ? 'none' : 'block'}">${panenlDataObj.goalVal}</p>`
    + `<p style="font-size: 14px;color: #333;margin-bottom: 2px;display: ${panenlDataObj.prevVal === undefined ? 'none' : 'block'}">&nbsp;&nbsp;&nbsp;${panenlDataObj.prevVal}</p>`
    + `<p style="font-size: 12px;color: #3f3f3f;margin-bottom: 2px;display: ${panenlDataObj.crtVal === undefined ? 'none' : 'block'}">&nbsp;&nbsp;&nbsp;<span style="color:#FF6F00" >${panenlDataObj.crtVal > 0 ? '+' : ''}${panenlDataObj.crtVal}</span>&nbsp;&nbsp;${panenlDataObj.crtType}</p>`
    + '</div>'
    });
    chart.render();
  }

  changeMainChart = (panenlDataObj) => {
    const { chartId } = this.props;
    const { Shape } = F2;
    let { chart } = this.state;
    if (!chart) {
      chart = new F2.Chart({
        id: chartId,
        pixelRatio: window.devicePixelRatio,
        padding: [10, 0, 0, 0],
      });
      Shape.registerShape('point', 'pointer', {
        draw: function(cfg, group) {
          const center = this.parsePoint({ x: 0, y: 0 });
          group.addShape('line', {
            attrs: {
              x1: center.x,
              y1: center.y,
              x2: cfg.x,
              y2: cfg.y,
              stroke: '#FF6F00',
              lineWidth: 5,
              lineCap: 'round'
            },
          });
          group.addShape('circle', {
            attrs: {
              x: center.x,
              y: center.y,
              x2: cfg.x,
              r: 4,
              stroke: '#FF6F00',
              lineWidth: 3,
              fill: '#fff'
            }
          });
          return group;
        }
      });
    } else {
      chart.clear();
    }
    // 自定义Shape 部分
    chart.source(panenlDataObj.panelData);

    chart.coord('polar', {
      startAngle: -9 / 8 * Math.PI,
      endAngle: 1 / 8 * Math.PI,
    });
    chart.tooltip(false);
    chart.scale('value', {
      min: 0,
      max: 100,
      tickInterval: 20,
      nice: false
    });
    chart.axis('1', false);
    chart.axis('value', {
      line: null,
      label: {
        offset: -80,
        textStyle: {
          fontSize: 18,
          fill: '#CBCBCB',
          textAlign: 'center',
          textBaseline: 'middle'
        }
      },
      tickLine: {
        length: -24,
      },
      grid: null
    });
    chart.legend(false);
    chart.point().position('value*1')
      .shape('pointer');
    this.setState({
      chart
    });
    this.draw(chart, panenlDataObj);
  }

  render() {
    const { chartId } = this.props;
    return (
      <div style={{ marginBottom: '50px' }}>
        <canvas id={chartId} className="canvas"></canvas>
      </div>
    );
  }
}

数据获取:

成图:

注意: 

1.panelData要为Number类型,antvF2为固定~3.5.0-beta.3版本,当我^3.5.0-beta.3向上兼容新的版本的时候,仪表盘指针会失效,查到原因是 x1: center.x,y1: center.y,x2: cfg.x,y2: cfg.y,会对应同一个坐标点,导致指针肯定无法显示了。不知道新的f2版本为啥会出现这个问题~~~~~

2.当你切换多个tab下的罗盘时,会出现罗盘数值会被重复覆盖的问题,或者是手指触摸屏幕查看图标数据,会有闪现的情况发生。都可以用,结合clear()和setState使用即可

在此附上f2官网实例https://f2.antv.vision/zh/examples/line/basic

 

发布了68 篇原创文章 · 获赞 32 · 访问量 16万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览