vue3 tsx 项目中使用 Antv/G2 实现多线折线图

Antv/G2 文档
Antv/G2 双折线图

安装依赖

项目中安装 antv/g2 依赖库:

npm install @antv/g2 --save

安装成功:
在这里插入图片描述

项目使用

新建文件 IndicatorTrend.tsx

import { defineComponent, PropType, onMounted, ref } from 'vue'
import { useChartAutoResize } from '@/hooks/chart'
import styled from '@/styled-components'
import { Chart } from '@antv/g2';

export interface TrendListItem {
  date: string
  city: string
  tempvalue: number
}

interface Props {
  dataList?: TrendListItem[]
}

const Container = styled.div`  
  width: 100%;
  height: 100%;
`

const TitleBox = styled.h3`
  margin-bottom: 10px;
`

const ChartContainer = styled.div`
  height:100%;
`

export default defineComponent({
  props: {
    dataList: {
      type: Array as PropType<TrendListItem[]>,
      default: () => []
    }
  },
  setup() {
    const dataList = ref<TrendListItem[]>([])
    const canvasRef = ref<null | HTMLElement>(null)
    const chartRef = ref<null | InstanceType<typeof Chart>>(null)

    onMounted(() => {
      if (canvasRef.value) {
        const chart = new Chart({
          container: canvasRef.value,
          autoFit: true
        })

        chartRef.value = chart
      }

      refreshChartView()
    })

    useChartAutoResize(canvasRef, chartRef)

    function refreshChartView(){      
      const chart: any = chartRef.value
      chart.clear()
      setTimeout(() => {
        chart.data(dataList.value)
        
        chart.scale({
          date: {
            range: [0, 1],
          },
          tempvalue: {
            nice: true,
          },
        });
        
        chart.tooltip({
          showCrosshairs: true,
          shared: true,
        });
        
        chart.axis('tempvalue', {
          label: {
            formatter: (val:number) => {
              return val + ' °C';
            },
          },
        });
        
        chart
          .line()
          .position('date*tempvalue')
          .color('city')
          .shape('smooth');
        
        chart
          .point()
          .position('date*tempvalue')
          .color('city')
          .shape('circle')
          .style({
            stroke: '#fff',
            lineWidth: 1,
          });
        
        chart.render()
      })
    }

    return (props: Props) => {
      dataList.value = props.dataList || []
      return (
        <Container>
          <TitleBox>总趋势</TitleBox> 
          <ChartContainer>      
          <div ref={canvasRef} />     
          </ChartContainer>   
        </Container>
      )
    }
  }
})

其中,引用了公共方法 hooks/chart

import { ref, onUnmounted, watchEffect } from 'vue'
import { changeSizeAfterCanvasResize, deleteGlobalChartItem } from '@/utils/chart'

// 没找到ref的类型
export const useChartAutoResize = (canvasRef: any, chartRef: any): void => {
  const queueIndex = ref<number>(-1)
  const isCreated = ref(false)

  function clearThisChart() {
    queueIndex.value > 0 && deleteGlobalChartItem(queueIndex.value)
  }

  // 后续如果需要重复绑定,可以返回一个更新的方法
  watchEffect(() => {
    if (!isCreated.value && canvasRef.value && chartRef.value) {
      clearThisChart()
      isCreated.value = true
      queueIndex.value = changeSizeAfterCanvasResize(canvasRef.value, chartRef.value)
    }
  }, {
    flush: 'post'
  })

  onUnmounted(() => {
    clearThisChart()
  })
}

utils/chart 文件:

import { Chart } from '@antv/g2'
import { ChartResizeQueueItem } from '@/globalType'

const getChartIndex: () => number = createChartIndex()

export function getGlobalChartQueue(): ChartResizeQueueItem[] {
  return window.chartResizeQueue
}

export function setGlobalChartQueue(arr: ChartResizeQueueItem[]): ChartResizeQueueItem[] {
  window.chartResizeQueue = arr
  return window.chartResizeQueue
}

export function deleteGlobalChartItem(index: number): void {
  const queue = getGlobalChartQueue()
  setGlobalChartQueue(queue.filter(item => item.index !== index))
}

