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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章