基于vue3 和 F2 3.5.0
<template><div :style="{minHeight: `${height}px`,width: '100%' }" ref="container"><canvas v-show="showChart" ref="canvas" :id="chartId" class="chart-canval"></canvas><empty-box v-show="!showChart"></empty-box></div>
</template><script setup lang="ts">
import { ref, onMounted } from 'vue'
import F2 from '@antv/f2/lib/index-all.js';
import { flame } from "ionicons/icons";
import {isArray, sumBy} from 'lodash-es';const props = defineProps({height: {type: Number,default: 260,required: false},chartId: {type: String,default: 'PieChart'},legendPosition: {type: String,default: 'bottom'},color: {type: Array,default: ['#F0BD58', '#97DFD8', '#ED7E63', '#7357F6', '#84BBF0FF', '#D364BBFF', '#459EF5FF', '#71D364FF', '#F5D18AFF', '#A1E498FF']},labelInto: {type: String,default: ''},unit: {type: String,default: ''},showLegendUnit: {type: Boolean,default: false},showLegend: {type: Boolean,default: true},showPieLabel: {type: Boolean,default: false},pieLabelSidePadding: {type: Number,default: 15},intervalPositionX: {type: String,default: 'name'},intervalPositionY: {type: String,default: 'number'},
})const chart = ref()
const canvas = ref()
const container = ref()
const showChart = ref(true)onMounted(() => {setTimeout(() => {newChartBox()}, 100);
})const newChartBox = () => {const clientWidth = document.documentElement.clientWidthconst domWidth = container.value.clientWidthchart.value = new F2.Chart({id: props.chartId,width: domWidth || clientWidth,height: props.height,// padding: [10, 10, 100, 30],pixelRatio: window.devicePixelRatio});
}/*** @description: 饼图* @param {*} data 数据* @return {*}*/
const initChartTimeout = (data: any, labelNumber?: any) => {if (data.length > 0) {showChart.value = true;const mapNum: any = {};const mapRate: any = {};const totalNum: any = Number(sumBy(data, props.intervalPositionY).toFixed(2))if (isArray(data)) {data.forEach(function (obj) {mapNum[obj[props.intervalPositionX]] = obj[props.intervalPositionY];});data.forEach(function (obj) {if ( obj['ratio'] ) {mapRate[obj[props.intervalPositionX]] = obj.ratio;} else {const ratio: any = Number((obj[props.intervalPositionY] / totalNum * 100).toFixed(2));obj['ratio'] = ratio;mapRate[obj[props.intervalPositionX]] = ratio;}});}if (chart.value) {chart.value.clear(); // 清理所有}chart.value.source(data);chart.value.tooltip(false);chart.value.coord('polar', {transposed: true,innerRadius: 0.75,radius: 0.95});chart.value.axis(false);chart.value.interval().position(`const*ratio`).color([props.intervalPositionX], props.color).adjust('stack');if (props.showLegend) {chart.value.legend({position: props.legendPosition,align: 'center',itemWidth: null,itemFormatter: (val: any) => {if (props.showLegendUnit) {return `${val} ${mapNum[val]}${props.unit} ${mapRate[val]}%`;} else {return `${val} ${mapNum[val]}${props.unit}`;}}})} else {chart.value.legend(false);}if (labelNumber || props.labelInto) {chart.value.guide().html({position: ['50%', '50%'],html: `<div style="width: 120px;;text-align: center;"><div style="font-size: 16px;font-weight:600;">${totalNum || ''}</div><div style="font-size: 12px">${props.labelInto || ''}</div></div>`});}if (props.showPieLabel) {chart.value.pieLabel({sidePadding: props.pieLabelSidePadding,label1: function label1(data: any) {return {text: data[props.intervalPositionX],fill: '#808080',};},label2: function label2(data: any) {return {fill: '#000000',text: `${data[props.intervalPositionY]} ${data.ratio}%`,fontWeight: 500,fontSize: 10,};}});}render()} else {showChart.value = false}
}const initChart = (data: any, labelNumber?: any) => {setTimeout(() => {initChartTimeout(data, labelNumber)}, 100);
}const render = () => {chart.value.render();
}defineExpose({ initChart, chart, render, newChartBox })</script>
引用
<InitPieChart ref="refPieChart" chartId="refPieChart" :height="220" unit="户" label-into="总户数"/>
const initChart = () => {let chartData = [{number: 0, name: '农户', const: 'const', prop: 'subjectNumFarm'},{number: 0, name: '商户', const: 'const', prop: 'subjectNumMerc'},{number: 0, name: '企业', const: 'const', prop: 'subjectNumEnt'},{number: 0, name: '其他', const: 'const', prop: 'subjectNumOth'}]chartData = chartData.map(item => ({...item,number: houseData.value[item.prop]}));refPieChart.value.initChart(chartData)
}