// canvas适应父元素的大小,并刷新图表宽高
export function refreshChartSize(canvas: HTMLElement, chart: Chart): void {
  let width: number = 0
  let height: number = 0

  if (canvas.parentNode && getComputedStyle) {
    const styles = getComputedStyle(canvas.parentNode as HTMLElement)
    width = Number(styles.width.split('px')[0])
    height = Number(styles.height.split('px')[0])
  } else if (canvas.parentNode) {
    width = (canvas.parentNode as HTMLElement).offsetWidth
    height = (canvas.parentNode as HTMLElement).offsetHeight
  }

  canvas.setAttribute('width', `${width}px`)
  canvas.setAttribute('height', `${height}px`)
  chart.changeSize(width, height)
}

// 添加到全局图表队列,并且自动更新宽高
export function changeSizeAfterCanvasResize(canvas: HTMLElement, chart: InstanceType<typeof Chart>): number {
  const queue = getGlobalChartQueue()
  const index: number = getChartIndex()

  refreshChartSize(canvas, chart)
  setGlobalChartQueue(queue.concat([{ index, canvas, chart }]))

  return index
}

function createChartIndex() {
  let index: number = 0

  return (): number => {
    index++
    return index
  }
}

globalType.ts 文件:

export interface ChartResizeQueueItem {
  index: number
  canvas: HTMLElement,
  chart: any
}

在父组件中引用 IndicatorTrend.tsx 组件:

<IndicatorTrend dataList={totalTrendList.value}></IndicatorTrend>         

数据源为:

totalTrendList.value = [{
        date: '2023/8/1',
        city: 'bily',
        tempvalue: 4623
      }, {
        date: '2023/8/1',
        city: 'cily',
        tempvalue: 2208
      }, {
        date: '2023/8/1',
        city: 'bill',
        tempvalue: 182
      }, {
        date: '2023/8/2',
        city: 'bily',
        tempvalue: 6145
      }, {
        date: '2023/8/2',
        city: 'cily',
        tempvalue: 2016
      }, {
        date: '2023/8/2',
        city: 'bill',
        tempvalue: 257
      }, {
        date: '2023/8/3',
        city: 'bily',
      
        tempvalue: 508
      }, {
        date: '2023/8/3',
        city: 'cily',
        tempvalue: 2916
      }, {
        date: '2023/8/3',
        city: 'bill',
        tempvalue: 289
      }, {
      
        date: '2023/8/4',
        city: 'bily',
        tempvalue: 6268
      }, {
        date: '2023/8/4',
        city: 'cily',
        tempvalue: 4512
      }, {
        date: '2023/8/4',
        city: 'bill',
        tempvalue: 428
      }, {
        date: '2023/8/5',
        city: 'bily',
        tempvalue: 6411
      }, {
        date: '2023/8/5',
        city: 'cily',
        tempvalue: 8281
      }, {
        date: '2023/8/5',
        city: 'bill',
        tempvalue: 619
      }, {
        date: '2023/8/6',
        city: 'bily',
        tempvalue: 1890
      }, {
      
        date: '2023/8/6',
        city: 'cily',
        tempvalue: 2008
      }, {
        date: '2023/8/6',
        city: 'bill',
        tempvalue: 87
      }, {
        date: '2023/8/7',
        city: 'bily',
        tempvalue: 4251
      }, {
        date: '2023/8/7',
        city: 'cily',
        tempvalue: 1963
      }, {
        date: '2023/8/7',
        city: 'bill',
        tempvalue: 706
      }, {
        date: '2023/8/8',
        city: 'bily',
        tempvalue: 2978
      }, {
        date: '2023/8/8',
        city: 'cily',
        tempvalue: 2367
      }, {
      
        date: '2023/8/8',
        city: 'bill',
        tempvalue: 387
      }, {
        date: '2023/8/9',
        city: 'bily',
        tempvalue: 3880
      }, {
        date: '2023/8/9',
        city: 'cily',
        tempvalue: 2956
      }, {
        date: '2023/8/9',
        city: 'bill',
        tempvalue: 488
      }, {
        date: '2023/8/10',
        city: 'bily',
      
        tempvalue: 3606
      }, {
        date: '2023/8/10',
        city: 'cily',
        tempvalue: 678
      }, {
        date: '2023/8/10',
        city: 'bill',
        tempvalue: 507
      }, {
      
        date: '2023/8/11',
        city: 'bily',
        tempvalue: 4311
      }, {
        date: '2023/8/11',
        city: 'cily',
        tempvalue: 3188
      }, {
        date: '2023/8/11',
        city: 'bill',
        tempvalue: 548
      }, {
        date: '2023/8/12',
        city: 'bily',
        tempvalue: 4116
      }, {
        date: '2023/8/12',
        city: 'cily',
        tempvalue: 3491
      }, {
        date: '2023/8/12',
        city: 'bill',
        tempvalue: 456
      }, {
        date: '2023/8/13',
        city: 'bily',
        tempvalue: 6419
      }, {
      
        date: '2023/8/13',
        city: 'cily',
        tempvalue: 2852
      }, {
        date: '2023/8/13',
        city: 'bill',
        tempvalue: 689
      }, {
        date: '2023/8/14',
      
        city: 'bily',
        tempvalue: 1643
      }, {
        date: '2023/8/14',
        city: 'cily',
        tempvalue: 4788
      }, {
        date: '2023/8/14',
        city: 'bill',
        tempvalue: 280
      }, {
        date: '2023/8/15',
        city: 'bily',
        tempvalue: 445
      }, {
        date: '2023/8/15',
        city: 'cily',
        tempvalue: 4319
      }, {
      
        date: '2023/8/15',
        city: 'bill',
        tempvalue: 176
      }]

