基于vue3 和 F2 3.5.0
<template>
<div :style="{ minHeight: `${height}px`, width: '100%' }" ref="container">
<canvas v-show="showChart" :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';
const props = defineProps({
height: {
type: Number,
default: 300,
required: false
},
chartId: {
type: String,
default: 'LineChart'
},
color: {
type: Array,
default: ['#1890ff', '#6be58f', '#ffcb00', '#fd1063', '#7357F6FF', '#ED7E63FF', '#84BBF0FF', '#D364BBFF']
},
areaColor: {
type: Array,
// default: ['l(270) 0:#ffffff 0.5:#7ec2f3 1:#1890ff', 'l(270) 0:#ffffff 0.5:#2fc25b 1:#6be58f', 'l(270) 0:#ffffff 0.5:#ffcb00 1:#ffcb00', 'l(270) 0:#ffffff 0.5:#fd1063 1:#fd1063']
default: []
},
showLegend: {
type: Boolean,
default: true
},
legendPosition: {
type: String,
default: 'bottom'
},
unit: {
type: String,
default: '单位:%'
},
isTwoUnit: {
type: Boolean,
default: false
},
unit2: {
type: String,
default: '单位:%'
},
})
const chart = ref()
const container = ref()
const showChart = ref(true)
onMounted(() => {
setTimeout(() => {
const clientWidth = document.documentElement.clientWidth
const domWidth = container.value.clientWidth
chart.value = new F2.Chart({
id: props.chartId,
width: domWidth || clientWidth,
height: props.height,
// appendPadding: [10, 25, 10, 10],
pixelRatio: window.devicePixelRatio
});
}, 100);
})
/**
* @description: 折线图
* @param {*} data 数据
* @return {*}
*/
const initChartTimeout = (data: any, unit?: String) => {
if (data && data.length > 0) {
showChart.value = true
if (chart.value) {
chart.value.clear(); // 清理所有
}
chart.value.source(data, {
xValue: {
range: [0, 1],
tickCount: 6
}
});
if (!props.isTwoUnit) {
chart.value.line()
.position('xValue*yValue')
.color('type', props.color)
.shape('s mooth')
chart.value.tooltip({
layout: 'vertical',
offsetY: 110,
background: {
radius: 6,
fill: '#1890FF',
},
nameStyle: {
fontSize: 10,
},
valueStyle: {
fontSize: 10,
},
onShow: function onShow(ev: any) {
const items = ev.items;
items.unshift({
name: items[0].title,
x: items[0].x,
y: items[0].y,
})
}
})
chart.value.axis('xValue');
chart.value.guide().text({
top: true, // 是否绘制在 canvas 最上层,默认为 false
position: ['min', 'max'], // 文本的起始位置,值为原始数据值,支持 callback
content: unit ? unit : props.unit,
style: {
// fill: '#000', // 文本颜色
fontSize: '10', // 文本大小
},
offsetX: -15, // x 方向的偏移量
offsetY: -20, // y 方向偏移量
});
} else {
chart.value.line()
.position('xValue*yValue')
.color('type', props.color)
.shape('s mooth')
chart.value.axis('xValue');
chart.value.tooltip({
layout: 'vertical',
offsetY: 110,
background: {
radius: 6,
fill: '#1890FF',
},
nameStyle: {
fontSize: 10,
},
valueStyle: {
fontSize: 10,
},
onChange(obj: any) {
obj.items.splice(obj.items.findIndex((obj: any) => obj.name === "yValue2"), 1)
obj.items.map((obj: any) => {
if (obj.name === "出租率") {
obj.value = obj.origin.yValue2.toString();
}
return obj;
});
},
// onShow: function onShow(ev: any) {
// const items = ev.items;
// items.unshift({
// name: items[0].title,
// x: items[0].x,
// y: items[0].y,
// })
// },
})
chart.value.line().position('xValue*yValue2').color('blue');
chart.value.axis('yValue2');
chart.value.guide().text({
top: true, // 是否绘制在 canvas 最上层,默认为 false
position: ['min', 'max'], // 文本的起始位置,值为原始数据值,支持 callback
content: unit ? unit : props.unit,
style: {
// fill: '#000', // 文本颜色
fontSize: '10', // 文本大小
},
offsetX: -15, // x 方向的偏移量
offsetY: -20, // y 方向偏移量
});
chart.value.guide().text({
top: true, // 是否绘制在 canvas 最上层,默认为 false
position: ['min', 'max'], // 文本的起始位置,值为原始数据值,支持 callback
content: unit ? unit : props.unit2,
style: {
// fill: '#000', // 文本颜色
fontSize: '10', // 文本大小
},
offsetX: document.documentElement.clientWidth - 50, // x 方向的偏移量
offsetY: -20, // y 方向偏移量
});
}
if (props.showLegend) {
chart.value.legend({
position: props.legendPosition,
align: 'center',
itemWidth: null,
itemFormatter: (val: any) => {
console.log("val :",val)
// if ( props.showLegendUnit ){
// return `${val} ${mapNum[val]}${props.unit} ${mapRate[val]}%`;
// } else {
// return `${val} ${mapNum[val]}${props.unit}`;
// }
}
})
} else {
chart.value.legend(false)
}
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 })
</script>
引用
<InitLineChart ref="comprehEvaChart" chartId="comprehEvaChart" :height="260" unit="分"/>
const initLineChart = (originalData: any) => {
let chartData: any = []
originalData.forEach((item: any) => {
chartData.push({
type: item.zoneName,
xValue: item.syear,
yValue: item.comprehEvaScore,
})
})
comprehEvaChart.value.initChart(chartData)
}