import React, { Component } from 'react'; import { Chart, Tooltip, Geom, Coord } from 'bizcharts'; import { DataView } from '@antv/data-set'; import { Divider } from 'antd'; import classNames from 'classnames'; import ReactFitText from 'react-fittext'; import Debounce from 'lodash-decorators/debounce'; import Bind from 'lodash-decorators/bind'; import autoHeight from '../autoHeight'; import styles from './index.less'; /* eslint react/no-danger:0 */ @autoHeight() export default class Pie extends Component { state = { legendData: [], legendBlock: false, }; componentDidMount() { this.getLegendData(); this.resize(); window.addEventListener('resize', this.resize); } componentWillReceiveProps(nextProps) { const { data } = this.props; if (data !== nextProps.data) { // because of charts data create when rendered // so there is a trick for get rendered time const { legendData } = this.state; this.setState( { legendData: [...legendData], }, () => { this.getLegendData(); } ); } } componentWillUnmount() { window.removeEventListener('resize', this.resize); this.resize.cancel(); } getG2Instance = chart => { this.chart = chart; }; // for custom lengend view getLegendData = () => { if (!this.chart) return; const geom = this.chart.getAllGeoms()[0]; // 获取所有的图形 const items = geom.get('dataArray') || []; // 获取图形对应的 const legendData = items.map(item => { /* eslint no-underscore-dangle:0 */ const origin = item[0]._origin; origin.color = item[0].color; origin.checked = true; return origin; }); this.setState({ legendData, }); }; handleRoot = n => { this.root = n; }; handleLegendClick = (item, i) => { const newItem = item; newItem.checked = !newItem.checked; const { legendData } = this.state; legendData[i] = newItem; const filteredLegendData = legendData.filter(l => l.checked).map(l => l.x); if (this.chart) { this.chart.filter('x', val => filteredLegendData.indexOf(val) > -1); } this.setState({ legendData, }); }; // for window resize auto responsive legend @Bind() @Debounce(300) resize() { const { hasLegend } = this.props; if (!hasLegend || !this.root) { window.removeEventListener('resize', this.resize); return; } const { legendBlock } = this.state; if (this.root.parentNode.clientWidth <= 380) { if (!legendBlock) { this.setState({ legendBlock: true, }); } } else if (legendBlock) { this.setState({ legendBlock: false, }); } } render() { const { valueFormat, subTitle, total, hasLegend = false, className, style, height, forceFit = true, percent = 0, color, inner = 0.75, animate = true, colors, lineWidth = 1, } = this.props; const { legendData, legendBlock } = this.state; const pieClassName = classNames(styles.pie, className, { [styles.hasLegend]: !!hasLegend, [styles.legendBlock]: legendBlock, }); const { data: propsData, selected: propsSelected = true, tooltip: propsTooltip = true, } = this.props; let data = propsData || []; let selected = propsSelected; let tooltip = propsTooltip; const defaultColors = colors; // let data = this.props.data || []; // let selected = this.props.selected || true; // let tooltip = this.props.tooltip || true; let formatColor; const scale = { x: { type: 'cat', range: [0, 1], }, y: { min: 0, }, }; if (percent) { selected = false; tooltip = false; formatColor = value => { if (value === '占比') { return color || 'rgba(24, 144, 255, 0.85)'; } else { return '#F0F2F5'; } }; data = [ { x: '占比', y: parseFloat(percent), }, { x: '反比', y: 100 - parseFloat(percent), }, ]; } const tooltipFormat = [ 'x*percent', (x, p) => ({ name: x, value: `${(p * 100).toFixed(2)}%`, }), ]; const padding = [12, 0, 12, 0]; const dv = new DataView(); dv.source(data).transform({ type: 'percent', field: 'y', dimension: 'x', as: 'percent', }); return (