页面效果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/149233.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp基础学习笔记01

文章目录 本博客根据黑马教程学习uniapp一、技术架构二、创建项目2.1 Hbuilder创建2.2 插件安装2.3 微信开发者工具配置与运行2.3.1 简单修改基础页面 2.4 pages.json和tabBar2.4.1 pages.json与tabBar配置2.4.2 案例 三、uniapp与原生开发的区别 本博客根据黑马教程学习uniapp…

Postman工具简介

介绍 Postman是一个商业的接口测试工具。免费的版本也可以使用不少功能。 官网&#xff1a;https://www.postman.com/ 下载、安装、应用界面 下载 安装、安装成功以后的应用界面 双击下载下来的可执行文件进行安装&#xff0c;出现如下界面&#xff1a; 可以注册一个账…

自动化测试和手工测试有什么不同以及自动化测试和手工测试应用范围的对比

一、初识自动化测试 如果以前没有做过自动化测试&#xff0c;那么就不了解自动化测试&#xff0c;可能会觉得自动化测试比较神秘&#xff0c;但是&#xff0c;我们在日常的计算机操作中&#xff0c;可能会碰到一些自动化处理的过程&#xff0c;这些过程和自动化测试比较接近。 …

EDA实验------数控分频器设计(QuartusII)

目录 一、实验目的 二、实验原理 三、实验内容 四、实验步骤 五、注意事项 六、思考题 七、实验过程 分频器的基本原理 什么是分频器&#xff1f; 如何去分频&#xff1f; 1.创建新项目 2.创建Verilog文件&#xff0c;写入代码 3.连接电路 ​编辑 锁相环的创建 4…

做决策、定战略、带团队:顶级高手常用的16个思维模型

01 做决策 1.沃伦巴菲特的双目标清单系统&#xff08;Two-List System&#xff09; 弗林特当了巴菲特的私人飞行员十年之久&#xff0c;还曾为美国四任总统开过飞机&#xff0c;但他在事业上依然有更多追求。有一次&#xff0c;他和巴菲特在探讨他的职业生涯目标时&#xff0…

教你轻轻松松写出10万+的微头条爆文,赶紧收藏!

微头条是投放在今日头条上的稿件&#xff0c;重点在于微字&#xff0c;一般在300-500字之间&#xff0c;讲究的是原创干货&#xff0c;有独到见解。 企业和品牌撰写微头条来给自己带来更多曝光和展现。想要让你的微头条写出爆款内容&#xff0c;这是需要讲究技巧的&#xff0c…

<文件操作及常用的API>

文章目录 专栏导读&#x1f680;简单认识一下文件&#x1f680;树形结构和目录&#x1f680;文件路径-相对路径、绝对路径&#x1f680;文件类型&#x1f680;Java中文件的操作&#x1f680;File 类的常用方法 专栏导读 &#x1f680;多线程章节 &#x1f490;数据结构剖析 &am…

京东账单导出的手工操作

