目前公司需要開發移動端圖表項目,就選用了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'}"> ${panenlDataObj.prevVal}</p>`
+ `<p style="font-size: 12px;color: #3f3f3f;margin-bottom: 2px;display: ${panenlDataObj.crtVal === undefined ? 'none' : 'block'}"> <span style="color:#FF6F00" >${panenlDataObj.crtVal > 0 ? '+' : ''}${panenlDataObj.crtVal}</span> ${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