F2图例封装 - Line

文章介绍了如何使用Vue3和AntVF23.5.0版本构建一个可配置的折线图组件,包括数据绑定、高度自适应、颜色设置、图例和提示框功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于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)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值