文章目录 京东账单导出的手工操作概述笔记备注END 京东账单导出的手工操作 概述 在京东网页版找不到账单导出的操作. 在手机京东中可以导出账单. 当前京东APP的导出实现有点bug, 在输入验证码后, 发送邮件. 可是显示验证码失败, 但是已经发了邮件. 可能是因为发送成功提示不明…

半平面求交 - 洛谷 - P3194 [HNOI2008] 水平可见直线

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 往期相关背景点击前往 题目大意 题目链接 https://www.luogu.com.cn/problem/P3194 在直角坐标系中给定一些直线&#xff0c;然后从Y轴无穷大处往0处看&#xff0c;…

如何在面试中胜出?接口自动化面试题安排上

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

定位咨询与资源分配:最大化效益的关键

在当今竞争激烈的商业环境中&#xff0c;企业如何确保每一分投资都能产生最大的回报?答案在于有效的市场定位和精明的资源分配。本文将探讨定位咨询如何成为企业资源分配和效益最大化的关键。 定位咨询的核心作用 定位咨询是企业发现其在市场上独特地位的过程。这不仅关乎营销…

如何挑选护眼灯?光照均匀度、色温、眩光这3点!

光照环境对我们的生活质量影响深远&#xff0c;尤其在孩子的成长过程中&#xff0c;良好的光照环境对其学习效率、视力保护都至关重要。光照中的很多因素都对视力有着或大或小的影响&#xff0c;本文将从光照均匀度、眩光、色温三个关键点&#xff0c;深入浅出地让消费者了解其…

大模型在数据分析场景下的能力评测|进阶篇

做数据分析&#xff0c;什么大模型比较合适&#xff1f; 如何调优大模型&#xff0c;来更好地做数据计算和洞察分析&#xff1f; 如何降低整体成本&#xff0c;同时保障分析体验&#xff1f;10月25日&#xff0c;我们发布了数据分析场景下的大模型能力评测框架&#xff08;点击…

【验证码逆向专栏】百某网数字九宫格验证码逆向分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 本文章未…

正版软件|Ashampoo WinOptimizer 26 - Win优化器

使用 Ashampoo WinOptimizer 加速、优化和清洁你的电脑&#xff0c;非常轻松&#xff01; 关于Ashampoo WinOptimizer Windows是很棒&#xff0c;但总有改进的余地。 这就是Ashampoo WinOptimizer 26的用武之地! 因为&#xff0c;随着时间的推移&#xff0c;操作系统往往会变慢…

Git常用规范

分支命名规范 Git分支命名规范可以根据具体的项目和团队的需要而有所不同&#xff0c;但是以下是一些常见的规范&#xff1a; 主分支&#xff08;master/main&#xff09;&#xff1a;这个分支通常是主要的稳定分支&#xff0c;它包含了当前生产环境的代码。在一些项目中&…

妙手ERP本期功能优化:TikTok创建折扣活动可默认生成活动名称和时间、Shopee利润明细新增字段等

为了给卖家朋友带来更好的使用体验&#xff0c;更高效地运营跨境店铺&#xff0c;妙手ERP在上周优化了以下多项功能。 01、产品模块优化 全平台 - 批量编辑平台SKU增加翻译功能 TikTok - 创建折扣活动时&#xff0c;可默认生成活动名称和时间 02、订单模块优化 全平台 - 扫…

day21_mysql

今日内容 零、 复习昨日 第一阶段: Java基础知识(会编程,懂编程) 第二阶段: Web开发(前端,后端,数据库) 一、MySQL 一、引言 二、数据库 2.1 概念 ​ 数据库是“按照数据结构来组织、存储和管理数据的仓库。是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合…

一篇文章让你真正搞懂epoll机制

目录 1.epoll简介 2.epoll实现原理 3.创建epoll文件 4.增加&#xff0c;删除&#xff0c;修改epoll事件 5.epoll事件就绪 6.epoll编程流程 7.epoll常见问题&#xff1f; 1.epoll简介 epoll是Linux内核为处理大批量文件描述符而作了改进的poll&#xff0c;它能显著提高程…

Visual Studio Code配置c/c++环境

Visual Studio Code配置c/c环境 1.创建项目目录2.vscode打开项目目录3.项目中添加文件4.文件内容5.配置编译器6.配置构建任务7.配置调试设置 1.创建项目目录 d:\>mkdir d:\c语言项目\test012.vscode打开项目目录 3.项目中添加文件 4.文件内容 #include <iostream> u…